diff --git a/plugins/alipay_cpn/internal/util.go b/plugins/alipay_cpn/internal/util.go index 1016be0..8d60978 100644 --- a/plugins/alipay_cpn/internal/util.go +++ b/plugins/alipay_cpn/internal/util.go @@ -44,10 +44,10 @@ func req(config *Config, req *po.Param) (url.Values, error) { } func Post(ctx context.Context, uv url.Values) ([]byte, http.Header, error) { - headers := map[string]string{ - "Content-Type": "application/x-www-form-urlencoded", + h := http.Header{ + "Content-Type": []string{"application/x-www-form-urlencoded"}, } - respBody, respHeader, err := request.Post(ctx, baseUri+"?"+uv.Encode(), nil, request.WithHeaders(headers)) + respHeader, respBody, err := request.Post(ctx, baseUri+"?"+uv.Encode(), nil, request.WithHeaders(h)) if err != nil { return nil, nil, proto.ErrorRequestFail(err.Error()) } diff --git a/plugins/alipay_redpack/internal/util.go b/plugins/alipay_redpack/internal/util.go index 0136a24..84ef584 100644 --- a/plugins/alipay_redpack/internal/util.go +++ b/plugins/alipay_redpack/internal/util.go @@ -43,10 +43,10 @@ func req(config *Config, req *po.Param) (url.Values, error) { } func Post(ctx context.Context, uv url.Values) ([]byte, http.Header, error) { - headers := map[string]string{ - "Content-Type": "application/x-www-form-urlencoded", + h := http.Header{ + "Content-Type": []string{"application/x-www-form-urlencoded"}, } - respBody, respHeader, err := request.Post(ctx, baseUri+"?"+uv.Encode(), nil, request.WithHeaders(headers)) + respHeader, respBody, err := request.Post(ctx, baseUri+"?"+uv.Encode(), nil, request.WithHeaders(h)) if err != nil { return nil, nil, proto.ErrorRequestFail(err.Error()) } diff --git a/plugins/union_pay_cpn/internal/transform.go b/plugins/union_pay_cpn/internal/transform.go index 5e5638b..9ca1e86 100644 --- a/plugins/union_pay_cpn/internal/transform.go +++ b/plugins/union_pay_cpn/internal/transform.go @@ -10,7 +10,7 @@ import ( "net/http" "plugins/union_pay_cpn/internal/po" "plugins/union_pay_cpn/internal/vo" - request "plugins/utils/request/v2" + "plugins/utils/request" "plugins/utils/union_pay" "strings" "time" diff --git a/plugins/union_pay_redpack/internal/transform.go b/plugins/union_pay_redpack/internal/transform.go index 64f1850..208d6f3 100644 --- a/plugins/union_pay_redpack/internal/transform.go +++ b/plugins/union_pay_redpack/internal/transform.go @@ -10,7 +10,7 @@ import ( "net/http" "plugins/union_pay_redpack/internal/po" "plugins/union_pay_redpack/internal/vo" - request "plugins/utils/request/v2" + "plugins/utils/request" "plugins/utils/union_pay" "time" ) diff --git a/utils/request/request.go b/utils/request/request.go index 8bcd882..988e7f9 100644 --- a/utils/request/request.go +++ b/utils/request/request.go @@ -11,8 +11,9 @@ import ( // RequestOptions 用于配置请求的各种选项 type RequestOptions struct { + Headers http.Header + Timeout time.Duration - Headers map[string]string StatusCodeFunc func(int) bool } @@ -27,7 +28,7 @@ func WithTimeout(timeout time.Duration) RequestOption { } // WithHeaders 设置请求头的选项函数 -func WithHeaders(headers map[string]string) RequestOption { +func WithHeaders(headers http.Header) RequestOption { return func(options *RequestOptions) { options.Headers = headers } @@ -40,24 +41,27 @@ func WithStatusCodeFunc(statusCodeFunc func(int) bool) RequestOption { } } -func Post(ctx context.Context, url string, body []byte, options ...RequestOption) ([]byte, http.Header, error) { +func Post(ctx context.Context, url string, body []byte, options ...RequestOption) (http.Header, []byte, error) { return Request(ctx, http.MethodPost, url, body, options...) } -func Get(ctx context.Context, url string, options ...RequestOption) ([]byte, http.Header, error) { +func Get(ctx context.Context, url string, options ...RequestOption) (http.Header, []byte, error) { return Request(ctx, http.MethodGet, url, nil, options...) } -func Put(ctx context.Context, url string, body []byte, options ...RequestOption) ([]byte, http.Header, error) { +func Put(ctx context.Context, url string, body []byte, options ...RequestOption) (http.Header, []byte, error) { return Request(ctx, http.MethodPut, url, body, options...) } // Request 封装的HTTP请求函数,使用选项模式进行配置 -func Request(_ context.Context, method, url string, body []byte, options ...RequestOption) ([]byte, http.Header, error) { +func Request(_ context.Context, method, url string, body []byte, options ...RequestOption) (http.Header, []byte, error) { // 设置默认选项 - defaultOptions := &RequestOptions{ + o := &RequestOptions{ + Headers: http.Header{ + "Content-Type": []string{"application/json"}, + }, Timeout: 15 * time.Second, - Headers: make(map[string]string), + StatusCodeFunc: func(code int) bool { return code == http.StatusOK }, @@ -65,37 +69,32 @@ func Request(_ context.Context, method, url string, body []byte, options ...Requ // 根据传入的选项更新默认选项 for _, option := range options { - option(defaultOptions) + option(o) } req, err := http.NewRequest(method, url, bytes.NewBuffer(body)) if err != nil { - return nil, nil, fmt.Errorf("创建HTTP请求失败: %v", err) - } - - // 设置请求头 - for key, value := range defaultOptions.Headers { - req.Header.Set(key, value) + return nil, nil, fmt.Errorf("创建HTTP请求失败: %w", err) } + req.Header = o.Headers httpClient := &http.Client{ - Timeout: defaultOptions.Timeout, + Timeout: o.Timeout, } - resp, err := httpClient.Do(req) if err != nil { - return nil, nil, fmt.Errorf("发送HTTP请求失败: %v", err) + return nil, nil, fmt.Errorf("发送HTTP请求失败: %w", err) } defer resp.Body.Close() bodyBytes, err := io.ReadAll(resp.Body) if err != nil { - return nil, nil, fmt.Errorf("读取响应体失败: %v", err) + return nil, nil, fmt.Errorf("读取响应体失败: %w", err) } - if !defaultOptions.StatusCodeFunc(resp.StatusCode) { + if !o.StatusCodeFunc(resp.StatusCode) { return nil, nil, fmt.Errorf("请求异常:%s", resp.Status) } - return bodyBytes, resp.Header, nil + return resp.Header, bodyBytes, nil } diff --git a/utils/request/request_test.go b/utils/request/request_test.go index b262045..4f13710 100644 --- a/utils/request/request_test.go +++ b/utils/request/request_test.go @@ -2,7 +2,6 @@ package request import ( "context" - "fmt" "net/http" "net/url" "testing" @@ -12,70 +11,56 @@ import ( func Test_Get(t *testing.T) { uri := "https://gateway.dev.cdlsxd.cn/adminyx/admin/v1/key_batch/list" - headers := map[string]string{ - "Content-Type": "application/x-www-form-urlencoded", - } - uv := url.Values{} uv.Set("page", "1") uv.Set("limit", "2") - respBody, respHeader, err := Get(context.Background(), uri+"?"+uv.Encode(), WithHeaders(headers)) + h := http.Header{ + "Content-Type": []string{"application/x-www-form-urlencoded"}, + } + respHeader, respBody, err := Get(context.Background(), uri+"?"+uv.Encode(), WithHeaders(h)) if err != nil { - fmt.Println(err) + t.Error(err) return } - fmt.Println("响应体:", string(respBody)) - fmt.Println("响应头:", respHeader) -} - -func Test_Request(t *testing.T) { - url := "https://gateway.dev.cdlsxd.cn/adminyx/admin/v1/key_batch/get_zip_url/109" - - respBody, respHeader, err := Get(context.Background(), url) - if err != nil { - fmt.Println(err) - return - } - - fmt.Println("响应体:", string(respBody)) - fmt.Println("响应头:", respHeader) + t.Logf("响应体:", string(respBody)) + t.Logf("响应头:", respHeader) } func Test_RequestHeaders(t *testing.T) { - url := "http://example.com/api" + uri := "http://example.com/api" body := []byte("request body") - headers := map[string]string{ - "Content-Type": "application/json", - "Authorization": "Bearer token", + h := http.Header{ + "Content-Type": []string{"application/json"}, + "Authorization": []string{"Bearer token"}, } - respBody, respHeader, err := Post(context.Background(), url, body, WithTimeout(10*time.Second), WithHeaders(headers)) + respHeader, respBody, err := Post(context.Background(), uri, body, WithTimeout(10*time.Second), WithHeaders(h)) if err != nil { - fmt.Println(err) + t.Error(err) return } - fmt.Println("响应体:", string(respBody)) - fmt.Println("响应头:", respHeader) + t.Logf("响应体:", string(respBody)) + t.Logf("响应头:", respHeader) } func Test_RequestStatusCode(t *testing.T) { - url := "http://example.com/api/update" + uri := "http://example.com/api/update" body := []byte("update data") isSuccess := func(code int) bool { return code == http.StatusOK || code == http.StatusCreated } - respBody, respHeader, err := Put(context.Background(), url, body, WithStatusCodeFunc(isSuccess)) + respHeader, respBody, err := Put(context.Background(), uri, body, WithStatusCodeFunc(isSuccess)) if err != nil { - fmt.Println(err) + t.Error(err) return } - fmt.Println("响应体:", string(respBody)) - fmt.Println("响应头:", respHeader) + t.Logf("响应体:", string(respBody)) + t.Logf("响应头:", respHeader) } diff --git a/utils/request/v2/request.go b/utils/request/v2/request.go deleted file mode 100644 index e41ea0c..0000000 --- a/utils/request/v2/request.go +++ /dev/null @@ -1,100 +0,0 @@ -package v2 - -import ( - "bytes" - "context" - "fmt" - "io" - "net/http" - "time" -) - -// RequestOptions 用于配置请求的各种选项 -type RequestOptions struct { - Headers http.Header - - Timeout time.Duration - StatusCodeFunc func(int) bool -} - -// RequestOption 是一个函数类型,用于设置RequestOptions的各个字段 -type RequestOption func(*RequestOptions) - -// WithTimeout 设置请求超时时间的选项函数 -func WithTimeout(timeout time.Duration) RequestOption { - return func(options *RequestOptions) { - options.Timeout = timeout - } -} - -// WithHeaders 设置请求头的选项函数 -func WithHeaders(headers http.Header) RequestOption { - return func(options *RequestOptions) { - options.Headers = headers - } -} - -// WithStatusCodeFunc 设置自定义状态码处理函数的选项函数 -func WithStatusCodeFunc(statusCodeFunc func(int) bool) RequestOption { - return func(options *RequestOptions) { - options.StatusCodeFunc = statusCodeFunc - } -} - -func Post(ctx context.Context, url string, body []byte, options ...RequestOption) (http.Header, []byte, error) { - return Request(ctx, http.MethodPost, url, body, options...) -} - -func Get(ctx context.Context, url string, options ...RequestOption) (http.Header, []byte, error) { - return Request(ctx, http.MethodGet, url, nil, options...) -} - -func Put(ctx context.Context, url string, body []byte, options ...RequestOption) (http.Header, []byte, error) { - return Request(ctx, http.MethodPut, url, body, options...) -} - -// Request 封装的HTTP请求函数,使用选项模式进行配置 -func Request(_ context.Context, method, url string, body []byte, options ...RequestOption) (http.Header, []byte, error) { - // 设置默认选项 - o := &RequestOptions{ - Headers: http.Header{ - "Content-Type": []string{"application/json"}, - }, - Timeout: 15 * time.Second, - - StatusCodeFunc: func(code int) bool { - return code == http.StatusOK - }, - } - - // 根据传入的选项更新默认选项 - for _, option := range options { - option(o) - } - - req, err := http.NewRequest(method, url, bytes.NewBuffer(body)) - if err != nil { - return nil, nil, fmt.Errorf("创建HTTP请求失败: %w", err) - } - req.Header = o.Headers - - httpClient := &http.Client{ - Timeout: o.Timeout, - } - resp, err := httpClient.Do(req) - if err != nil { - return nil, nil, fmt.Errorf("发送HTTP请求失败: %w", err) - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return nil, nil, fmt.Errorf("读取响应体失败: %w", err) - } - - if !o.StatusCodeFunc(resp.StatusCode) { - return nil, nil, fmt.Errorf("请求异常:%s", resp.Status) - } - - return resp.Header, bodyBytes, nil -} diff --git a/utils/request/v2/request_test.go b/utils/request/v2/request_test.go deleted file mode 100644 index feb7ea6..0000000 --- a/utils/request/v2/request_test.go +++ /dev/null @@ -1,66 +0,0 @@ -package v2 - -import ( - "context" - "net/http" - "net/url" - "testing" - "time" -) - -func Test_Get(t *testing.T) { - uri := "https://gateway.dev.cdlsxd.cn/adminyx/admin/v1/key_batch/list" - - uv := url.Values{} - uv.Set("page", "1") - uv.Set("limit", "2") - - h := http.Header{ - "Content-Type": []string{"application/x-www-form-urlencoded"}, - } - respHeader, respBody, err := Get(context.Background(), uri+"?"+uv.Encode(), WithHeaders(h)) - if err != nil { - t.Error(err) - return - } - - t.Logf("响应体:", string(respBody)) - t.Logf("响应头:", respHeader) -} - -func Test_RequestHeaders(t *testing.T) { - uri := "http://example.com/api" - body := []byte("request body") - - h := http.Header{ - "Content-Type": []string{"application/json"}, - "Authorization": []string{"Bearer token"}, - } - - respHeader, respBody, err := Post(context.Background(), uri, body, WithTimeout(10*time.Second), WithHeaders(h)) - if err != nil { - t.Error(err) - return - } - - t.Logf("响应体:", string(respBody)) - t.Logf("响应头:", respHeader) -} - -func Test_RequestStatusCode(t *testing.T) { - uri := "http://example.com/api/update" - body := []byte("update data") - - isSuccess := func(code int) bool { - return code == http.StatusOK || code == http.StatusCreated - } - - respHeader, respBody, err := Put(context.Background(), uri, body, WithStatusCodeFunc(isSuccess)) - if err != nil { - t.Error(err) - return - } - - t.Logf("响应体:", string(respBody)) - t.Logf("响应头:", respHeader) -}