Skip to content

配置

Config

go
type Config struct {
    Timeouts   *TimeoutConfig
    Connection *ConnectionConfig
    Security   *SecurityConfig
    Retry      *RetryConfig
    Middleware *MiddlewareConfig
}

主配置结构体,通过 DefaultConfig() 获取安全默认值。

子配置为指针

自 v1.5.1 起,五个子配置均为指针类型DefaultConfig() 及所有预设函数(SecureConfigPerformanceConfig 等)会自动初始化这些指针为非空结构体,因此 cfg.Timeouts.Requestcfg.Security.AllowPrivateIPs 等字段访问可直接使用。若手动构造 Config{} 字面量,需用 &httpc.TimeoutConfig{...} 形式赋值,且使用前应确保指针非空。

go
cfg := httpc.DefaultConfig()
cfg.Timeouts.Request = 60 * time.Second
cfg.Retry.MaxRetries = 5
client, err := httpc.New(cfg)

TimeoutConfig

go
type TimeoutConfig struct {
    Request        time.Duration // 总请求超时(含重试),默认 180s
    Dial           time.Duration // TCP 连接超时,默认 10s
    TLSHandshake   time.Duration // TLS 握手超时,默认 10s
    ResponseHeader time.Duration // 等待响应头超时,默认 0(禁用,依赖上下文超时)
    IdleConn       time.Duration // 空闲连接保持时间,默认 90s
}
字段默认值最大值
Request180s30min
Dial10s30min
TLSHandshake10s30min
ResponseHeader030min
IdleConn90s30min

设为 0 表示无超时(生产环境不推荐)。

ResponseHeader 设计

ResponseHeader 默认为 0(禁用),此时使用 TimeoutConfig.RequestWithTimeout() 作为唯一的超时机制,确保 WithTimeout() 对请求持续时间有完全控制。此设计适合 AI API 和长轮询等需要扩展响应时间的场景。仅在需要传输层硬性上限(如防御 Slowloris 攻击)时设为正值,但需注意这会覆盖 WithTimeout

ConnectionConfig

go
type ConnectionConfig struct {
    MaxIdleConns           int           // 全局最大空闲连接,默认 50
    MaxConnsPerHost        int           // 每主机最大连接数,默认 10
    ProxyURL               string        // 代理地址,如 "http://proxy:8080"
    EnableSystemProxy      bool          // 自动检测系统代理,默认 false
    EnableHTTP2            bool          // 启用 HTTP/2,默认 true
    EnableCookies          bool          // 启用 Cookie 管理,默认 false
    EnableDoH              bool          // 启用 DNS-over-HTTPS,默认 false
    DoHCacheTTL            time.Duration // DoH 缓存 TTL,默认 5min
    MaxResponseHeaderBytes int64         // 响应头最大字节数,默认 0(使用 Go 标准库默认 10MB)
}

DNS-over-HTTPS

启用 DoH 减少 DNS 解析延迟和防止 DNS 劫持:

go
cfg := httpc.DefaultConfig()
cfg.Connection.EnableDoH = true
cfg.Connection.DoHCacheTTL = 5 * time.Minute

默认 DoH 提供商(按优先级):Cloudflare → Google → AliDNS。详见 连接池与代理

SecurityConfig

go
type SecurityConfig struct {
    TLSConfig               *tls.Config           // 自定义 TLS 配置
    MinTLSVersion           uint16                // 最低 TLS 版本,默认 TLS 1.2
    MaxTLSVersion           uint16                // 最高 TLS 版本,默认 TLS 1.3
    InsecureSkipVerify      bool                  // 跳过证书验证(仅测试用)
    MaxResponseBodySize     int64                 // 响应体大小限制,默认 10MB
    MaxRequestBodySize      int64                 // 请求体大小限制,默认 0(不限制请求体大小;与 MaxResponseBodySize 不同,无自动回退)
    MaxDecompressedBodySize int64                 // 解压后大小限制,默认 100MB
    AllowPrivateIPs         bool                  // 允许私有 IP,默认 false
    SSRFExemptCIDRs         []string              // SSRF 豁免 CIDR
    ValidateURL             bool                  // URL 验证,默认 true
    ValidateHeaders         bool                  // 请求头验证,默认 true
    StrictContentLength     bool                  // 严格 Content-Length,默认 true
    CookieSecurity          *CookieSecurityConfig // Cookie 安全验证
    CertificatePinner       CertificatePinner     // 证书固定(SPKI 哈希/公钥),默认 nil(禁用)
    RedirectWhitelist       []string              // 重定向白名单域名
}

证书固定(CertificatePinner)

CertificatePinner 启用证书固定:TLS 握手在服务端未提供已固定密钥/证书时将被拒绝,即便受信任 CA 被攻破也可防御中间人攻击。默认 nil(禁用)。通过以下构造函数创建:

构造函数说明
NewSPKIHashPinner(hashes ...string) (CertificatePinner, error)由一个或多个 base64 编码的 SPKI SHA-256 哈希创建(最常用,支持密钥轮换)
NewPublicKeyPinner(publicKeys ...[]byte) (CertificatePinner, error)由 DER 编码的 PKIX 公钥创建(内部计算 SHA-256)
NewCertificatePinnerChain(pinners ...CertificatePinner) CertificatePinner组合多个 pinner,任一通过即接受
go
pinner, err := httpc.NewSPKIHashPinner(
    "YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2fuihg=", // 当前密钥
    "C5+lpZ7tcVwmwQIMcRtPbsQtWLABXhQzejna0wHFr8M=", // 备用密钥(轮换)
)
if err != nil {
    log.Fatal(err)
}

cfg := httpc.DefaultConfig()
cfg.Security.CertificatePinner = pinner
client, err := httpc.New(cfg)

维护成本

证书固定要求在服务端更换证书(如 Let's Encrypt 续期)时同步更新固定值。建议固定多个哈希(当前 + 备用)并建立更新机制,避免因密钥轮换导致连接中断。

SSRF 防护

AllowPrivateIPs 默认为 false,阻止连接到私有/保留 IP(127.0.0.1、10.x、192.168.x 等)。仅在连接内部服务时设为 true

SSRF 豁免示例

go
cfg := httpc.DefaultConfig()
cfg.Security.SSRFExemptCIDRs = []string{
    "10.0.0.0/8",       // VPC 内部
    "100.64.0.0/10",    // Tailscale
}

RetryConfig

go
type RetryConfig struct {
    MaxRetries    int           // 最大重试次数,默认 3
    Delay         time.Duration // 初始重试延迟,默认 1s
    BackoffFactor float64       // 退避倍数,默认 2.0
    EnableJitter  bool          // 启用抖动,默认 true
    MaxRetryDelay time.Duration // 最大重试延迟上限,默认 30s
    CustomPolicy  RetryPolicy   // 自定义重试策略
}
字段默认值范围
MaxRetries30-10
Delay1s0-30min
BackoffFactor2.01.0-10.0
MaxRetryDelay30s0-30min

重试延迟公式:min(Delay * BackoffFactor^attempt + jitter, MaxRetryDelay)

MiddlewareConfig

go
type MiddlewareConfig struct {
    Middlewares     []MiddlewareFunc // 中间件列表
    UserAgent       string           // User-Agent,默认 "httpc/1.0"
    Headers         map[string]string // 默认请求头
    FollowRedirects bool             // 跟随重定向,默认 true
    MaxRedirects    int              // 最大重定向次数,默认 10
}

配置预设

DefaultConfig

go
func DefaultConfig() *Config

安全默认配置。SSRF 防护默认开启。

SecureConfig

go
func SecureConfig() *Config

安全优先配置。更短的超时、禁用自动重定向、严格的 SSRF 防护。

配置项
Request 超时15s
Dial 超时5s
TLSHandshake 超时5s
ResponseHeader 超时10s(Slowloris 防御)
IdleConn 超时30s
MaxIdleConns20
MaxConnsPerHost5
MaxResponseBodySize5MB
MaxRetries1
Delay2s
EnableJittertrue
FollowRedirectsfalse

PerformanceConfig

go
func PerformanceConfig() *Config

高吞吐配置。更大连接池、更长超时,保持安全验证。

TIP

PerformanceConfig 保持 ValidateURLValidateHeaders 开启以确保安全性。在可信环境中如需最大性能,可手动关闭:cfg.Security.ValidateURL = false,但需注意安全风险(注入攻击、SSRF)。

配置项
Request 超时60s
Dial 超时15s
TLSHandshake 超时15s
ResponseHeader 超时0(禁用,使用 Request 超时)
IdleConn 超时120s
MaxIdleConns100
MaxConnsPerHost20
EnableCookiestrue
MaxResponseBodySize50MB
StrictContentLengthfalse
ValidateURLtrue
ValidateHeaderstrue
Delay500ms
BackoffFactor1.5
EnableJittertrue

TestingConfig

go
func TestingConfig() *Config

测试环境配置。禁用安全检查、短超时。

配置项
Dial 超时5s
TLSHandshake 超时5s
ResponseHeader 超时0(禁用,使用 Request 超时)
IdleConn 超时30s
MaxIdleConns10
MaxConnsPerHost5
EnableHTTP2false
EnableCookiestrue
InsecureSkipVerifytrue
AllowPrivateIPstrue
ValidateURLfalse
ValidateHeadersfalse
MaxRetries1
Delay100ms
EnableJitterfalse
UserAgenthttpc-test/1.0

DANGER

此配置禁用 TLS 验证和 SSRF 防护,仅用于测试。在非测试环境使用会打印安全警告(详见 安全警告输出)。

MinimalConfig

go
func MinimalConfig() *Config

轻量级配置。禁用重试和重定向,最小连接池。

配置项
Dial 超时5s
TLSHandshake 超时5s
ResponseHeader 超时0(禁用,使用 Request 超时)
IdleConn 超时30s
MaxIdleConns10
MaxConnsPerHost2
MaxResponseBodySize1MB
MaxRetries0
Delay0
BackoffFactor1.0
EnableJitterfalse
FollowRedirectsfalse

安全警告输出

SetSecurityWarnOutput

go
func SetSecurityWarnOutput(w io.Writer)

重定向安全警告的输出目标。当使用 TestingConfig() 或将 SecurityConfig.InsecureSkipVerifyConfig.Security)设为 true 时,httpc 会向该 writer 打印 [SECURITY WARNING] 级别的告警(每种警告每进程最多打印一次)。默认输出到 os.Stderr;传入 io.Discard 可完全抑制警告,便于测试或已知安全的内部场景静默运行。

go
// 测试中抑制安全警告
httpc.SetSecurityWarnOutput(io.Discard)
cfg := httpc.TestingConfig()

影响范围

此设置是进程级全局状态,影响所有后续创建的客户端。TestingConfigInsecureSkipVerify 两种告警各自独立计数(互不影响触发),但共享同一输出 writer。

验证

ValidateConfig

go
func ValidateConfig(cfg *Config) error

验证配置有效性。New() 内部会自动调用,也可显式调用。

go
cfg := httpc.DefaultConfig()
cfg.Retry.MaxRetries = 100 // 超出范围

if err := httpc.ValidateConfig(cfg); err != nil {
    log.Fatal(err) // invalid retry configuration: Retry.MaxRetries must be 0-10, got 100
}

Config.String

go
func (c *Config) String() string

返回安全的字符串表示。ProxyURL 凭据会被脱敏,TLSConfig 显示为 <configured><default>,Headers 不会被输出。

go
cfg := httpc.DefaultConfig()
fmt.Println(cfg.String())
// Config{Timeouts:{Request: 3m0s, ...}, Security:{TLSConfig: <default>, ...}}

CookieSecurityConfig

go
type CookieSecurityConfig struct {
    RequireSecure                bool
    RequireHttpOnly              bool
    RequireSameSite              string
    AllowSameSiteNone            bool
    RequireSecureForSameSiteNone bool
}

Cookie 安全属性验证配置。

字段类型说明
RequireSecurebool要求 Cookie 设置 Secure 属性
RequireHttpOnlybool要求 Cookie 设置 HttpOnly 属性
RequireSameSitestring要求的 SameSite 值,如 "Strict""Lax";空字符串表示不检查
AllowSameSiteNonebool是否允许 SameSite=None
RequireSecureForSameSiteNoneboolSameSite=None 时要求 Secure 属性(默认 true

DefaultCookieSecurityConfig

go
func DefaultCookieSecurityConfig() *CookieSecurityConfig

默认 Cookie 安全配置。不要求 Secure/HttpOnly/SameSite 属性,但强制 SameSite=None 的 Cookie 必须设置 Secure。

StrictCookieSecurityConfig

go
func StrictCookieSecurityConfig() *CookieSecurityConfig

严格 Cookie 安全配置。要求 Secure、HttpOnly 和 SameSite=Strict。

go
cfg := httpc.DefaultConfig()
cfg.Security.CookieSecurity = httpc.StrictCookieSecurityConfig()