Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/http: Setting custom "Host" request header doesn't have effect #7682

Closed
gopherbot opened this issue Apr 1, 2014 · 12 comments
Closed

net/http: Setting custom "Host" request header doesn't have effect #7682

gopherbot opened this issue Apr 1, 2014 · 12 comments
Milestone

Comments

@gopherbot
Copy link

by mislav.marohnic:

go version: go1.2

The `Header.Add` line in the following code doesn't have any effect:

    client := &http.Client {}
    req, _ := http.NewRequest("GET", "http://127.0.0.1:9292";, nil)
    req.Header.Add("Host", "example.com")
    client.Do(req)

I expected that the server on 127.0.0.1:9292 receives a request with the header
"Host: example.com", but the request was made with "Host:
127.0.0.1:9292" instead.

This does the trick, however:

    req.Host = "example.com"

I was wondering why doesn't the first approach work?

Relevant code:
https://code.google.com/p/go/source/browse/src/pkg/net/http/request.go?name=go1.2#301
@ianlancetaylor
Copy link
Contributor

Comment 1:

Possible a documentation issue.

Labels changed: added repo-main, release-go1.3maybe.

@gopherbot
Copy link
Author

Comment 2 by mislav.marohnic:

Well, I expected `Header.Add` to modify the "Host" header of the request. From the
source code it seems that Go ignores this header setting by design, and uses `req.Host`.
This is surprising behavior and would continue to be surprising even if it was better
documented.
To be clear: there are two separate hosts we are specifying. The first is the actual
host that the connection is being made to: "127.0.0.1:9292". (This is specified with the
full URL of the request.) The second is what we want this server to receive as the
`Host` header value. Usually these values are the same, but there are use-cases when you
want to specify a custom `Host` header.
It's also surprising that changing `req.Host` actually does the trick. I would expect
that to change the actual host we're connecting to, not just the header value. So the
current behavior is backwards from my perspective.

@owenthereal
Copy link

Comment 3:

This is the Go example to reproduce this: http://play.golang.org/p/5I0i3S_szO

@gopherbot
Copy link
Author

Comment 4 by mislav.marohnic:

Hmm, running your Go example to reproduce this apparently results in no `Host` header
being set whatsoever. However, if I try my code against a real server, I see the header
being set. Maybe a limitation of httptest?

@owenthereal
Copy link

Comment 5:

I'm using a simple http debug proxy like this and am still seeing no `Host` header:
https://github.com/jingweno/hdp/blob/master/main.go

@owenthereal
Copy link

Comment 6:

Looks like `Host` doesn't show us in `Request.Header` but is parsed into `Request.Host`.
A modification of the above Go example makes it work:
http://play.golang.org/p/DEFLb7_WRJ.
`Header.Add` still doesn't correctly set the header: http://play.golang.org/p/Kqh7sgX-z1

@bradfitz
Copy link
Contributor

bradfitz commented Apr 2, 2014

Comment 7:

This is documented at http://tip.golang.org/pkg/net/http/#Request.Write
I'll add a note to reference that on the Request struct.

Owner changed to @bradfitz.

Status changed to Accepted.

@gopherbot
Copy link
Author

Comment 8 by mislav.marohnic:

I was aware that this behavior is kind of documented (see "Relevant code" link in my
original post).
The reason I opened this issue, if it isn't clear by now, is twofold:
1. Why isn't `Header.Add` allowed to modify the "Host" header? It's a regular HTTP
header like any other, so I've epxected it to work. Why doesn't it at least throw a
runtime exception?
2. Setting `req.Host = "example.com"` is ambiguous. It's not clear whether this changes
the actual hostname the connection is opened to, or just the "Host" header.
Experimentation shows it's the latter, but that wasn't clear to me prior to
experimentation.
I'm proposing the following fixes:
1. Allow `Header.Add("Host"...)` to change the "Host" header.
2. Make it clear in Request.Host documentation that setting this value only changes the
"Host" header but won't change the actual hostname/IP the connection will be opened to.

@bradfitz
Copy link
Contributor

bradfitz commented Apr 3, 2014

Comment 9:

Sent https://golang.org/cl/83800043
I don't think we can safely change the behavior at this point.

Status changed to Started.

@gopherbot
Copy link
Author

Comment 10 by mislav.marohnic:

That's a nice documentation update. Thank you.

@owenthereal
Copy link

Comment 11:

Thanks for updating the doc! Hopefully in the near future I would be able to say
`Header.Add("Host", ..)` with the same effect as `req.Host = ...`.

@bradfitz
Copy link
Contributor

bradfitz commented Apr 3, 2014

Comment 12:

This issue was closed by revision 9dbb185.

Status changed to Fixed.

This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants