Kir*_*ill 4 go http-headers go-http
我知道我可以使用手动向每个 HTTP 请求添加标头
cli := &http.Client{}
req, err := http.NewRequest("GET", "https://myhost", nil)
req.Header.Add("X-Test", "true")
if err != nil {
panic(err)
}
rsp, err := cli.Do(req)
Run Code Online (Sandbox Code Playgroud)
但我想为我的应用程序中的每个 HTTP 请求自动添加此标头。
最好的方法是什么?
我知道三个可能的解决方案。在(我的)优先顺序中:
http.NewRequest
使用添加所需标头的自定义代码包装:
func MyRequest(method, path url, body io.Reader) (*http.Request, error) {
req, err := http.NewRequest(method, path, body)
if err != nil {
return nil, err
}
req.Header.Add("X-Test", "true")
return req, nil
}
Run Code Online (Sandbox Code Playgroud)
这种方法的优点是直接、非魔法和便携。它将与任何第三方软件一起使用,添加自己的标头或设置自定义传输。
唯一不起作用的情况是,如果您依赖第三方库来创建 HTTP 请求。我希望这很少见(我不记得在我自己的经历中曾经遇到过这种情况)。即使在这种情况下,也许您可以改为包装该调用。
包装调用以client.Do
添加标头,以及可能的任何其他共享逻辑。
func MyDo(client *http.Client, req *http.Request) (*http.Response, error) {
req.Header.Add("X-Test", "true")
// Any other common handling of the request
res, err := client.Do(req)
if err != nil {
return nil, err
}
// Any common handling of response
return res, nil
}
Run Code Online (Sandbox Code Playgroud)
这种方法也很简单,并且具有额外的优势(超过 #1),可以轻松减少其他样板文件。这种通用方法也可以很好地与#1 结合使用。一个可能的缺点是您必须始终MyDo
直接调用您的方法,这意味着您不能依赖调用http.Do
自身的第三方软件。
使用自定义 http.Transport
type myTransport struct{}
func (t *myTransport) RoundTrip(req *http.Request) (*http.Response, error) {
req.Header.Add("X-Test", "true")
return http.DefaultTransport.RoundTrip(req)
}
Run Code Online (Sandbox Code Playgroud)
然后像这样使用它:
client := &Client{Transport: &myTransport{}}
req := http.NewRequest("GET", "/foo", nil)
res, err := client.Do(req)
Run Code Online (Sandbox Code Playgroud)
这种方法的优点是几乎可以使用任何其他软件在“幕后”工作,因此如果您依赖第三方库来创建http.Request
对象并调用http.Do
,这可能是您唯一的选择。
但是,这具有不明显的潜在缺点,如果您使用任何还设置自定义传输的第三方软件(而不必费心遵守现有的自定义传输),则可能会中断。
最终,您使用哪种方法将取决于第三方软件需要哪种类型的可移植性。但如果这不是问题,我建议使用最明显的解决方案,据我估计,就是上面提供的顺序。
归档时间: |
|
查看次数: |
4580 次 |
最近记录: |