Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

net/http.Request.URL.Host returns empty string

Tags:

http

url

request

go

I was trying to redirect my client to https url. And I tried this:

func index(w http.ResponseWriter, r *http.Request) {
        if r.URL.Scheme != "https" {
                http.Redirect(w, r, "https://"+r.URL.Host+r.URL.Path, 301)
                return
        }
//....
}

But it gave me this response:

$ curl -i http://localhost
HTTP/1.1 301 Moved Permanently
Content-Type: text/html; charset=utf-8
Location: https:///
Date: Sat, 24 Nov 2018 20:02:33 GMT
Content-Length: 44

<a href="https:///">Moved Permanently</a>.

The mysterious thing is Location: https:/// this line. And I read the go doc again and found:

// URL specifies either the URI being requested (for server
// requests) or the URL to access (for client requests).
//
// For server requests the URL is parsed from the URI
// supplied on the Request-Line as stored in RequestURI.  **For
// most requests, fields other than Path and RawQuery will be
// empty. (See RFC 7230, Section 5.3)**
//
// For client requests, the URL's Host specifies the server to
// connect to, while the Request's Host field optionally
// specifies the Host header value to send in the HTTP
// request.
URL *url.URL

Then I've understood that why it's returning and empty string for r.URL.Host.

I have also tried r.Header.Get("Host") and then r.Header.Get("Origin"). It also gave me an empty string.

Any other way to get the host name?

like image 925
Hasibul Hasn Avatar asked Sep 16 '25 02:09

Hasibul Hasn


2 Answers

From go doc http.request:

type Request struct {
        ...
        // For incoming requests, the Host header is promoted to the
        // Request.Host field and removed from the Header map.
       ...
        Header Header
       ...
        // 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.
        ...
        Host string

Thus, use r.Host not r.Header.Get("Host")

like image 125
Steffen Ullrich Avatar answered Sep 18 '25 16:09

Steffen Ullrich


Try using r.Host?

The docs say:

// For server requests Host specifies the host on which the URL
// is sought. Per RFC 7230, section 5.4, this is either the value
// of the "Host" header or the host name given in the URL itself.

So Maybe try that?

func index(w http.ResponseWriter, r *http.Request) {
    if r.URL.Scheme != "https" {
            http.Redirect(w, r, "https://"+r.Host+r.URL.Path, 301)
            return
    }
//....
}
like image 27
jrwren Avatar answered Sep 18 '25 16:09

jrwren