请求选项
请求选项是函数式配置项,通过 RequestOption 类型传递给请求方法,实现细粒度的请求控制。
result, err := client.Post(url,
httpc.WithJSON(data),
httpc.WithBearerToken(token),
httpc.WithQuery("page", 1),
)所有选项可自由组合,按传入顺序依次应用。
请求头
WithHeader
func WithHeader(key, value string) RequestOption设置单个请求头。键和值经过安全验证(CRLF 注入防护)。
result, err := client.Get(url,
httpc.WithHeader("X-Custom", "value"),
)WithHeaderMap
func WithHeaderMap(headers map[string]string) RequestOption批量设置请求头。
result, err := client.Get(url,
httpc.WithHeaderMap(map[string]string{
"Accept": "application/json",
"X-Request-ID": "abc123",
}),
)WithUserAgent
func WithUserAgent(userAgent string) RequestOption设置 User-Agent 头。是 WithHeader("User-Agent", ...) 的便捷包装。
认证
WithBasicAuth
func WithBasicAuth(username, password string) RequestOption设置 HTTP Basic 认证。用户名不能为空,凭据长度有限制。
result, err := client.Get(url,
httpc.WithBasicAuth("admin", "password"),
)WithBearerToken
func WithBearerToken(token string) RequestOption设置 Authorization: Bearer <token> 头。Token 不能为空。
result, err := client.Get(url,
httpc.WithBearerToken("eyJhbGciOiJIUzI1NiIs..."),
)请求体
WithJSON
func WithJSON(data any) RequestOption设置 JSON 请求体,自动添加 Content-Type: application/json。
result, err := client.Post(url,
httpc.WithJSON(map[string]any{
"name": "test",
"email": "[email protected]",
}),
)WithXML
func WithXML(data any) RequestOption设置 XML 请求体,自动添加 Content-Type: application/xml。
WithForm
func WithForm(data map[string]string) RequestOption设置 URL 编码表单请求体,自动添加 Content-Type: application/x-www-form-urlencoded。
result, err := client.Post(url,
httpc.WithForm(map[string]string{
"username": "admin",
"password": "secret",
}),
)WithFormData
func WithFormData(data *FormData) RequestOption设置 multipart/form-data 请求体,支持文件和字段混合上传。
result, err := client.Post(url,
httpc.WithFormData(&httpc.FormData{
Fields: map[string]string{"description": "upload"},
Files: map[string]*httpc.FileData{
"file": {Filename: "doc.pdf", Content: fileBytes},
},
}),
)WithFile
func WithFile(fieldName, filename string, content []byte) RequestOption便捷文件上传。自动构建 multipart 请求体,文件名经过路径遍历防护处理。
result, err := client.Post(url,
httpc.WithFile("upload", "report.csv", csvBytes),
)WithBinary
func WithBinary(data []byte, contentType ...string) RequestOption设置二进制请求体。默认 Content-Type 为 application/octet-stream,可自定义。
result, err := client.Post(url,
httpc.WithBinary(imageBytes, "image/png"),
)WithBody
func WithBody(data any, kind ...BodyKind) RequestOption通用请求体设置,支持自动检测和显式指定类型。
自动检测规则(默认 BodyAuto):
| 输入类型 | Content-Type |
|---|---|
string | text/plain; charset=utf-8 |
[]byte | application/octet-stream |
map[string]string | application/x-www-form-urlencoded |
*FormData | multipart/form-data |
io.Reader | 不设置(由调用方处理) |
| 其他类型 | application/json |
显式指定类型:
// 自动检测(默认)
result, _ := client.Post(url, httpc.WithBody(data))
// 强制 JSON
result, _ := client.Post(url, httpc.WithBody(data, httpc.BodyJSON))
// 强制 XML
result, _ := client.Post(url, httpc.WithBody(data, httpc.BodyXML))| 常量 | 含义 |
|---|---|
BodyAuto | 自动检测(默认) |
BodyJSON | 强制 JSON |
BodyXML | 强制 XML |
BodyForm | 强制表单 |
BodyBinary | 强制二进制 |
BodyMultipart | 强制 multipart(需要 *FormData) |
查询参数
WithQuery
func WithQuery(key string, value any) RequestOption设置单个查询参数。
result, err := client.Get(url,
httpc.WithQuery("page", 1),
httpc.WithQuery("limit", 10),
)WithQueryMap
func WithQueryMap(params map[string]any) RequestOption批量设置查询参数。
result, err := client.Get(url,
httpc.WithQueryMap(map[string]any{
"page": 1,
"limit": 10,
"sort": "created_at",
}),
)Cookie
WithCookie
func WithCookie(cookie http.Cookie) RequestOption添加单个 Cookie,经过安全验证。
result, err := client.Get(url,
httpc.WithCookie(http.Cookie{Name: "session", Value: "abc123"}),
)WithCookies
func WithCookies(cookies []http.Cookie) RequestOption批量添加 Cookie,比多次调用 WithCookie 更高效——预分配容量并在单次遍历中验证所有 Cookie。
cookies := []http.Cookie{
{Name: "session_id", Value: "abc123"},
{Name: "user_pref", Value: "dark_mode"},
{Name: "lang", Value: "en"},
}
result, err := client.Get("https://api.example.com",
httpc.WithCookies(cookies),
)WithCookieMap
func WithCookieMap(cookies map[string]string) RequestOption批量添加简单 Cookie。适合仅需 name-value 的场景。
result, err := client.Get(url,
httpc.WithCookieMap(map[string]string{
"session_id": "abc123",
"lang": "zh",
}),
)WithCookieString
func WithCookieString(cookieString string) RequestOption从原始 Cookie 头字符串添加 Cookie。
result, err := client.Get(url,
httpc.WithCookieString("session=abc123; lang=zh"),
)WithSecureCookie
func WithSecureCookie(securityConfig *CookieSecurityConfig) RequestOption强制验证请求 Cookie 的安全属性(Secure、HttpOnly、SameSite)。
选项顺序
此选项仅校验应用时已存在的 Cookie。必须将 WithSecureCookie 放在所有 WithCookie/WithCookies/WithCookieMap/WithCookieString 之后,否则后添加的 Cookie 不会被校验。如需不受顺序限制的会话级 Cookie 安全校验,请使用 SessionManager.SetCookieSecurity。
// 正确顺序:先添加 Cookie,再校验
result, err := client.Get(url,
httpc.WithCookie(sessionCookie),
httpc.WithCookieMap(otherCookies),
httpc.WithSecureCookie(httpc.StrictCookieSecurityConfig()),
)请求控制
WithContext
func WithContext(ctx context.Context) RequestOption设置请求上下文,支持超时和取消。上下文不能为 nil。
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
result, err := client.Get(url, httpc.WithContext(ctx))WithTimeout
func WithTimeout(timeout time.Duration) RequestOption设置单次请求超时,覆盖客户端默认超时。范围:0 到 30 分钟。
result, err := client.Get(url, httpc.WithTimeout(5*time.Second))WithMaxRetries
func WithMaxRetries(maxRetries int) RequestOption设置单次请求最大重试次数,覆盖客户端配置。范围:0-10。
result, err := client.Get(url, httpc.WithMaxRetries(3))WithFollowRedirects
func WithFollowRedirects(follow bool) RequestOption控制是否跟随重定向。
// 禁止跟随重定向
result, err := client.Get(url, httpc.WithFollowRedirects(false))WithMaxRedirects
func WithMaxRedirects(maxRedirects int) RequestOption设置单次请求最大重定向次数。范围:0-50。
0 值语义
0 不会禁用重定向。引擎将 0 视为「未显式设置」的哨兵值,回退到默认上限(10),因此 WithMaxRedirects(0) 等价于省略该选项。要完全禁用重定向跟随,请改用 WithFollowRedirects(false)。
WithAllowPrivateIPs
func WithAllowPrivateIPs(allow bool) RequestOption为单次请求覆盖客户端的 SSRF 策略。当 allow 为 true 时,该请求可访问 localhost 和私有/保留 IP 段(127.0.0.0/8、10.0.0.0/8、192.168.0.0/16、169.254.0.0/16 等),并可跟随到此类地址的重定向;为 false 时,即使客户端配置了 Security.AllowPrivateIPs=true,本次请求仍强制启用 SSRF 防护。
安全提示
这是 SSRF 防护的单次请求逃生舱,适用于默认安全的客户端(AllowPrivateIPs=false)偶尔需要访问内部服务、回环地址或本地开发服务器的场景。
仅在请求 URL 可信且非来自不受信任的用户输入时启用。若需整客户端访问内部服务,应直接在 Config 上设置 Security.AllowPrivateIPs=true。
// 默认客户端阻止私有 IP;本次调用逐请求放行
result, err := httpc.Get("http://localhost:8080/health",
httpc.WithAllowPrivateIPs(true),
)WithStreamBody
func WithStreamBody(stream bool) RequestOption启用流式模式,响应体不缓存到内存。
重要限制
流式模式仅通过 Download 生效。与标准请求方法(Get/Post/Put/Patch/Delete/Head/Options/Request)配合使用时,响应体会被完整读入并转换为 Result,随后底层流被关闭——返回的 Result 响应体为空,调用方无法消费该流。
要真正流式下载大文件而不缓存到内存,请使用 Download。
回调
WithOnRequest
func WithOnRequest(callback func(req RequestMutator) error) RequestOption注册请求发送前的回调。可链式注册多个,按添加顺序执行。回调返回错误会中止请求。
result, err := client.Get(url,
httpc.WithOnRequest(func(req httpc.RequestMutator) error {
log.Printf("发送 %s %s", req.Method(), req.URL())
return nil
}),
)WithOnResponse
func WithOnResponse(callback func(resp ResponseMutator) error) RequestOption注册响应接收后的回调。可链式注册多个,按添加顺序执行。
result, err := client.Get(url,
httpc.WithOnResponse(func(resp httpc.ResponseMutator) error {
log.Printf("收到响应: %d %s", resp.StatusCode(), resp.Status())
return nil
}),
)