Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between `Host` and `URL.Host` for golang `http.Request`?

Tags:

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:

  1. Why are there two different Host field in request? I mean isn't this a duplicate?
  2. Can the two Host fields be different in the same request?
  3. Which one should I use for what situation?

Answers with a real HTTP request example would be the best. Thanks in advance.

like image 405
cizixs Avatar asked Mar 21 '17 08:03

cizixs


People also ask

How do I find my Golang host URL?

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.

What is host from URL?

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.

What is HTTP request context Golang?

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.


1 Answers

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.

like image 165
Bayta Darell Avatar answered Oct 10 '22 08:10

Bayta Darell