Closed
Description
by vitaly.dvd:
What does 'go version' print? go version go1.2 linux/amd64 What steps reproduce the problem? 1. Write simple program on a proxyHost that should forward requests to a targetHost censored.go: ( http://play.golang.org/p/YXT3zso8Ff ) package main import ( "log" "net/http" "net/http/httputil" "net/url" ) func main() { targetUrl, _ := url.Parse("http://navalny.livejournal.com";) log.Fatal(http.ListenAndServe(":49200", httputil.NewSingleHostReverseProxy(targetUrl))) } 2. On a proxyHost (AWS instance in my case) run go program: go run censored.go run tcpDump: sudo tcpdump -vvvs 1024 -l -A host navalny.livejournal.com What happened? The HOST header points to my proxy host instead of a target one curl -v http://54.228.241.100:49200 > /dev/null GET / HTTP/1.1 Host: 54.228.241.100:49200 User-Agent: curl/7.30.0 Accept: */* X-Forwarded-For: 109.188.90.98 Accept-Encoding: gzip As a result life journal returns HTTP redirect with Location: http://navalny.livejournal.com (the same target host) What should have happened instead? The host header should be set to targetHost, navalny.livejournal.com in this case. curl -v http://54.228.241.100:49200 > /dev/null GET / HTTP/1.1 Host: navalny.livejournal.com User-Agent: curl/7.30.0 Accept: */* Please provide any additional information below. fix is simple: the req.Host should explicitly rewrite req.Host in NewSingleHostReverseProxy // NewSingleHostReverseProxy returns a new ReverseProxy that rewrites // URLs to the scheme, host, and base path provided in target. If the // target's path is "/base" and the incoming request was for "/dir", // the target request will be for /base/dir. func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy { targetQuery := target.RawQuery director := func(req *http.Request) { req.URL.Scheme = target.Scheme req.URL.Host = target.Host + req.Host = target.Host req.URL.Path = singleJoiningSlash(target.Path, req.URL.Path) if targetQuery == "" || req.URL.RawQuery == "" { req.URL.RawQuery = targetQuery + req.URL.RawQuery } else { req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery } } return &ReverseProxy{Director: director} }