diff --git a/pkg/apiserver/proxy.go b/pkg/apiserver/proxy.go index a64eabd0faf..360ef417152 100644 --- a/pkg/apiserver/proxy.go +++ b/pkg/apiserver/proxy.go @@ -169,6 +169,11 @@ type proxyTransport struct { } func (t *proxyTransport) RoundTrip(req *http.Request) (*http.Response, error) { + // Add reverse proxy headers. + req.Header.Set("X-Forwarded-Uri", t.proxyPathPrepend+req.URL.Path) + req.Header.Set("X-Forwarded-Host", t.proxyHost) + req.Header.Set("X-Forwarded-Proto", t.proxyScheme) + resp, err := http.DefaultTransport.RoundTrip(req) if err != nil { diff --git a/pkg/apiserver/proxy_test.go b/pkg/apiserver/proxy_test.go index 7765ab2c83c..99f3ce66f8d 100644 --- a/pkg/apiserver/proxy_test.go +++ b/pkg/apiserver/proxy_test.go @@ -56,69 +56,77 @@ func TestProxyTransport(t *testing.T) { testTransport := &proxyTransport{ proxyScheme: "http", proxyHost: "foo.com", - proxyPathPrepend: "/proxy/minion/minion1:10250/", + proxyPathPrepend: "/proxy/minion/minion1:10250", } testTransport2 := &proxyTransport{ proxyScheme: "https", proxyHost: "foo.com", - proxyPathPrepend: "/proxy/minion/minion1:8080/", + proxyPathPrepend: "/proxy/minion/minion1:8080", } table := map[string]struct { - input string - sourceURL string - transport *proxyTransport - output string - contentType string + input string + sourceURL string + transport *proxyTransport + output string + contentType string + forwardedURI string }{ "normal": { - input: `
kubelet.loggoogle.log`, - sourceURL: "http://myminion.com/logs/log.log", - transport: testTransport, - output: `
kubelet.loggoogle.log`, - contentType: "text/html", + input: `
kubelet.loggoogle.log`, + sourceURL: "http://myminion.com/logs/log.log", + transport: testTransport, + output: `
kubelet.loggoogle.log`, + contentType: "text/html", + forwardedURI: "/proxy/minion/minion1:10250/logs/log.log", }, "content-type charset": { - input: `
kubelet.loggoogle.log`, - sourceURL: "http://myminion.com/logs/log.log", - transport: testTransport, - output: `
kubelet.loggoogle.log`, - contentType: "text/html; charset=utf-8", + input: `
kubelet.loggoogle.log`, + sourceURL: "http://myminion.com/logs/log.log", + transport: testTransport, + output: `
kubelet.loggoogle.log`, + contentType: "text/html; charset=utf-8", + forwardedURI: "/proxy/minion/minion1:10250/logs/log.log", }, "content-type passthrough": { - input: `
kubelet.loggoogle.log`, - sourceURL: "http://myminion.com/logs/log.log", - transport: testTransport, - output: `
kubelet.loggoogle.log`, - contentType: "text/plain", + input: `
kubelet.loggoogle.log`, + sourceURL: "http://myminion.com/logs/log.log", + transport: testTransport, + output: `
kubelet.loggoogle.log`, + contentType: "text/plain", + forwardedURI: "/proxy/minion/minion1:10250/logs/log.log", }, "subdir": { - input: `kubelet.loggoogle.log`, - sourceURL: "http://myminion.com/whatever/apt/somelog.log", - transport: testTransport2, - output: `kubelet.loggoogle.log`, - contentType: "text/html", + input: `kubelet.loggoogle.log`, + sourceURL: "http://myminion.com/whatever/apt/somelog.log", + transport: testTransport2, + output: `kubelet.loggoogle.log`, + contentType: "text/html", + forwardedURI: "/proxy/minion/minion1:8080/whatever/apt/somelog.log", }, "image": { - input: `
`, - sourceURL: "http://myminion.com/", - transport: testTransport, - output: `
`, - contentType: "text/html", + input: `
`, + sourceURL: "http://myminion.com/", + transport: testTransport, + output: `
`, + contentType: "text/html", + forwardedURI: "/proxy/minion/minion1:10250/", }, "abs": { - input: ``, - sourceURL: "http://myminion.com/any/path/", - transport: testTransport, - output: ``, - contentType: "text/html", + input: ``, + sourceURL: "http://myminion.com/any/path/", + transport: testTransport, + output: ``, + contentType: "text/html", + forwardedURI: "/proxy/minion/minion1:10250/any/path/", }, "abs but same host": { - input: ``, - sourceURL: "http://myminion.com/any/path/", - transport: testTransport, - output: ``, - contentType: "text/html", + input: ``, + sourceURL: "http://myminion.com/any/path/", + transport: testTransport, + output: ``, + contentType: "text/html", + forwardedURI: "/proxy/minion/minion1:10250/any/path/", }, } @@ -127,7 +135,19 @@ func TestProxyTransport(t *testing.T) { item.input = fmtHTML(item.input) item.output = fmtHTML(item.output) - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Check request headers. + if got, want := r.Header.Get("X-Forwarded-Uri"), item.forwardedURI; got != want { + t.Errorf("%v: X-Forwarded-Uri = %q, want %q", name, got, want) + } + if got, want := r.Header.Get("X-Forwarded-Host"), item.transport.proxyHost; got != want { + t.Errorf("%v: X-Forwarded-Host = %q, want %q", name, got, want) + } + if got, want := r.Header.Get("X-Forwarded-Proto"), item.transport.proxyScheme; got != want { + t.Errorf("%v: X-Forwarded-Proto = %q, want %q", name, got, want) + } + + // Send response. w.Header().Set("Content-Type", item.contentType) fmt.Fprint(w, item.input) }))