132 lines
3.9 KiB
Go
132 lines
3.9 KiB
Go
package starnet
|
||
|
||
import (
|
||
"context"
|
||
"crypto/tls"
|
||
"io"
|
||
"net"
|
||
"net/http"
|
||
"time"
|
||
)
|
||
|
||
// HTTP Content-Type 常量
|
||
const (
|
||
ContentTypeFormURLEncoded = "application/x-www-form-urlencoded"
|
||
ContentTypeFormData = "multipart/form-data"
|
||
ContentTypeJSON = "application/json"
|
||
ContentTypeXML = "application/xml"
|
||
ContentTypePlain = "text/plain"
|
||
ContentTypeHTML = "text/html"
|
||
ContentTypeOctetStream = "application/octet-stream"
|
||
)
|
||
|
||
// 默认配置
|
||
const (
|
||
DefaultDialTimeout = 5 * time.Second
|
||
DefaultTimeout = 10 * time.Second
|
||
DefaultUserAgent = "Starnet/1.0.0"
|
||
DefaultFetchRespBody = false
|
||
)
|
||
|
||
// RequestFile 表示要上传的文件
|
||
type RequestFile struct {
|
||
FormName string // 表单字段名
|
||
FileName string // 文件名
|
||
FilePath string // 文件路径(如果从文件读取)
|
||
FileData io.Reader // 文件数据流
|
||
FileSize int64 // 文件大小
|
||
FileType string // MIME 类型
|
||
}
|
||
|
||
// UploadProgressFunc 文件上传进度回调函数
|
||
type UploadProgressFunc func(filename string, uploaded int64, total int64)
|
||
|
||
// NetworkConfig 网络配置
|
||
type NetworkConfig struct {
|
||
Proxy string // 代理地址
|
||
DialTimeout time.Duration // 连接超时
|
||
Timeout time.Duration // 总超时
|
||
DialFunc func(ctx context.Context, network, addr string) (net.Conn, error)
|
||
}
|
||
|
||
// TLSConfig TLS 配置
|
||
type TLSConfig struct {
|
||
Config *tls.Config // TLS 配置
|
||
SkipVerify bool // 跳过证书验证
|
||
}
|
||
|
||
// DNSConfig DNS 配置
|
||
type DNSConfig struct {
|
||
CustomIP []string // 直接指定 IP(最高优先级)
|
||
CustomDNS []string // 自定义 DNS 服务器
|
||
LookupFunc func(ctx context.Context, host string) ([]net.IPAddr, error) // 自定义解析函数
|
||
}
|
||
|
||
// BodyConfig 请求体配置
|
||
type BodyConfig struct {
|
||
Bytes []byte // 原始字节
|
||
Reader io.Reader // 数据流
|
||
FormData map[string][]string // 表单数据
|
||
Files []RequestFile // 文件列表
|
||
}
|
||
|
||
// RequestConfig 请求配置(内部使用)
|
||
type RequestConfig struct {
|
||
Network NetworkConfig
|
||
TLS TLSConfig
|
||
DNS DNSConfig
|
||
Body BodyConfig
|
||
Headers http.Header
|
||
Cookies []*http.Cookie
|
||
Queries map[string][]string
|
||
|
||
// 其他配置
|
||
BasicAuth [2]string // Basic 认证
|
||
ContentLength int64 // 手动设置的 Content-Length
|
||
AutoCalcContentLength bool // 自动计算 Content-Length
|
||
UploadProgress UploadProgressFunc // 上传进度回调
|
||
|
||
// Transport 配置
|
||
CustomTransport bool // 是否使用自定义 Transport
|
||
Transport *http.Transport // 自定义 Transport
|
||
}
|
||
|
||
// Clone 克隆配置
|
||
func (c *RequestConfig) Clone() *RequestConfig {
|
||
return &RequestConfig{
|
||
Network: NetworkConfig{
|
||
Proxy: c.Network.Proxy,
|
||
DialTimeout: c.Network.DialTimeout,
|
||
Timeout: c.Network.Timeout,
|
||
DialFunc: c.Network.DialFunc,
|
||
},
|
||
TLS: TLSConfig{
|
||
Config: cloneTLSConfig(c.TLS.Config),
|
||
SkipVerify: c.TLS.SkipVerify,
|
||
},
|
||
DNS: DNSConfig{
|
||
CustomIP: cloneStringSlice(c.DNS.CustomIP),
|
||
CustomDNS: cloneStringSlice(c.DNS.CustomDNS),
|
||
LookupFunc: c.DNS.LookupFunc,
|
||
},
|
||
Body: BodyConfig{
|
||
Bytes: cloneBytes(c.Body.Bytes),
|
||
Reader: c.Body.Reader, // Reader 不可克隆
|
||
FormData: cloneStringMapSlice(c.Body.FormData),
|
||
Files: cloneFiles(c.Body.Files),
|
||
},
|
||
Headers: cloneHeader(c.Headers),
|
||
Cookies: cloneCookies(c.Cookies),
|
||
Queries: cloneStringMapSlice(c.Queries),
|
||
BasicAuth: c.BasicAuth,
|
||
ContentLength: c.ContentLength,
|
||
AutoCalcContentLength: c.AutoCalcContentLength,
|
||
UploadProgress: c.UploadProgress,
|
||
CustomTransport: c.CustomTransport,
|
||
Transport: c.Transport, // Transport 共享
|
||
}
|
||
}
|
||
|
||
// RequestOpt 请求选项函数
|
||
type RequestOpt func(*Request) error
|