func TestProcessesRequestWithShuntBackend(t *testing.T) { u, _ := url.ParseRequestURI("https://www.example.org/hello") r := &http.Request{ URL: u, Method: "GET", Header: http.Header{"X-Test-Header": []string{"test value"}}} w := httptest.NewRecorder() fr := make(filters.Registry) fr.Register(builtin.NewResponseHeader()) doc := `hello: Path("/hello") -> responseHeader("X-Test-Response-Header", "response header value") -> <shunt>` dc, err := testdataclient.NewDoc(doc) if err != nil { t.Error(err) } p := New(routing.New(routing.Options{ fr, routing.MatchingOptionsNone, sourcePollTimeout, []routing.DataClient{dc}, 0}), OptionsNone) delay() p.ServeHTTP(w, r) if h, ok := w.Header()["X-Test-Response-Header"]; !ok || h[0] != "response header value" { t.Error("wrong response header") } }
func Example() { // create registry registry := builtin.MakeRegistry() // create and register the filter specification spec := &customSpec{name: "customFilter"} registry.Register(spec) // create simple data client, with route entries referencing 'customFilter', // and clipping part of the request path: dataClient, err := testdataclient.NewDoc(` ui: Path("/ui/*page") -> customFilter("ui request") -> modPath("^/[^/]*", "") -> "https://ui.example.org"; api: Path("/api/*resource") -> customFilter("api request") -> modPath("^/[^/]*", "") -> "https://api.example.org"`) if err != nil { log.Fatal(err) } // create http.Handler: proxy.New( routing.New(routing.Options{ FilterRegistry: registry, DataClients: []routing.DataClient{dataClient}}), proxy.OptionsNone) }
func TestReceivesDelete(t *testing.T) { dc := testdataclient.New([]*eskip.Route{ {Id: "route1", Path: "/some-path", Backend: "https://www.example.org"}, {Id: "route2", Path: "/some-other", Backend: "https://other.example.org"}}) rt := routing.New(routing.Options{ UpdateBuffer: 0, DataClients: []routing.DataClient{dc}, PollTimeout: pollTimeout}) req, err := http.NewRequest("GET", "https://www.example.com/some-path", nil) if err != nil { t.Error(err) } <-waitRoute(rt, req) <-waitUpdate(dc, nil, []string{"route1"}, false) time.Sleep(6 * pollTimeout) req, err = http.NewRequest("GET", "https://www.example.com/some-path", nil) if err != nil { t.Error(err) } if waitDone(0, waitRoute(rt, req)) { t.Error("should not have found route") } }
func TestStreaming(t *testing.T) { const expectedParts = 3 payload := []byte("some data to stream") s := startTestServer(payload, expectedParts, voidCheck) defer s.Close() doc := fmt.Sprintf(`hello: Path("/hello") -> "%s"`, s.URL) dc, err := testdataclient.NewDoc(doc) if err != nil { t.Error(err) } p := New(routing.New(routing.Options{ nil, routing.MatchingOptionsNone, sourcePollTimeout, []routing.DataClient{dc}, 0}), OptionsNone) delay() u, _ := url.ParseRequestURI("https://www.example.org/hello") r := &http.Request{ URL: u, Method: "GET"} w := httptest.NewRecorder() parts := 0 total := 0 done := make(chan int) go p.ServeHTTP(w, r) go func() { for { buf := w.Body.Bytes() if len(buf) == 0 { time.Sleep(streamingDelay) continue } parts++ total += len(buf) if total >= len(payload) { close(done) return } } }() select { case <-done: if parts <= expectedParts { t.Error("streaming failed", parts) } case <-time.After(150 * time.Millisecond): t.Error("streaming timeout") } }
func TestMergesMultipleSources(t *testing.T) { if testing.Short() { t.Skip() } dc1 := testdataclient.New([]*eskip.Route{{Id: "route1", Path: "/some-path", Backend: "https://www.example.org"}}) dc2 := testdataclient.New([]*eskip.Route{{Id: "route2", Path: "/some-other", Backend: "https://other.example.org"}}) dc3 := testdataclient.New([]*eskip.Route{{Id: "route3", Path: "/another", Backend: "https://another.example.org"}}) rt := routing.New(routing.Options{ UpdateBuffer: 0, DataClients: []routing.DataClient{dc1, dc2, dc3}, PollTimeout: pollTimeout}) req1, err := http.NewRequest("GET", "https://www.example.com/some-path", nil) if err != nil { t.Error(err) } req2, err := http.NewRequest("GET", "https://www.example.com/some-other", nil) if err != nil { t.Error(err) } req3, err := http.NewRequest("GET", "https://www.example.com/another", nil) if err != nil { t.Error(err) } if !waitDone(6*pollTimeout, waitRoute(rt, req1), waitRoute(rt, req2), waitRoute(rt, req3)) { t.Error("test timeout") } }
func Example() { // create a data client: dataClient := testdataclient.New([]*eskip.Route{ {Path: "/some/path", Backend: "https://www.example.org"}}) // (only in tests) tl := loggingtest.New() defer tl.Close() // create a router: r := routing.New(routing.Options{ DataClients: []routing.DataClient{dataClient}, Log: tl}) defer r.Close() // wait for the route data being propagated: tl.WaitFor("route settigns applied", time.Second) // test the router: route, _ := r.Route(&http.Request{URL: &url.URL{Path: "/some/path"}}) if route == nil { log.Fatal("failed to route request") } fmt.Println(route.Backend) // Output: // https://www.example.org }
func TestMergesUpdatesFromMultipleSources(t *testing.T) { dc1 := testdataclient.New([]*eskip.Route{{Id: "route1", Path: "/some-path", Backend: "https://www.example.org"}}) dc2 := testdataclient.New([]*eskip.Route{{Id: "route2", Path: "/some-other", Backend: "https://other.example.org"}}) dc3 := testdataclient.New([]*eskip.Route{{Id: "route3", Path: "/another", Backend: "https://another.example.org"}}) rt := routing.New(routing.Options{ UpdateBuffer: 0, DataClients: []routing.DataClient{dc1, dc2, dc3}, PollTimeout: pollTimeout}) req1, err := http.NewRequest("GET", "https://www.example.com/some-path", nil) if err != nil { t.Error(err) } req2, err := http.NewRequest("GET", "https://www.example.com/some-other", nil) if err != nil { t.Error(err) } req3, err := http.NewRequest("GET", "https://www.example.com/another", nil) if err != nil { t.Error(err) } waitRoute(rt, req1) waitRoute(rt, req2) waitRoute(rt, req3) <-waitUpdate(dc1, []*eskip.Route{{Id: "route1", Path: "/some-changed-path", Backend: "https://www.example.org"}}, nil, false) <-waitUpdate(dc2, []*eskip.Route{{Id: "route2", Path: "/some-other-changed", Backend: "https://www.example.org"}}, nil, false) <-waitUpdate(dc3, nil, []string{"route3"}, false) req1, err = http.NewRequest("GET", "https://www.example.com/some-changed-path", nil) if err != nil { t.Error(err) } req2, err = http.NewRequest("GET", "https://www.example.com/some-other-changed", nil) if err != nil { t.Error(err) } req3, err = http.NewRequest("GET", "https://www.example.com/another", nil) if err != nil { t.Error(err) } if !waitDone(6*pollTimeout, waitRoute(rt, req1), waitRoute(rt, req2)) { t.Error("test timeout") } time.Sleep(3 * pollTimeout) if waitDone(0, waitRoute(rt, req3)) { t.Error("should not have found route") } }
func TestProcessesPredicates(t *testing.T) { dc, err := testdataclient.NewDoc(` route1: CustomPredicate("custom1") -> "https://route1.example.org"; route2: CustomPredicate("custom2") -> "https://route2.example.org"; catchAll: * -> "https://route.example.org"`) if err != nil { t.Error(err) return } cps := []routing.PredicateSpec{&predicate{}, &predicate{}} rt := routing.New(routing.Options{ DataClients: []routing.DataClient{dc}, PollTimeout: pollTimeout, Predicates: cps}) req, err := http.NewRequest("GET", "https://www.example.com", nil) if err != nil { t.Error(err) return } req.Header.Set(predicateHeader, "custom1") select { case r := <-waitRoute(rt, req): if r.Backend != "https://route1.example.org" { t.Error("custom predicate matching failed, route1") return } case <-time.After(3 * pollTimeout): t.Error("test timeout") } req.Header.Set(predicateHeader, "custom2") select { case r := <-waitRoute(rt, req): if r.Backend != "https://route2.example.org" { t.Error("custom predicate matching failed, route2") return } case <-time.After(3 * pollTimeout): t.Error("test timeout") } req.Header.Del(predicateHeader) select { case r := <-waitRoute(rt, req): if r.Backend != "https://route.example.org" { t.Error("custom predicate matching failed, catch-all") return } case <-time.After(3 * pollTimeout): t.Error("test timeout") } }
func Example() { // create etcd data client: dataClient := etcd.New([]string{"https://etcd.example.org"}, "/skipper") // create http.Handler: proxy.New( routing.New(routing.Options{ FilterRegistry: builtin.MakeRegistry(), DataClients: []routing.DataClient{dataClient}}), proxy.OptionsNone) }
func TestRoute(t *testing.T) { payload1 := []byte("host one") s1 := startTestServer(payload1, 0, voidCheck) defer s1.Close() payload2 := []byte("host two") s2 := startTestServer(payload2, 0, voidCheck) defer s2.Close() doc := fmt.Sprintf(` route1: Path("/host-one/*any") -> "%s"; route2: Path("/host-two/*any") -> "%s" `, s1.URL, s2.URL) dc, err := testdataclient.NewDoc(doc) if err != nil { t.Error(err) } p := New(routing.New(routing.Options{ nil, routing.MatchingOptionsNone, sourcePollTimeout, []routing.DataClient{dc}, nil, 0}), OptionsNone) delay() var ( r *http.Request w *httptest.ResponseRecorder u *url.URL ) u, _ = url.ParseRequestURI("https://www.example.org/host-one/some/path") r = &http.Request{ URL: u, Method: "GET"} w = httptest.NewRecorder() p.ServeHTTP(w, r) if w.Code != http.StatusOK || !bytes.Equal(w.Body.Bytes(), payload1) { t.Error("wrong routing 1") } u, _ = url.ParseRequestURI("https://www.example.org/host-two/some/path") r = &http.Request{ URL: u, Method: "GET"} w = httptest.NewRecorder() p.ServeHTTP(w, r) if w.Code != http.StatusOK || !bytes.Equal(w.Body.Bytes(), payload2) { t.Error("wrong routing 2") } }
func newTestRoutingWithFiltersPredicates(fr filters.Registry, cps []routing.PredicateSpec, dc ...routing.DataClient) (*testRouting, error) { tl := loggingtest.New() rt := routing.New(routing.Options{ FilterRegistry: fr, Predicates: cps, DataClients: dc, PollTimeout: pollTimeout, Log: tl}) tr := &testRouting{tl, rt} return tr, tr.waitForNRouteSettings(len(dc)) }
// Run skipper. func Run(o Options) error { // create authentication for Innkeeper auth := createInnkeeperAuthentication(o) // create data client dataClients, err := createDataClients(o, auth) if err != nil { return err } if len(dataClients) == 0 { log.Println("warning: no route source specified") } // create a filter registry with the available filter specs registered, // and register the custom filters registry := builtin.MakeRegistry() for _, f := range o.CustomFilters { registry.Register(f) } // create routing // create the proxy instance var mo routing.MatchingOptions if o.IgnoreTrailingSlash { mo = routing.IgnoreTrailingSlash } // ensure a non-zero poll timeout if o.SourcePollTimeout <= 0 { o.SourcePollTimeout = defaultSourcePollTimeout } // check for dev mode, and set update buffer of the routes updateBuffer := defaultRoutingUpdateBuffer if o.DevMode { updateBuffer = 0 } // create a routing engine routing := routing.New(routing.Options{ registry, mo, o.SourcePollTimeout, dataClients, updateBuffer}) // create the proxy proxy := proxy.New(routing, o.ProxyOptions, o.PriorityRoutes...) // start the http server log.Printf("listening on %v\n", o.Address) return http.ListenAndServe(o.Address, proxy) }
func Example() { // create etcd data client: dataClient, err := etcd.New(etcd.Options{[]string{"https://etcd.example.org"}, "/skipper", 0}) if err != nil { log.Fatal(err) } // create http.Handler: proxy.New( routing.New(routing.Options{ FilterRegistry: builtin.MakeRegistry(), DataClients: []routing.DataClient{dataClient}}), proxy.OptionsNone) }
func DisabledExample() { // create a target backend server. It will return the value of the 'X-Echo' request header // as the response body: targetServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte(r.Header.Get("X-Echo"))) })) defer targetServer.Close() // create a filter registry, and register the custom filter: filterRegistry := builtin.MakeRegistry() filterRegistry.Register(&setEchoHeader{}) // create a data client with a predefined route, referencing the filter and a path condition // containing a wildcard called 'echo': routeDoc := fmt.Sprintf(`Path("/return/:echo") -> setEchoHeader() -> "%s"`, targetServer.URL) dataClient, err := testdataclient.NewDoc(routeDoc) if err != nil { log.Fatal(err) } // create routing object: rt := routing.New(routing.Options{ FilterRegistry: filterRegistry, DataClients: []routing.DataClient{dataClient}}) defer rt.Close() // create a proxy instance, and start an http server: proxy := proxy.New(rt, proxy.OptionsNone) defer proxy.Close() router := httptest.NewServer(proxy) defer router.Close() // make a request to the proxy: rsp, err := http.Get(fmt.Sprintf("%s/return/Hello,+world!", router.URL)) if err != nil { log.Fatal(err) } defer rsp.Body.Close() // print out the response: if _, err := io.Copy(os.Stdout, rsp.Body); err != nil { log.Fatal(err) } // Output: // Hello, world! }
func Example() { // open file with a routing table: dataClient, err := eskipfile.Open("/some/path/to/routing-table.eskip") if err != nil { // log.Fatal(err) return } // create http.Handler: proxy.New( routing.New(routing.Options{ DataClients: []routing.DataClient{dataClient}}), proxy.OptionsNone) }
func TestFlusherImplementation(t *testing.T) { h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello, ")) time.Sleep(15 * time.Millisecond) w.Write([]byte("world!")) }) ts := httptest.NewServer(h) defer ts.Close() doc := fmt.Sprintf(`* -> "%s"`, ts.URL) dc, err := testdataclient.NewDoc(doc) if err != nil { t.Error(err) } p := New(routing.New(routing.Options{ nil, routing.MatchingOptionsNone, sourcePollTimeout, []routing.DataClient{dc}, nil, 0}), OptionsNone) delay() a := fmt.Sprintf(":%d", 1<<16-rand.Intn(1<<15)) ps := &http.Server{Addr: a, Handler: p} go ps.ListenAndServe() // let the server start listening time.Sleep(15 * time.Millisecond) rsp, err := http.Get("http://127.0.0.1" + a) if err != nil { t.Error(err) return } defer rsp.Body.Close() b, err := ioutil.ReadAll(rsp.Body) if err != nil { t.Error(err) return } if string(b) != "Hello, world!" { t.Error("failed to receive response") } }
func TestAppliesFilters(t *testing.T) { payload := []byte("Hello World!") s := startTestServer(payload, 0, func(r *http.Request) { if h, ok := r.Header["X-Test-Request-Header"]; !ok || h[0] != "request header value" { t.Error("request header is missing") } }) defer s.Close() u, _ := url.ParseRequestURI("https://www.example.org/hello") r := &http.Request{ URL: u, Method: "GET", Header: http.Header{"X-Test-Header": []string{"test value"}}} w := httptest.NewRecorder() fr := make(filters.Registry) fr.Register(builtin.NewRequestHeader()) fr.Register(builtin.NewResponseHeader()) doc := fmt.Sprintf(`hello: Path("/hello") -> requestHeader("X-Test-Request-Header", "request header value") -> responseHeader("X-Test-Response-Header", "response header value") -> "%s"`, s.URL) dc, err := testdataclient.NewDoc(doc) if err != nil { t.Error(err) } p := New(routing.New(routing.Options{ fr, routing.MatchingOptionsNone, sourcePollTimeout, []routing.DataClient{dc}, nil, 0}), OptionsNone) delay() p.ServeHTTP(w, r) if h, ok := w.Header()["X-Test-Response-Header"]; !ok || h[0] != "response header value" { t.Error("missing response header") } }
func TestProcessesRequestWithPriorityRouteOverStandard(t *testing.T) { s0 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("X-Test-Header", "priority-value") })) s1 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("X-Test-Header", "normal-value") })) req, err := http.NewRequest( "GET", "https://example.org/hello/world", nil) if err != nil { t.Error(err) } u, err := url.Parse(s0.URL) if err != nil { t.Error(err) } prt := &priorityRoute{&routing.Route{Scheme: u.Scheme, Host: u.Host}, nil, func(r *http.Request) bool { return r == req }} doc := fmt.Sprintf(`hello: Path("/hello") -> "%s"`, s1.URL) dc, err := testdataclient.NewDoc(doc) if err != nil { t.Error(err) } p := New(routing.New(routing.Options{ nil, routing.MatchingOptionsNone, sourcePollTimeout, []routing.DataClient{dc}, nil, 0}), OptionsNone, prt) delay() w := httptest.NewRecorder() p.ServeHTTP(w, req) if w.Header().Get("X-Test-Header") != "priority-value" { t.Error("failed match priority route") } }
func TestReceivesInitial(t *testing.T) { dc := testdataclient.New([]*eskip.Route{{Id: "route1", Path: "/some-path", Backend: "https://www.example.org"}}) rt := routing.New(routing.Options{ UpdateBuffer: 0, DataClients: []routing.DataClient{dc}, PollTimeout: pollTimeout}) req, err := http.NewRequest("GET", "https://www.example.com/some-path", nil) if err != nil { t.Error(err) } if !waitDone(6*pollTimeout, waitRoute(rt, req)) { t.Error("test timeout") } }
func TestIgnoresInvalidBackend(t *testing.T) { dc := testdataclient.New([]*eskip.Route{{Id: "route1", Path: "/some-path", Backend: "invalid backend"}}) rt := routing.New(routing.Options{ UpdateBuffer: 0, DataClients: []routing.DataClient{dc}, PollTimeout: pollTimeout}) req, err := http.NewRequest("GET", "https://www.example.com/some-path", nil) if err != nil { t.Error(err) } if waitDone(6*pollTimeout, waitRoute(rt, req)) { t.Error("should not have found route") } }
func Example() { // create etcd data client: dataClient, err := etcd.New(etcd.Options{[]string{"https://etcd.example.org"}, "/skipper", 0, false}) if err != nil { log.Fatal(err) } // create routing object: rt := routing.New(routing.Options{ FilterRegistry: builtin.MakeRegistry(), DataClients: []routing.DataClient{dataClient}}) defer rt.Close() // create http.Handler: p := proxy.New(rt, proxy.OptionsNone) defer p.Close() }
func TestPostRoundtrip(t *testing.T) { s := startTestServer(nil, 0, func(r *http.Request) { if r.Method != "POST" { t.Error("wrong request method", r.Method) } if th, ok := r.Header["X-Test-Header"]; !ok || th[0] != "test value" { t.Error("wrong request header") } }) defer s.Close() u, _ := url.ParseRequestURI("https://www.example.org/hello") r := &http.Request{ URL: u, Method: "POST", Header: http.Header{"X-Test-Header": []string{"test value"}}} w := httptest.NewRecorder() doc := fmt.Sprintf(`hello: Path("/hello") -> "%s"`, s.URL) dc, err := testdataclient.NewDoc(doc) if err != nil { t.Error(err) } p := New(routing.New(routing.Options{ nil, routing.MatchingOptionsNone, sourcePollTimeout, []routing.DataClient{dc}, nil, 0}), OptionsNone) delay() p.ServeHTTP(w, r) if w.Code != http.StatusOK { t.Error("wrong status", w.Code) } if w.Body.Len() != 0 { t.Error("wrong content", string(w.Body.Bytes())) } }
func ExampleFilter() { // create a test filter and add to the registry: fr := builtin.MakeRegistry() fr.Register(&filtertest.Filter{FilterName: "testFilter"}) // create a data client, with a predefined route referencing the filter: dc, err := testdataclient.NewDoc(`Path("/some/path/:param") -> testFilter(3.14, "Hello, world!") -> "https://www.example.org"`) if err != nil { log.Fatal(err) } // create an http.Handler: proxy.New( routing.New(routing.Options{ DataClients: []routing.DataClient{dc}, FilterRegistry: fr}), proxy.OptionsNone) }
func WithParams(fr filters.Registry, o proxy.Params, routes ...*eskip.Route) *TestProxy { dc := testdataclient.New(routes) tl := loggingtest.New() rt := routing.New(routing.Options{FilterRegistry: fr, DataClients: []routing.DataClient{dc}, Log: tl}) o.Routing = rt pr := proxy.WithParams(o) tsp := httptest.NewServer(pr) if err := tl.WaitFor("route settings applied", 3*time.Second); err != nil { panic(err) } return &TestProxy{ URL: tsp.URL, log: tl, routing: rt, proxy: pr, server: tsp} }
func ExamplePriorityRoute() { // create a routing doc forwarding all requests, // and load it in a data client: routeDoc := `* -> "https://www.example.org"` dataClient, err := testdataclient.NewDoc(routeDoc) if err != nil { log.Fatal(err) } // create a priority route making exceptions: pr := &priorityRoute{} // create an http.Handler: proxy.New( routing.New(routing.Options{ FilterRegistry: builtin.MakeRegistry(), DataClients: []routing.DataClient{dataClient}}), proxy.OptionsNone, pr) }
func newTestProxyWithFilters(fr filters.Registry, doc string, flags Flags, pr ...PriorityRoute) (*testProxy, error) { dc, err := testdataclient.NewDoc(doc) if err != nil { return nil, err } tl := loggingtest.New() rt := routing.New(routing.Options{ FilterRegistry: fr, PollTimeout: sourcePollTimeout, DataClients: []routing.DataClient{dc}, Log: tl}) p := WithParams(Params{Routing: rt, Flags: flags, PriorityRoutes: pr}) if err := tl.WaitFor("route settings applied", time.Second); err != nil { return nil, err } return &testProxy{tl, rt, p}, nil }
func TestProcessesFilterDefinitions(t *testing.T) { if testing.Short() { t.Skip() } fr := make(filters.Registry) fs := &filtertest.Filter{FilterName: "filter1"} fr.Register(fs) dc := testdataclient.New([]*eskip.Route{{ Id: "route1", Path: "/some-path", Filters: []*eskip.Filter{{Name: "filter1", Args: []interface{}{3.14, "Hello, world!"}}}, Backend: "https://www.example.org"}}) rt := routing.New(routing.Options{ UpdateBuffer: 0, DataClients: []routing.DataClient{dc}, PollTimeout: pollTimeout, FilterRegistry: fr}) req, err := http.NewRequest("GET", "https://www.example.com/some-path", nil) if err != nil { t.Error(err) } select { case r := <-waitRoute(rt, req): if len(r.Filters) != 1 { t.Error("failed to process filters") return } if f, ok := r.Filters[0].Filter.(*filtertest.Filter); !ok || f.FilterName != fs.Name() || len(f.Args) != 2 || f.Args[0] != float64(3.14) || f.Args[1] != "Hello, world!" { t.Error("failed to process filters") } case <-time.After(3 * pollTimeout): t.Error("test timeout") } }
// to run this test, set `-args listener` for the test command func TestHTTPSServer(t *testing.T) { // TODO: figure why sometimes cannot connect if !testListener() { t.Skip() } a, err := findAddress() if err != nil { t.Fatal(err) } o := Options{ Address: a, CertPathTLS: "fixtures/test.crt", KeyPathTLS: "fixtures/test.key", } rt := routing.New(routing.Options{ FilterRegistry: builtin.MakeRegistry(), DataClients: []routing.DataClient{}}) defer rt.Close() proxy := proxy.New(rt, proxy.OptionsNone) defer proxy.Close() go listenAndServe(proxy, &o) r, err := waitConnGet("https://" + o.Address) if r != nil { defer r.Body.Close() } if err != nil { t.Fatalf("Cannot connect to the local server for testing: %s ", err.Error()) } if r.StatusCode != 404 { t.Fatalf("Status code should be 404, instead got: %d\n", r.StatusCode) } _, err = ioutil.ReadAll(r.Body) if err != nil { t.Fatalf("Failed to stream response body: %v", err) } }
func TestOriginalRequestResponse(t *testing.T) { s := startTestServer(nil, 0, func(r *http.Request) { if th, ok := r.Header["X-Test-Header-Preserved"]; !ok || th[0] != "test value" { t.Error("wrong request header") } }) defer s.Close() u, _ := url.ParseRequestURI("https://www.example.org/hello") r := &http.Request{ URL: u, Method: "GET", Header: http.Header{"X-Test-Header": []string{"test value"}}} w := httptest.NewRecorder() doc := fmt.Sprintf(`hello: Path("/hello") -> preserveOriginal() -> "%s"`, s.URL) dc, err := testdataclient.NewDoc(doc) if err != nil { t.Error(err) } fr := builtin.MakeRegistry() fr.Register(&preserveOriginalSpec{}) p := New(routing.New(routing.Options{ fr, routing.MatchingOptionsNone, sourcePollTimeout, []routing.DataClient{dc}, nil, 0}), OptionsPreserveOriginal) delay() p.ServeHTTP(w, r) if th, ok := w.Header()["X-Test-Response-Header-Preserved"]; !ok || th[0] != "response header value" { t.Error("wrong response header", ok) } }
func TestWithWrongKeyPathFails(t *testing.T) { a, err := findAddress() if err != nil { t.Fatal(err) } o := Options{Address: a, CertPathTLS: "fixtures/test.crt", KeyPathTLS: "fixtures/notFound.key", } rt := routing.New(routing.Options{ FilterRegistry: builtin.MakeRegistry(), DataClients: []routing.DataClient{}}) defer rt.Close() proxy := proxy.New(rt, proxy.OptionsNone) defer proxy.Close() err = listenAndServe(proxy, &o) if err == nil { t.Fatal(err) } }