Skip to content

net/http: bad host for WriteProxy for HTTP schemes #36831

Closed
@tehmoon

Description

@tehmoon

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions