如何在 golang net/http 中使用 Transport 添加头信息

Posted

技术标签:

【中文标题】如何在 golang net/http 中使用 Transport 添加头信息【英文标题】:How to add headers info using Transport in golang net/http 【发布时间】:2017-05-04 22:10:47 【问题描述】:

我正在尝试通过创建 Trasport 来控制 keep-alives 会话以重用 tcp 连接。

这是我的 sn-p,我不确定如何添加标头信息以进行身份​​验证。

url := "http://localhost:8181/api/v1/resource"
tr := &http.Transport
    DisableKeepAlives:   false,
    MaxIdleConns:        0,
    MaxIdleConnsPerHost: 0,
    IdleConnTimeout:     time.Second * 10,

client := &http.ClientTransport: tr
resp, err := client.Get(url)

【问题讨论】:

你没有。标头取自*http.Request。 DisableKeepAlives 的默认值为 false,这意味着将尽可能重用连接。 所以,看起来我不需要创建 Transport,因为它的 DisableKeepAlives 默认为 false。 另外,如果您要覆盖DefaultTransport,您仍应确保复制所有重要设置,即您几乎总是需要一个带超时的 DialContext。 (并且您的前 3 个字段是零值,因此设置它们不会做任何事情) @JimB 尝试使用 go-routine 但 TCP 连接数正在堆积。 你用 goroutine 做什么?你应该有一个传输,可能是 DefaultTransport,不管任何 goroutines。 【参考方案1】:

不要混合请求中的Client。 客户端使用Transport 并运行请求:client.Do(req)

你用(h Header) Set(key, value string)http.Request上设置了标题:

req.Header.Set("name", "value")

【讨论】:

好吧,让我试试。那么,如果我想自定义传输结构,我应该怎么做。 @James 你已经在做什么了。标头是在请求中设置的。 这里,我尝试通过多个 goroutine 使用。因此,考虑只创建一次并重复使用它。 @James:是的,你应该只使用1个Transport,但这仍然与在每个请求中设置标头无关。 @James 你想设置什么标题?根据您的协议,您可能仅在第一次写入时才需要它们,例如在 grpc 中:github.com/grpc/grpc-go/blob/…【参考方案2】:

这是我发现的:

    package main

    import (
        "fmt"
        "io/ioutil"
        "net/http"
    )

    var URL = "http://httpbin.org/ip"

    func main() 
        tr := &http.TransportDisableKeepAlives: false
        req, _ := http.NewRequest("GET", URL, nil)
        req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", "Token"))
        req.Close = false

        res, err := tr.RoundTrip(req)
        if err != nil 
            fmt.Println(err)
        
        body, _ := ioutil.ReadAll(res.Body)
        fmt.Println(string(body))
    

而且它有效。

【讨论】:

这似乎符合我在回答中的建议。 +1【参考方案3】:

对于您的特定问题,这可能不是您想要的 - 在请求中设置它在您的情况下更有意义,但要直接回答您的问题,您应该能够为通过使用自定义的 RoundTrip 方法进行传输。

查看https://golang.org/pkg/net/http/#RoundTripper

类似:

type CustomTransport struct 
  http.RoundTripper


func (ct *CustomTransport) RoundTrip(req *http.Request) (*http.Response, error) 
    req.Header.Add("header-key", "header-value")
    return ct.RoundTripper.RoundTrip(req)


url := "http://localhost:8181/api/v1/resource"
tr := &CustomTransport
    DisableKeepAlives:   false,
    MaxIdleConns:        0,
    MaxIdleConnsPerHost: 0,
    IdleConnTimeout:     time.Second * 10,

client := &http.ClientTransport: tr
resp, err := client.Get(url)

当我无法直接访问 API 客户端库(或每个请求对象)使用的 http 客户端时,我发现这很有用,但它允许我传入传输。

【讨论】:

Can't modify the request in your RoundTripper "// RoundTrip 不应该修改请求" pkg.go.dev/net/http#RoundTripper

以上是关于如何在 golang net/http 中使用 Transport 添加头信息的主要内容,如果未能解决你的问题,请参考以下文章

golang如何创建反向代理

如何在 Golang 中使用 HTTP/2 写入/读取/发送数据帧?

如何使用 Golang net/http 服务器接收上传的文件?

Golang pprof详解

是否可以使用 net/http 在 golang 中托管多个域 TLS?

golang http proxy反向代理