Skip to content
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 should copy *req.URL #20068

Closed
aronatkins opened this issue Apr 21, 2017 · 4 comments
Closed

net/http/httputil: ReverseProxy should copy *req.URL #20068

aronatkins opened this issue Apr 21, 2017 · 4 comments

Comments

@aronatkins
Copy link

The ReverseProxy.ServeHTTP performs a shallow copy of the incoming request. This includes just copying the pointer of req.URL to outreq.URL. The director is likely to mutate that request URL, which can lead to mismatched pre/post logging.

Workaround: Copy the url.URL within a custom director.

What version of Go are you using (go version)?

go version go1.8.1 darwin/amd64

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/aron/go"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/ts/s940qvdj5vj1czr9qh07fvtw0000gn/T/go-build348823784=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"

What did you do?

package main

import (
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"
)

func main() {
	target, err := url.Parse("http://google.com/")
	if err != nil {
		log.Fatalf("could not parse URL: %s", err)
	}
	pxy := httputil.NewSingleHostReverseProxy(target)
	server := http.Server{
		Addr: ":9999",
		Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			log.Printf("proxy starting: %s", r.URL)
			pxy.ServeHTTP(w, r)
			log.Printf("proxy complete: %s", r.URL)
		}),
	}
	err = server.ListenAndServe()
	if err != nil {
		log.Fatalf("could not serve: %s", err)
	}
}
$ curl http://localhost:9999/ > /dev/null

What did you expect to see?

2017/04/21 11:14:54 proxy starting: /
2017/04/21 11:14:54 proxy complete: /

What did you see instead?

2017/04/21 11:14:54 proxy starting: /
2017/04/21 11:14:54 proxy complete: http://google.com/
@odeke-em
Copy link
Member

/cc @bradfitz, I think the day of reckoning has arrived, for us to modify Request.WithContext https://golang.org/pkg/net/http/#Request.WithContext to perform some deep copies e.g for URL as requested by the issue. What do you think?

@gopherbot
Copy link

CL https://golang.org/cl/41308 mentions this issue.

@aronatkins
Copy link
Author

This issue is also similar to #18327, which is trying to establish what is possible/recommended in the director.

@CSEMike
Copy link

CSEMike commented May 19, 2017

Also related: #19706

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants