Skip to content

Commit 78bda26

Browse files
committed
feat: add http package with basic structure
Create request/response models and validation
1 parent e097e04 commit 78bda26

3 files changed

Lines changed: 168 additions & 0 deletions

File tree

internal/http/manager.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package http
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"strings"
7+
"time"
8+
9+
"github.com/maniac-en/req/internal/log"
10+
)
11+
12+
func NewHTTPManager() *HTTPManager {
13+
client := &http.Client{
14+
Timeout: 30 * time.Second,
15+
}
16+
return &HTTPManager{
17+
Client: client,
18+
}
19+
}
20+
21+
func validateMethod(method string) error {
22+
method = strings.ToUpper(strings.TrimSpace(method))
23+
validMethods := []string{"GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"}
24+
for _, valid := range validMethods {
25+
if method == valid {
26+
return nil
27+
}
28+
}
29+
return fmt.Errorf("invalid HTTP method: %s", method)
30+
}
31+
32+
func validateURL(url string) error {
33+
url = strings.TrimSpace(url)
34+
if url == "" {
35+
return fmt.Errorf("URL cannot be empty")
36+
}
37+
if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
38+
return fmt.Errorf("URL must start with http:// or https://")
39+
}
40+
return nil
41+
}
42+
43+
func (h *HTTPManager) ValidateRequest(req *Request) error {
44+
if err := validateMethod(req.Method); err != nil {
45+
log.Error("invalid method", "method", req.Method, "error", err)
46+
return err
47+
}
48+
if err := validateURL(req.URL); err != nil {
49+
log.Error("invalid URL", "url", req.URL, "error", err)
50+
return err
51+
}
52+
return nil
53+
}

internal/http/manager_test.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package http
2+
3+
import (
4+
"testing"
5+
"time"
6+
)
7+
8+
func TestNewHTTPManager(t *testing.T) {
9+
manager := NewHTTPManager()
10+
if manager == nil {
11+
t.Fatal("NewHTTPManager returned nil")
12+
}
13+
if manager.Client == nil {
14+
t.Fatal("HTTPManager client is nil")
15+
}
16+
if manager.Client.Timeout != 30*time.Second {
17+
t.Errorf("expected timeout 30s, got %v", manager.Client.Timeout)
18+
}
19+
}
20+
21+
func TestValidateMethod(t *testing.T) {
22+
tests := []struct {
23+
method string
24+
valid bool
25+
}{
26+
{"GET", true},
27+
{"POST", true},
28+
{"put", true},
29+
{"delete", true},
30+
{"INVALID", false},
31+
{"", false},
32+
}
33+
34+
for _, test := range tests {
35+
err := validateMethod(test.method)
36+
if test.valid && err != nil {
37+
t.Errorf("expected %s to be valid, got error: %v", test.method, err)
38+
}
39+
if !test.valid && err == nil {
40+
t.Errorf("expected %s to be invalid, got no error", test.method)
41+
}
42+
}
43+
}
44+
45+
func TestValidateURL(t *testing.T) {
46+
tests := []struct {
47+
url string
48+
valid bool
49+
}{
50+
{"https://example.com", true},
51+
{"http://localhost:8080", true},
52+
{"ftp://invalid.com", false},
53+
{"", false},
54+
{"not-a-url", false},
55+
}
56+
57+
for _, test := range tests {
58+
err := validateURL(test.url)
59+
if test.valid && err != nil {
60+
t.Errorf("expected %s to be valid, got error: %v", test.url, err)
61+
}
62+
if !test.valid && err == nil {
63+
t.Errorf("expected %s to be invalid, got no error", test.url)
64+
}
65+
}
66+
}
67+
68+
func TestValidateRequest(t *testing.T) {
69+
manager := NewHTTPManager()
70+
71+
validReq := &Request{
72+
Method: "GET",
73+
URL: "https://example.com",
74+
}
75+
76+
if err := manager.ValidateRequest(validReq); err != nil {
77+
t.Errorf("expected valid request to pass validation, got: %v", err)
78+
}
79+
80+
invalidReq := &Request{
81+
Method: "INVALID",
82+
URL: "not-a-url",
83+
}
84+
85+
if err := manager.ValidateRequest(invalidReq); err == nil {
86+
t.Error("expected invalid request to fail validation")
87+
}
88+
}

internal/http/models.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Package http provides HTTP client functionality for making HTTP requests.
2+
package http
3+
4+
import (
5+
"net/http"
6+
"time"
7+
)
8+
9+
type HTTPManager struct {
10+
Client *http.Client
11+
}
12+
13+
type Request struct {
14+
Method string
15+
URL string
16+
Headers map[string]string
17+
QueryParams map[string]string
18+
Body string
19+
}
20+
21+
type Response struct {
22+
StatusCode int
23+
Status string
24+
Headers map[string][]string
25+
Body string
26+
Duration time.Duration
27+
}

0 commit comments

Comments
 (0)