When developing golang http application, I use http.Request
a lot. 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.
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.
// 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:
GET http://localhost:8080/ HTTP/1.1
Host: localhost:8080
But it does not solve many problems than it creates:
- Why are there two different
Host
field in request? I mean isn't this a duplicate? - Can the two
Host
fields be different in the same request? - Which one should I use for what situation?
Answers with a real HTTP request example would be the best. Thanks in advance.