plugins/utils/request/request.go

101 lines
2.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package request
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
}