-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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/httputil: ReverseProxy does not set host header correctly #28168
Comments
Change https://golang.org/cl/141718 mentions this issue: |
It's preferring the req.Host first per the docs on net/http.Request.Host: // 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 I worry it might not be safe to change this without breaking other people. (There's the usual forward-proxy vs reverse-proxy distinction that people often bring up, too, which is kinda related here.) But if we have different behavior already whether we use HTTP/1 vs HTTP/2 to the backend, then I could see changing it. |
Hm, would it be safe to set (or unset) Request.Host in the default director? To note.... The workaround I tried for godoc actually didn't work in production (but worked locally). It 502s and logs this:
|
Well a PROTOCOL_ERROR is very interesting too. If we have a nice way to capture stderr on one of those, GODEBUG=http2debug=2 would be very interesting. (but send it to me privately in case there are secrets: likely) |
ReverseProxy doesn't re-set the Request's Host field, only Request.URL.Host. The HTTP/2 client prefers Request.Host over Request.URL.Host, so this results in the request being sent back to the host that originally accepted the request. This results in an infinite redirect (and consumption of many connections to itself). See Issue golang/go#28168 for details. Replace it with a simple proxy that drops all the headers (except Content-Type). I tried setting the proxy.Director, but it still didn't work. Could do with some more investigation. Fixes golang/go#28134. Change-Id: I5051ce72a379dcacfbe8484f58f8cf7d9385024d Reviewed-on: https://go-review.googlesource.com/c/141718 Run-TryBot: Chris Broadfoot <cbro@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Change https://golang.org/cl/153858 mentions this issue: |
…oxy for /share ReverseProxy doesn't re-set the Request's Host field, only Request.URL.Host. The HTTP/2 client prefers Request.Host over Request.URL.Host, so this results in the request being sent back to the host that originally accepted the request. This results in an infinite redirect (and consumption of many connections to itself). See Issue golang/go#28168 for details. Replace it with a simple proxy that drops all the headers (except Content-Type). I tried setting the proxy.Director, but it still didn't work. Could do with some more investigation. Fixes golang/go#28134. Change-Id: I5051ce72a379dcacfbe8484f58f8cf7d9385024d Reviewed-on: https://go-review.googlesource.com/c/141718 Run-TryBot: Chris Broadfoot <cbro@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> (cherry picked from commit 837e805) Reviewed-on: https://go-review.googlesource.com/c/153858 Run-TryBot: Andrew Bonventre <andybons@golang.org>
I also hit this! It applies to both http/1 and http/2 based on my experimentation. I refactored both I basically rewrite the I also asked this at https://stackoverflow.com/questions/55426924/go-httputil-reverseproxy-not-overriding-the-host-authority-header, my minimal repro below: package main
import (
"log"
"net/http"
"net/http/httputil"
)
func main() {
proxy := &httputil.ReverseProxy{
Transport: roundTripper(rt),
Director: func(req *http.Request) {
req.URL.Scheme = "https"
req.URL.Host = "httpbin.org"
req.Header.Set("Host", "httpbin.org") // <--- I set it here first
},
}
log.Fatal(http.ListenAndServe(":8080", proxy))
}
func rt(req *http.Request) (*http.Response, error) {
log.Printf("request received. url=%s", req.URL)
req.Header.Set("Host", "httpbin.org") // <--- I set it here as well
defer log.Printf("request complete. url=%s", req.URL)
return http.DefaultTransport.RoundTrip(req)
}
// roundTripper makes func signature a http.RoundTripper
type roundTripper func(*http.Request) (*http.Response, error)
func (f roundTripper) RoundTrip(req *http.Request) (*http.Response, error) { return f(req) } |
Goang's access to nginx through proxy can not correctly orientate the website, is it solved at present? If it's solved, you can tell me which version, or solve it by other means.thinks. |
Turns out I needed to set |
Lost 1h searching for my downstream server returning 403 when going through the At least, the implementation of |
The local proxy currently assumes that a verification will take place against either a) a local endpoint or b) an http endpoint. It did not support external hosts on https.o It also did not rewrite the Host header correctly (see golang/go#28168) This change: 1. Rewrites the header during proxying 2. Hard codes the local proxy to run only on http - there is no reason why it should run on https even if the endpoint under test _is_. 3. Opens the door for client configured transports during verification, to enable self-signed certificates to be easily used
Confirmed this had me digging for some time too. |
Welp, we just ran into this. |
Ran into the same issue in almost 2021 now. Fixed it by manually adding
in the director function.. but why do I have to do this!? |
Change https://go.dev/cl/407214 mentions this issue: |
The HTTP/2 client prefers Request.Host over Request.URL.Host:
go/src/net/http/h2_bundle.go
Lines 7947 to 7954 in a0d6420
ReverseProxy's default Director only sets Request.URL.Host, and not Request.Host, so the request would get proxied to the same host, rather than the proxy target. This resulted in an infinite loop on golang.org (see Issue #28134).
go/src/net/http/httputil/reverseproxy.go
Lines 105 to 121 in a0d6420
The text was updated successfully, but these errors were encountered: