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