plugins/utils/request/request.go

100 lines
2.3 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"
)
// Options 用于配置请求的各种选项
type Options struct {
Headers http.Header
StatusCodeFunc func(int) bool
Timeout time.Duration
}
// Option 是一个函数类型用于设置RequestOptions的各个字段
type Option func(*Options)
// WithTimeout 设置请求超时时间的选项函数
func WithTimeout(timeout time.Duration) Option {
return func(options *Options) {
options.Timeout = timeout
}
}
// WithHeaders 设置请求头的选项函数
func WithHeaders(headers http.Header) Option {
return func(options *Options) {
options.Headers = headers
}
}
// WithStatusCodeFunc 设置自定义状态码处理函数的选项函数
func WithStatusCodeFunc(statusCodeFunc func(int) bool) Option {
return func(options *Options) {
options.StatusCodeFunc = statusCodeFunc
}
}
func Post(ctx context.Context, url string, body []byte, options ...Option) (http.Header, []byte, error) {
return Request(ctx, http.MethodPost, url, body, options...)
}
func Get(ctx context.Context, url string, options ...Option) (http.Header, []byte, error) {
return Request(ctx, http.MethodGet, url, nil, options...)
}
func Put(ctx context.Context, url string, body []byte, options ...Option) (http.Header, []byte, error) {
return Request(ctx, http.MethodPut, url, body, options...)
}
func Request(_ context.Context, method, url string, body []byte, options ...Option) (http.Header, []byte, error) {
o := &Options{
Headers: http.Header{
"Content-Type": []string{"application/json"},
},
StatusCodeFunc: func(code int) bool {
return code == http.StatusOK
},
Timeout: 15 * time.Second,
}
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
}