Skip to content

Commit 4e85afb

Browse files
committed
feat: support headers and query params
Handle URL building and header setting
1 parent 9b613b4 commit 4e85afb

2 files changed

Lines changed: 86 additions & 1 deletion

File tree

internal/http/manager.go

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package http
33
import (
44
"fmt"
55
"net/http"
6+
"net/url"
67
"strings"
78
"time"
89

@@ -59,13 +60,24 @@ func (h *HTTPManager) ExecuteRequest(req *Request) (*Response, error) {
5960

6061
log.Debug("executing HTTP request", "method", req.Method, "url", req.URL)
6162

63+
requestURL, err := h.buildURL(req.URL, req.QueryParams)
64+
if err != nil {
65+
log.Error("failed to build URL", "error", err)
66+
return nil, fmt.Errorf("failed to build URL: %w", err)
67+
}
68+
6269
start := time.Now()
63-
httpReq, err := http.NewRequest(strings.ToUpper(req.Method), req.URL, nil)
70+
httpReq, err := http.NewRequest(strings.ToUpper(req.Method), requestURL, nil)
6471
if err != nil {
6572
log.Error("failed to create HTTP request", "error", err)
6673
return nil, fmt.Errorf("failed to create request: %w", err)
6774
}
6875

76+
if err := h.setHeaders(httpReq, req.Headers); err != nil {
77+
log.Error("failed to set headers", "error", err)
78+
return nil, fmt.Errorf("failed to set headers: %w", err)
79+
}
80+
6981
resp, err := h.Client.Do(httpReq)
7082
if err != nil {
7183
log.Error("HTTP request failed", "error", err)
@@ -85,3 +97,32 @@ func (h *HTTPManager) ExecuteRequest(req *Request) (*Response, error) {
8597
log.Info("HTTP request completed", "status", resp.StatusCode, "duration", duration)
8698
return response, nil
8799
}
100+
101+
func (h *HTTPManager) buildURL(baseURL string, queryParams map[string]string) (string, error) {
102+
if len(queryParams) == 0 {
103+
return baseURL, nil
104+
}
105+
106+
parsedURL, err := url.Parse(baseURL)
107+
if err != nil {
108+
return "", err
109+
}
110+
111+
values := parsedURL.Query()
112+
for key, value := range queryParams {
113+
values.Set(key, value)
114+
}
115+
parsedURL.RawQuery = values.Encode()
116+
117+
return parsedURL.String(), nil
118+
}
119+
120+
func (h *HTTPManager) setHeaders(req *http.Request, headers map[string]string) error {
121+
for key, value := range headers {
122+
if strings.TrimSpace(key) == "" {
123+
return fmt.Errorf("header key cannot be empty")
124+
}
125+
req.Header.Set(key, value)
126+
}
127+
return nil
128+
}

internal/http/manager_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package http
22

33
import (
4+
"net/http"
45
"testing"
56
"time"
67
)
@@ -86,3 +87,46 @@ func TestValidateRequest(t *testing.T) {
8687
t.Error("expected invalid request to fail validation")
8788
}
8889
}
90+
91+
func TestBuildURL(t *testing.T) {
92+
manager := NewHTTPManager()
93+
94+
tests := []struct {
95+
baseURL string
96+
queryParams map[string]string
97+
expected string
98+
}{
99+
{"https://example.com", nil, "https://example.com"},
100+
{"https://example.com", map[string]string{}, "https://example.com"},
101+
{"https://example.com", map[string]string{"foo": "bar"}, "https://example.com?foo=bar"},
102+
}
103+
104+
for _, test := range tests {
105+
result, err := manager.buildURL(test.baseURL, test.queryParams)
106+
if err != nil {
107+
t.Errorf("buildURL failed: %v", err)
108+
}
109+
if result != test.expected {
110+
t.Errorf("expected %s, got %s", test.expected, result)
111+
}
112+
}
113+
}
114+
115+
func TestSetHeaders(t *testing.T) {
116+
manager := NewHTTPManager()
117+
req, _ := http.NewRequest("GET", "https://example.com", nil)
118+
119+
headers := map[string]string{
120+
"Content-Type": "application/json",
121+
"User-Agent": "req-cli",
122+
}
123+
124+
err := manager.setHeaders(req, headers)
125+
if err != nil {
126+
t.Errorf("setHeaders failed: %v", err)
127+
}
128+
129+
if req.Header.Get("Content-Type") != "application/json" {
130+
t.Error("Content-Type header not set correctly")
131+
}
132+
}

0 commit comments

Comments
 (0)