http Host &Set Host in Golang Go语言http包Header设置Host未生效

Host是http1.1版本添加的Header, 可以用于指定具体的Host,通常该Header的值会从URL中自动解析。例如我们请求http://httpbin.org/anything?pass=111,返回的结果如下:

{
    "args": {
        "pass": "111"
    },
    "data": "",
    "files": {},
    "form": {},
    "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate",
        "Cache-Control": "no-cache",
        "Host": "httpbin.org",
        "Postman-Token": "d2d7c62b-8144-4926-88c3-5bb06b5d4a3a",
        "User-Agent": "PostmanRuntime/7.13.0"
    },
    "json": null,
    "method": "GET",
    "origin": "111.111.111.111, 111.111.111.111",
    "url": "https://httpbin.org/anything?pass=111"
}

HeaderHost为自动填充的信息,本例中就是httpbin.org
但是如果我们请求IP的时候呢?通过解析工具得知httpbin.org的IP为:34.230.136.58,我们改去请求http://34.230.136.58/anything?pass=111,得到的结果如下:

{
    "args": {
        "pass": "111"
    },
    "data": "",
    "files": {},
    "form": {},
    "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate",
        "Cache-Control": "no-cache",
        "Host": "34.230.136.58",
        "Postman-Token": "ef2f8e19-130e-477e-9da5-517c4d13fb95",
        "User-Agent": "PostmanRuntime/7.13.0"
    },
    "json": null,
    "method": "GET",
    "origin": "111.111.111.111, 111.111.111.111",
    "url": "https://34.230.136.58/anything?pass=111"
}

可以看到Host变成了我们请求的IP地址。

但是上边两个示例并没有说明白Host这个属性到底是干嘛的 - -。

让我们假象一种情况,也是实际中常见的情况:
一台机器上同一IP绑定了不同的域名(可以通过域名提供商设置,或者Nginx),可能不同的域名解析出的IP都是111.111.111.111,那么这个时候Host的值就很有用了,它可以用于区分到底是哪个站点。
由于我们平常大部分时候都是用过域名访问的,所以不用纠结这个问题。但是如果利用IP访问的话,就需要手动指定一下Host了。

还比如某个IP通过Nginx转发到了指定的服务,那么你想访问另一个服务时候怎么办呢?
要么改用域名访问,要么请求IP的时候修改Header设置Host的值为你想要访问的服务的域名。

但是,在Golang中,利用req.Header.Set()req.Header.Add()方法是无法设置Host的值的,可以在http包的request.go文件Header的声明注释内看到:

// For incoming requests, the Host header is promoted to the
// Request.Host field and removed from the Header map.

Header的设置中把Host给屏蔽掉了,需要利用Request.Host来设置Host值。Google一下,有人提过issue: net/http: Setting custom “Host” request header doesn’t have effect #7682,最后也只是改动了文档,并没有说明为什么这样做。可能是为了方便吧。。。

参考文献:
https://stackoverflow.com/questions/12864302/how-to-set-headers-in-http-get-request
net/http: Setting custom “Host” request header doesn’t have effect #7682
网络—一篇文章详解请求头Host的概念

你可能感兴趣的:(GO)