[英]What is the difference between `Host` and `URL.Host` for golang `http.Request`?
When developing golang http application, I use http.Request
a lot. 在开发golang http应用程序时,我http.Request
使用http.Request
。 When accessing request host address, I would use req.Host
, but I find that there is req.URL.Host
field, but when I print it, it's empty. 当访问请求主机地址时,我会使用req.Host
,但我发现有req.URL.Host
字段,但是当我打印它时,它是空的。
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Println("uri Host: " + r.URL.Host + " Scheme: " + r.URL.Scheme)
fmt.Println("Host: " + r.Host)
}
The documentation of http.Request gives the following comments, while net/url
does not give much clue. http.Request的文档给出了以下注释,而net/url
没有提供太多线索。
// For server requests Host specifies the host on which the
// URL is sought. Per RFC 2616, this is either the value of
// the "Host" header or the host name given in the URL itself.
// It may be of the form "host:port". For international domain
// names, Host may be in Punycode or Unicode form. Use
// golang.org/x/net/idna to convert it to either format if
// needed.
//
// For client requests Host optionally overrides the Host
// header to send. If empty, the Request.Write method uses
// the value of URL.Host. Host may contain an international
// domain name.
Host string
It seems to me that there are two host value in a request: uri line and Host
header, like: 在我看来,请求中有两个主机值:uri行和Host
头,如:
GET http://localhost:8080/ HTTP/1.1
Host: localhost:8080
But it does not solve many problems than it creates: 但它并没有解决许多问题而不是它造成的问题:
Host
field in request? 为什么请求中有两个不同的Host
字段? I mean isn't this a duplicate? 我的意思是这不是重复的吗? Host
fields be different in the same request? 两个Host
字段在同一个请求中是否可以不同? Answers with a real HTTP request example would be the best. 具有真实HTTP请求示例的答案将是最好的。 Thanks in advance. 提前致谢。
The r.URL
field is created by parsing the HTTP request URI. r.URL
字段是通过解析HTTP请求URI创建的。
The r.Host
field is the value of the Host request header . r.Host
字段是Host请求标头的值。 It's the same value as calling r.Header.Get("Host")
. 它与调用r.Header.Get("Host")
值相同。
If the HTTP request on the wire is: 如果线路上的HTTP请求是:
GET /pub/WWW/TheProject.html HTTP/1.1
Host: www.example.org:8080
then r.URL.Host
is "" and r.Host
is www.example.org:8080
. 然后r.URL.Host
是“”而r.Host
是www.example.org:8080
。
The value of r.URL.Host
and r.Host
are almost always different. r.URL.Host
和r.Host
的值几乎总是不同的。 On a proxy server, r.URL.Host
is the host of the target server and r.Host
is the host of the proxy server itself. 在代理服务器上, r.URL.Host
是目标服务器的主机, r.Host
是代理服务器本身的主机。 When not connecting through a proxy, the client does not specify a host in the request URI. 未通过代理连接时,客户端不会在请求URI中指定主机。 In this scenario, r.URL.Host
is the empty string. 在这种情况下, r.URL.Host
是空字符串。
If you are not implementing a proxy, then you should use r.Host
to determine the host. 如果您没有实现代理,那么您应该使用r.Host
来确定主机。
Essentially http.Request.Host
is for convenience. 基本上http.Request.Host
是为了方便起见。
r.Host
is much easier to call than r.Header.Get("Host")
or r.URL.Host
. r.Host
比r.Header.Get("Host")
或r.URL.Host
更容易调用。
Also to be noted that some routers strip the host from http.Request.URL
so http.Request.Host
is useful in those cases as well. 还需要注意的是,有些路由器会从http.Request.URL
剥离主机,因此http.Request.Host
在这些情况下也很有用。
Hence it can be considered that req.Host provides the Host value even when the request header or url has been modified elsewhere. 因此,可以认为req.Host即使在其他地方修改了请求标头或URL时也提供了Host值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.