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:
Host
field in request? I mean isn't this a duplicate?Host
fields be different in the same request?Answers with a real HTTP request example would be the best. Thanks in advance.
To get a hostname or domain from a URL in Go, first, use the url. Parse() function, which parses the URL given as input, and then use the url. Hostname() method, which returns the hostname. If you do not want the www.
The host name identifies the host that holds the resource. For example, www.example.com . A server provides services in the name of the host, but hosts and servers do not have a one-to-one mapping. Refer to Host names.
context is a standard package of Golang that makes it easy to pass request-scoped values, cancelation signals, and deadlines across API boundaries to all the goroutines involved in handling a request.
The r.URL
field is created by parsing the HTTP request URI.
The r.Host
field is the value of the Host request header. It's the same value as calling r.Header.Get("Host")
.
If the HTTP request on the wire is:
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
.
The value of r.URL.Host
and r.Host
are almost always different. 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. When not connecting through a proxy, the client does not specify a host in the request URI. In this scenario, r.URL.Host
is the empty string.
If you are not implementing a proxy, then you should use r.Host
to determine the host.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With