| 282 | } |
| 283 | |
| 284 | func TestProxyHost(t *testing.T) { |
| 285 | server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| 286 | fmt.Fprint(w, r.Host) |
| 287 | })) |
| 288 | |
| 289 | // create a static route table so that we can see the effect |
| 290 | // of round robin distribution. The other tests generate the |
| 291 | // route table on the fly since order does not matter to them. |
| 292 | routes := "route add mock /hostdst http://a.com/ opts \"host=dst\"\n" |
| 293 | routes += "route add mock /hostcustom http://a.com/ opts \"host=foo.com\"\n" |
| 294 | routes += "route add mock /hostcustom http://b.com/ opts \"host=bar.com\"\n" |
| 295 | routes += "route add mock / http://a.com/" |
| 296 | tbl, _ := route.NewTable(bytes.NewBufferString(routes)) |
| 297 | |
| 298 | proxy := httptest.NewServer(&HTTPProxy{ |
| 299 | ProtectHeaders: testProtectHeaders, |
| 300 | Transport: &http.Transport{ |
| 301 | Dial: func(network, _ string) (net.Conn, error) { |
| 302 | addr := server.URL[len("http://"):] |
| 303 | return net.Dial(network, addr) |
| 304 | }, |
| 305 | }, |
| 306 | Lookup: func(r *http.Request) *route.Target { |
| 307 | return tbl.Lookup(r, route.Picker["rr"], route.Matcher["prefix"], globCache, globEnabled) |
| 308 | }, |
| 309 | }) |
| 310 | defer proxy.Close() |
| 311 | |
| 312 | check := func(t *testing.T, uri, host string) { |
| 313 | resp, body := mustGet(proxy.URL + uri) |
| 314 | if got, want := resp.StatusCode, http.StatusOK; got != want { |
| 315 | t.Fatalf("got status %d want %d", got, want) |
| 316 | } |
| 317 | if got, want := string(body), host; got != want { |
| 318 | t.Fatalf("got body %q want %q", got, want) |
| 319 | } |
| 320 | } |
| 321 | |
| 322 | proxyHost := proxy.URL[len("http://"):] |
| 323 | |
| 324 | // test that for 'host=dst' the Host header is set to the hostname of the |
| 325 | // target, in this case 'a.com' |
| 326 | t.Run("host eq dst", func(t *testing.T) { check(t, "/hostdst", "a.com") }) |
| 327 | |
| 328 | // test that without a 'host' option no Host header is set |
| 329 | t.Run("no host", func(t *testing.T) { check(t, "/", proxyHost) }) |
| 330 | |
| 331 | // 1. Test that a host header is set when the 'host' option is used. |
| 332 | // |
| 333 | // 2. Test that the host header is set per target, i.e. that different |
| 334 | // targets can have different 'host' options. |
| 335 | // |
| 336 | // The proxy is configured to use "rr" (round-robin) distribution |
| 337 | // for the requests. Therefore, requests to '/hostcustom' will be |
| 338 | // sent to the two different targets in alternating order. |
| 339 | t.Run("host is custom", func(t *testing.T) { |
| 340 | check(t, "/hostcustom", "foo.com") |
| 341 | check(t, "/hostcustom", "bar.com") |