From 730c775d8c1057cfc7b064e3de28ef89c13cd3e2 Mon Sep 17 00:00:00 2001 From: linuxscreen Date: Wed, 9 Oct 2024 20:07:07 +0800 Subject: [PATCH] feat:support defines proxy setting for request --- axios4go_test.go | 109 +++++++++++++++++++++++++++++++++++++++++++++++ client.go | 35 +++++++++++++++ 2 files changed, 144 insertions(+) diff --git a/axios4go_test.go b/axios4go_test.go index 1bdd23d..00b241b 100644 --- a/axios4go_test.go +++ b/axios4go_test.go @@ -12,6 +12,8 @@ func setupTestServer() *httptest.Server { switch r.URL.Path { case "/get": json.NewEncoder(w).Encode(map[string]string{"message": "get success"}) + case "/getByProxy": + json.NewEncoder(w).Encode(map[string]string{"message": "get success by proxy"}) case "/post": json.NewEncoder(w).Encode(map[string]string{"message": "post success"}) case "/put": @@ -754,3 +756,110 @@ func TestInterceptors(t *testing.T) { } }) } + +func handler(w http.ResponseWriter, r *http.Request) { + request, err := http.NewRequest(r.Method, r.RequestURI, nil) + client := http.Client{} + response, err := client.Do(request) + if err != nil { + return + } + bytes := make([]byte, response.ContentLength) + response.Body.Read(bytes) + w.Write(bytes) +} + +func TestGetByProxy(t *testing.T) { + server := setupTestServer() + defer server.Close() + path := "/getByProxy" + http.HandleFunc("/", handler) + go func() { + // start to mock a proxy server + err := http.ListenAndServe(":8080", nil) + if err != nil { + return + } + }() + t.Run("Simple Style", func(t *testing.T) { + response, err := Get(server.URL+path, + &RequestOptions{ + Proxy: &Proxy{ + Protocol: "http", + Host: "localhost", + Port: 8080, + Auth: &Auth{ + Username: "username", + Password: "password", + }, + }, + }, + ) + + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + + if response.StatusCode != http.StatusOK { + t.Errorf("Expected status code %d, got %d", http.StatusOK, response.StatusCode) + } + + var result map[string]string + err = json.Unmarshal(response.Body, &result) + if err != nil { + t.Fatalf("Error unmarshaling response Body: %v", err) + } + + if result["message"] != "get success by proxy" { + t.Errorf("Expected message 'get success by proxy', got '%s'", result["message"]) + } + }) + + t.Run("Promise Style", func(t *testing.T) { + promise := GetAsync(server.URL + path) + var thenExecuted, finallyExecuted bool + + promise. + Then(func(response *Response) { + // Assertions... + thenExecuted = true + }). + Catch(func(err error) { + t.Errorf("Expected no error, got %v", err) + }). + Finally(func() { + finallyExecuted = true + }) + + // Wait for the promise to complete + <-promise.done + + if !thenExecuted { + t.Error("Then was not executed") + } + if !finallyExecuted { + t.Error("Finally was not executed") + } + }) + + t.Run("Request Style", func(t *testing.T) { + response, err := Request("GET", server.URL+path) + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + + if response.StatusCode != http.StatusOK { + t.Errorf("Expected status code %d, got %d", http.StatusOK, response.StatusCode) + } + + var result map[string]string + err = json.Unmarshal(response.Body, &result) + if err != nil { + t.Fatalf("Error unmarshaling response Body: %v", err) + } + + if result["message"] != "get success by proxy" { + t.Errorf("Expected message 'get success by proxy', got '%s'", result["message"]) + } + }) +} diff --git a/client.go b/client.go index 94d4676..91e61f5 100644 --- a/client.go +++ b/client.go @@ -59,6 +59,14 @@ type RequestOptions struct { Decompress bool ValidateStatus func(int) bool InterceptorOptions InterceptorOptions + Proxy *Proxy +} + +type Proxy struct { + Protocol string + Host string + Port int + Auth *Auth } type Auth struct { @@ -382,6 +390,30 @@ func (c *Client) Request(options *RequestOptions) (*Response, error) { } } + if options.Proxy != nil { + // support http and https + proxyStr := fmt.Sprintf("%s://%s:%d", options.Proxy.Protocol, options.Proxy.Host, options.Proxy.Port) + proxyURL, err := url.Parse(proxyStr) + if err != nil { + return nil, err + } + transport := &http.Transport{ + Proxy: http.ProxyURL(proxyURL), + } + if options.Proxy.Auth != nil { + auth := options.Proxy.Auth.Username + ":" + options.Proxy.Auth.Password + basicAuth := base64.StdEncoding.EncodeToString([]byte(auth)) + transport.ProxyConnectHeader = http.Header{ + "Proxy-Authorization": {"Basic " + basicAuth}, + } + } + c.HTTPClient.Transport = transport + // cancel proxy after request + defer func() { + c.HTTPClient.Transport = nil + }() + } + resp, err := c.HTTPClient.Do(req) if err != nil { return nil, err @@ -472,6 +504,9 @@ func mergeOptions(dst, src *RequestOptions) { if src.InterceptorOptions.ResponseInterceptors != nil { dst.InterceptorOptions.ResponseInterceptors = src.InterceptorOptions.ResponseInterceptors } + if src.Proxy != nil { + dst.Proxy = src.Proxy + } dst.Decompress = src.Decompress }