Skip to content

Commit

Permalink
feat: add request and response interceptors to client requests
Browse files Browse the repository at this point in the history
  • Loading branch information
arrlancore committed Oct 6, 2024
1 parent 6e4201a commit a1ecc99
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 15 deletions.
56 changes: 56 additions & 0 deletions axios4go_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -698,3 +698,59 @@ func TestValidateStatus(t *testing.T) {
})

}

func TestInterceptors(t *testing.T) {
server := setupTestServer()
defer server.Close()

var interceptedRequest *http.Request
requestInterceptorCalled := false
requestInterceptor := func(req *http.Request) error {
req.Header.Set("X-Intercepted", "true")
interceptedRequest = req
requestInterceptorCalled = true
return nil
}

responseInterceptor := func(resp *http.Response) error {
resp.Header.Set("X-Intercepted-Response", "true")
return nil
}

opts := &RequestOptions{
headers: map[string]string{
"Content-Type": "application/json",
},
params: map[string]string{
"query": "myQuery",
},
}

opts.interceptorOptions = InterceptorOptions{
requestInterceptors: []func(*http.Request) error{requestInterceptor},
responseInterceptors: []func(*http.Response) error{responseInterceptor},
}

t.Run("Interceptors Test", func(t *testing.T) {
response, err := Get(server.URL+"/get", opts)
if err != nil {
t.Fatalf("Expected no error, got %v", err)
}

if !requestInterceptorCalled {
t.Error("Request interceptor was not called")
}

if interceptedRequest != nil {
if interceptedRequest.Header.Get("X-Intercepted") != "true" {
t.Errorf("Expected request header 'X-Intercepted' to be 'true', got '%s'", interceptedRequest.Header.Get("X-Intercepted"))
}
} else {
t.Error("Intercepted request is nil")
}

if response.Headers.Get("X-Intercepted-Response") != "true" {
t.Errorf("Expected response header 'X-Intercepted-Response' to be 'true', got '%s'", response.Headers.Get("X-Intercepted-Response"))
}
})
}
58 changes: 43 additions & 15 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,30 @@ type Promise struct {
mu sync.Mutex
}

type RequestInterceptors []func(*http.Request) error
type ResponseInterceptors []func(*http.Response) error
type InterceptorOptions struct {
requestInterceptors RequestInterceptors
responseInterceptors ResponseInterceptors
}

type RequestOptions struct {
method string
url string
baseURL string
params map[string]string
body interface{}
headers map[string]string
timeout int
auth *auth
responseType string
responseEncoding string
maxRedirects int
maxContentLength int
maxBodyLength int
decompress bool
validateStatus func(int) bool
method string
url string
baseURL string
params map[string]string
body interface{}
headers map[string]string
timeout int
auth *auth
responseType string
responseEncoding string
maxRedirects int
maxContentLength int
maxBodyLength int
decompress bool
validateStatus func(int) bool
interceptorOptions InterceptorOptions
}

type auth struct {
Expand Down Expand Up @@ -336,6 +344,13 @@ func (c *Client) Request(options *RequestOptions) (*Response, error) {
return nil, err
}

for _, interceptor := range options.interceptorOptions.requestInterceptors {
err = interceptor(req)
if err != nil {
return nil, fmt.Errorf("request interceptor failed: %w", err)
}
}

if options.headers == nil {
options.headers = make(map[string]string)
}
Expand Down Expand Up @@ -394,6 +409,13 @@ func (c *Client) Request(options *RequestOptions) (*Response, error) {
return nil, fmt.Errorf("Request failed with status code: %v", resp.StatusCode)
}

for _, interceptor := range options.interceptorOptions.responseInterceptors {
err = interceptor(resp)
if err != nil {
return nil, fmt.Errorf("response interceptor failed: %w", err)
}
}

return &Response{
StatusCode: resp.StatusCode,
Headers: resp.Header,
Expand Down Expand Up @@ -444,6 +466,12 @@ func mergeOptions(dst, src *RequestOptions) {
if src.validateStatus != nil {
dst.validateStatus = src.validateStatus
}
if src.interceptorOptions.requestInterceptors != nil {
dst.interceptorOptions.requestInterceptors = src.interceptorOptions.requestInterceptors
}
if src.interceptorOptions.responseInterceptors != nil {
dst.interceptorOptions.responseInterceptors = src.interceptorOptions.responseInterceptors
}
dst.decompress = src.decompress
}

Expand Down

0 comments on commit a1ecc99

Please sign in to comment.