Skip to content

Commit

Permalink
Using upstream hostname for request (fabiolb#294)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mitch Davis committed May 27, 2017
1 parent b5f9cd0 commit a4f6717
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 0 deletions.
57 changes: 57 additions & 0 deletions proxy/http_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,63 @@ func TestProxyStripsPath(t *testing.T) {
}
}

// TestProxyUseUpstreamHostname
func TestProxyUseUpstreamHostname(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, r.Host)
}))

proxy := httptest.NewServer(&HTTPProxy{
Transport: &http.Transport{
Dial: func(network, addr string) (net.Conn, error) {
addr = server.URL[len("http://"):]
return net.Dial(network, addr)
},
},
Lookup: func(r *http.Request) *route.Target {
tbl, _ := route.NewTable(`route add mock / http://a.com/ opts "useupstreamhostname=true"`)
return tbl.Lookup(r, "", route.Picker["rr"], route.Matcher["prefix"])
},
})
defer proxy.Close()

resp, body := mustGet(proxy.URL + "/")
if got, want := resp.StatusCode, http.StatusOK; got != want {
t.Fatalf("got status %d want %d", got, want)
}
if got, want := string(body), "a.com"; got != want {
t.Fatalf("got body %q want %q", got, want)
}
}

func TestProxyDoNotUseUpstreamHostname(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, r.Host)
}))

proxy := httptest.NewServer(&HTTPProxy{
Transport: &http.Transport{
Dial: func(network, addr string) (net.Conn, error) {
addr = server.URL[len("http://"):]
return net.Dial(network, addr)
},
},
Lookup: func(r *http.Request) *route.Target {
tbl, _ := route.NewTable(`route add mock / http://a.com/ opts "useupstreamhostname=false"`)
return tbl.Lookup(r, "", route.Picker["rr"], route.Matcher["prefix"])
},
})
defer proxy.Close()

resp, body := mustGet(proxy.URL + "/")
if got, want := resp.StatusCode, http.StatusOK; got != want {
t.Fatalf("got status %d want %d", got, want)
}
if got, want := string(body), proxy.URL[len("http://"):]; got != want {
t.Fatalf("got body %q want %q", got, want)
}
}

func TestProxyLogOutput(t *testing.T) {
// build a format string from all log fields and one header field
fields := []string{"header.X-Foo:$header.X-Foo"}
Expand Down
4 changes: 4 additions & 0 deletions proxy/http_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ func (p *HTTPProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
targetURL.RawQuery = t.URL.RawQuery + "&" + r.URL.RawQuery
}

if t.UseUpstreamHostname {
r.Host = targetURL.Host
}

// TODO(fs): The HasPrefix check seems redundant since the lookup function should
// TODO(fs): have found the target based on the prefix but there may be other
// TODO(fs): matchers which may have different rules. I'll keep this for
Expand Down
1 change: 1 addition & 0 deletions route/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ func (r *Route) addTarget(service string, targetURL *url.URL, fixedWeight float6
if r.Opts != nil {
t.StripPath = r.Opts["strip"]
t.TLSSkipVerify = r.Opts["tlsskipverify"] == "true"
t.UseUpstreamHostname = r.Opts["useupstreamhostname"] == "true"
}

r.Targets = append(r.Targets, t)
Expand Down
5 changes: 5 additions & 0 deletions route/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ type Target struct {
// TLS connections.
TLSSkipVerify bool

// UseUpstreamHostname causes the origin host header to be
// replaced by the upstream host header as its moving
// through the proxy.
UseUpstreamHostname bool

// URL is the endpoint the service instance listens on
URL *url.URL

Expand Down

0 comments on commit a4f6717

Please sign in to comment.