Description
What version of Go are you using (go version
)?
$ go version go version go1.13.4 linux/amd64
Does this issue reproduce with the latest release?
Yes, code path did not change
What operating system and processor architecture are you using (go env
)?
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/moon/.cache/go-build"
GOENV="/home/moon/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/moon/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/lib/go-1.13"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go-1.13/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build174047944=/tmp/go-build -gno-record-gcc-switches"
go env
Output
$ go env
What did you do?
While writing to proxy using either http.ProxyURL(
or http.ProxyFromEnvironment
. If the request.URL.Scheme
is http
, the request.RequestURI
's host will be from ``request.Host and not from request.URL.Host
.
What did you expect to see?
Using the following request:
POST /gen_204?atyp=csi&ei=xxx&s=jsa&jsi=s,t.0,et.focus,n.iDPoPb,cn.1&zx=xxxHTTP/1.1
Host: blah
I expect to see:
POST http://google.com/gen_204?atyp=csi&ei=_UMjXuLAHvLL5gKQ872YBw&s=jsa&jsi=s,t.0,et.focus,n.iDPoPb,cn.1&zx=1579369468594 HTTP/1.1
Host: blah
when I force request.URL.Host to "google.com" and request.URL.Scheme to "http"
What did you see instead?
Instead this is what's going on:
POST http://blah/gen_204?atyp=csi&ei=_UMjXuLAHvLL5gKQ872YBw&s=jsa&jsi=s,t.0,et.focus,n.iDPoPb,cn.1&zx=1579369468594 HTTP/1.1
Host: blah
Comments
The offending path is here: https://github.com/golang/go/blob/master/src/net/http/request.go#L560 where as you can see, the r.Host
is used first.
I think it would make more sense to have the same behavior as the request in the doc: https://golang.org/pkg/net/http/#Request
// 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
Which is what the proxy is going to do in direct mode. Use the URI first, then the header if not present.