-
Notifications
You must be signed in to change notification settings - Fork 18k
net/http/httputil: ReverseProxy.ServeHTTP should empty the outgoing request's Host once the outgoing request is cloned #33861
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
Comments
Change https://golang.org/cl/191937 mentions this issue: |
I replied on the CL: I'm afraid this would break more people than it'd fix. I'm not sure we can make a change like this at this point for compatibility reasons. You can also do this in your Director func. Perhaps we can have some new Director/ReverseProxy constructors instead. Everybody keeps trying to shove their preferred behavior into NewSingleHostReverseProxy but that probably can't accommodate everybody. |
My current workaround is to empty it in Director func. But I think the current way is a wrong implementation of the reverse proxy. Don't we need to correct it? If I understand the reverse proxy technique correctly, the incoming request's Host header should be placed in the X-Forwarded-Host header or the Forwarded header of the outgoing request. And the outgoing request's Host header should be the hostname of its destination. For now, in the example above, GCS will receive a request from me with a However, I can't estimate how many people's code will be broken by golang.org/cl/191937. I just think this is a mistake that needs to be corrected. |
Also found #14413. |
I remember coming across this issue probably more than 6 years ago, and I fixing it with my own |
I haven't thought of any scenarios that might cause the code to be broken by that change. As @DisposaBoy said, if most people don't know what the outgoing request's Host field should be, what do they do by relying on it? In fact, this reminds me of the same errors I encountered in my previous programs, but I didn't investigate the reasons at the time. My usual solution is to use alternatives like Nginx or Envoy, both of which work as expected. https://golang.org/doc/go1compat#expectations
So what we should do now is to do nothing, is it? |
Duplicate of #28168. |
Just lost a couple of hours on this "bug" while trying to use it as a forwarding proxy. |
So I ran the following program today:
Its purpose is to reverse proxy an endpoint of Google Cloud Storage. I think it's supposed to be the simplest way for doing this in Go. But, it failed.
GCP's response
And I found the reason why the above program failed. Currently,
httputil.ReverseProxy.ServeHTTP
clones a request before it is forwarded. This causes the Host field of the outgoing request to be equivalent to the client request instead of the one in the target URL.According to the documentation of
http.Request.Host
:the Host header in the outgoing request we actually send will be the same as the incoming request sent from the client.
Usually, this doesn't seem to have any serious impact. In fact, I have never seen one before I wrote the above program. For the above example, the Host header is "127.0.0.1:8080" instead of "storage.googleapis.com".
The text was updated successfully, but these errors were encountered: