func (s *VESuite) TestFrontendUpdateBackend(c *C) { server1 := testutils.NewHandler(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("1")) }) defer server1.Close() server2 := testutils.NewHandler(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("2")) }) defer server2.Close() // Create two different backends b1, srv1, url1 := "bk1", "srv1", server1.URL _, err := s.client.Set(s.path("backends", b1, "backend"), `{"Type": "http"}`, 0) c.Assert(err, IsNil) _, err = s.client.Set(s.path("backends", b1, "servers", srv1), fmt.Sprintf(`{"URL": "%s"}`, url1), 0) c.Assert(err, IsNil) b2, srv2, url2 := "bk2", "srv2", server2.URL _, err = s.client.Set(s.path("backends", b2, "backend"), `{"Type": "http"}`, 0) c.Assert(err, IsNil) _, err = s.client.Set(s.path("backends", b2, "servers", srv2), fmt.Sprintf(`{"URL": "%s"}`, url2), 0) c.Assert(err, IsNil) // Add frontend inititally pointing to the first backend fId := "fr1" _, err = s.client.Set(s.path("frontends", fId, "frontend"), `{"Type": "http", "BackendId": "bk1", "Route": "Path(\"/path\")"}`, 0) c.Assert(err, IsNil) time.Sleep(time.Second) url := fmt.Sprintf("%s%s", s.serviceUrl, "/path") response, body, err := testutils.Get(url) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) c.Assert(string(body), Equals, "1") // Update the backend _, err = s.client.Set(s.path("frontends", fId, "frontend"), `{"Type": "http", "BackendId": "bk2", "Route": "Path(\"/path\")"}`, 0) c.Assert(err, IsNil) time.Sleep(time.Second) response, body, err = testutils.Get(url) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) c.Assert(string(body), Equals, "2") }
// Make sure that stream handler preserves TLS settings func (s *STSuite) TestPreservesTLS(c *C) { srv := testutils.NewHandler(func(w http.ResponseWriter, req *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("ok")) }) defer srv.Close() // forwarder will proxy the request to whatever destination fwd, err := forward.New() c.Assert(err, IsNil) var t *tls.ConnectionState // this is our redirect to server rdr := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { t = req.TLS req.URL = testutils.ParseURI(srv.URL) fwd.ServeHTTP(w, req) }) // stream handler will forward requests to redirect st, err := New(rdr, Logger(utils.NewFileLogger(os.Stdout, utils.INFO))) c.Assert(err, IsNil) proxy := httptest.NewUnstartedServer(st) proxy.StartTLS() defer proxy.Close() re, _, err := testutils.Get(proxy.URL) c.Assert(err, IsNil) c.Assert(re.StatusCode, Equals, http.StatusOK) c.Assert(t, NotNil) }
func (s *STSuite) TestNoBody(c *C) { srv := testutils.NewHandler(func(w http.ResponseWriter, req *http.Request) { w.WriteHeader(http.StatusOK) }) defer srv.Close() // forwarder will proxy the request to whatever destination fwd, err := forward.New() c.Assert(err, IsNil) // this is our redirect to server rdr := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { req.URL = testutils.ParseURI(srv.URL) fwd.ServeHTTP(w, req) }) // stream handler will forward requests to redirect st, err := New(rdr, Logger(utils.NewFileLogger(os.Stdout, utils.INFO))) c.Assert(err, IsNil) proxy := httptest.NewServer(st) defer proxy.Close() re, _, err := testutils.Get(proxy.URL) c.Assert(err, IsNil) c.Assert(re.StatusCode, Equals, http.StatusOK) }
func (s *STSuite) TestCustomErrorHandler(c *C) { srv := testutils.NewHandler(func(w http.ResponseWriter, req *http.Request) { w.Write([]byte("hello, this response is too large")) }) defer srv.Close() // forwarder will proxy the request to whatever destination fwd, err := forward.New() c.Assert(err, IsNil) // this is our redirect to server rdr := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { req.URL = testutils.ParseURI(srv.URL) fwd.ServeHTTP(w, req) }) // stream handler will forward requests to redirect errHandler := utils.ErrorHandlerFunc(func(w http.ResponseWriter, req *http.Request, err error) { w.WriteHeader(http.StatusTeapot) w.Write([]byte(http.StatusText(http.StatusTeapot))) }) st, err := New(rdr, Logger(utils.NewFileLogger(os.Stdout, utils.INFO)), MaxResponseBodyBytes(4), ErrorHandler(errHandler)) c.Assert(err, IsNil) proxy := httptest.NewServer(st) defer proxy.Close() re, _, err := testutils.Get(proxy.URL) c.Assert(err, IsNil) c.Assert(re.StatusCode, Equals, http.StatusTeapot) }
func (s *STSuite) TestChunkedEncodingLimitReached(c *C) { srv := testutils.NewHandler(func(w http.ResponseWriter, req *http.Request) { w.Write([]byte("hello")) }) defer srv.Close() // forwarder will proxy the request to whatever destination fwd, err := forward.New() c.Assert(err, IsNil) // this is our redirect to server rdr := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { req.URL = testutils.ParseURI(srv.URL) fwd.ServeHTTP(w, req) }) // stream handler will forward requests to redirect st, err := New(rdr, Logger(utils.NewFileLogger(os.Stdout, utils.INFO)), MemRequestBodyBytes(4), MaxRequestBodyBytes(8)) c.Assert(err, IsNil) proxy := httptest.NewServer(st) defer proxy.Close() conn, err := net.Dial("tcp", testutils.ParseURI(proxy.URL).Host) c.Assert(err, IsNil) fmt.Fprintf(conn, "POST / HTTP/1.0\r\nTransfer-Encoding: chunked\r\n\r\n4\r\ntest\r\n5\r\ntest1\r\n5\r\ntest2\r\n0\r\n\r\n") status, err := bufio.NewReader(conn).ReadString('\n') c.Assert(status, Equals, "HTTP/1.0 413 Request Entity Too Large\r\n") }
func (s *ServerSuite) TestBackendUpdateOptions(c *C) { e := testutils.NewHandler(func(w http.ResponseWriter, r *http.Request) { time.Sleep(10 * time.Millisecond) w.Write([]byte("slow server")) }) defer e.Close() c.Assert(s.mux.Start(), IsNil) b := MakeBatch(Batch{Addr: "localhost:11300", Route: `Path("/")`, URL: e.URL}) settings := b.B.HTTPSettings() settings.Timeouts = engine.HTTPBackendTimeouts{Read: "1ms"} b.B.Settings = settings c.Assert(s.mux.UpsertBackend(b.B), IsNil) c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) re, _, err := testutils.Get(MakeURL(b.L, "/")) c.Assert(err, IsNil) c.Assert(re, NotNil) c.Assert(re.StatusCode, Equals, http.StatusGatewayTimeout) settings.Timeouts = engine.HTTPBackendTimeouts{Read: "20ms"} b.B.Settings = settings c.Assert(s.mux.UpsertBackend(b.B), IsNil) c.Assert(GETResponse(c, b.FrontendURL("/")), Equals, "slow server") }
func (s *STSuite) TestRequestLimitReached(c *C) { srv := testutils.NewHandler(func(w http.ResponseWriter, req *http.Request) { w.Write([]byte("hello")) }) defer srv.Close() // forwarder will proxy the request to whatever destination fwd, err := forward.New() c.Assert(err, IsNil) // this is our redirect to server rdr := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { req.URL = testutils.ParseURI(srv.URL) fwd.ServeHTTP(w, req) }) // stream handler will forward requests to redirect st, err := New(rdr, Logger(utils.NewFileLogger(os.Stdout, utils.INFO)), MaxRequestBodyBytes(4)) c.Assert(err, IsNil) proxy := httptest.NewServer(st) defer proxy.Close() re, _, err := testutils.Get(proxy.URL, testutils.Body("this request is too long")) c.Assert(err, IsNil) c.Assert(re.StatusCode, Equals, http.StatusRequestEntityTooLarge) }
func (s *STSuite) TestFileStreamingResponse(c *C) { srv := testutils.NewHandler(func(w http.ResponseWriter, req *http.Request) { w.Write([]byte("hello, this response is too large to fit in memory")) }) defer srv.Close() // forwarder will proxy the request to whatever destination fwd, err := forward.New() c.Assert(err, IsNil) // this is our redirect to server rdr := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { req.URL = testutils.ParseURI(srv.URL) fwd.ServeHTTP(w, req) }) // stream handler will forward requests to redirect st, err := New(rdr, Logger(utils.NewFileLogger(os.Stdout, utils.INFO)), MemResponseBodyBytes(4)) c.Assert(err, IsNil) proxy := httptest.NewServer(st) defer proxy.Close() re, body, err := testutils.Get(proxy.URL) c.Assert(err, IsNil) c.Assert(re.StatusCode, Equals, http.StatusOK) c.Assert(string(body), Equals, "hello, this response is too large to fit in memory") }
// Set up a frontend hit this frontend with request and make sure everything worked fine func (s *VESuite) TestFrontendCRUD(c *C) { called := false server := testutils.NewHandler(func(w http.ResponseWriter, r *http.Request) { called = true w.Write([]byte("Hi, I'm fine, thanks!")) }) defer server.Close() // Create a server b, srv, url := "bk1", "srv1", server.URL _, err := s.client.Set(s.path("backends", b, "backend"), `{"Type": "http"}`, 0) c.Assert(err, IsNil) _, err = s.client.Set(s.path("backends", b, "servers", srv), fmt.Sprintf(`{"URL": "%s"}`, url), 0) c.Assert(err, IsNil) // Add frontend fId := "fr1" _, err = s.client.Set(s.path("frontends", fId, "frontend"), `{"Type": "http", "BackendId": "bk1", "Route": "Path(\"/path\")"}`, 0) c.Assert(err, IsNil) time.Sleep(time.Second) response, _, err := testutils.Get(fmt.Sprintf("%s%s", s.serviceUrl, "/path")) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) c.Assert(called, Equals, true) }
func (s *ServerSuite) TestServerHTTPS(c *C) { var req *http.Request e := testutils.NewHandler(func(w http.ResponseWriter, r *http.Request) { req = r w.Write([]byte("hi https")) }) defer e.Close() b := MakeBatch(Batch{ Addr: "localhost:41000", Route: `Path("/")`, URL: e.URL, Protocol: engine.HTTPS, KeyPair: &engine.KeyPair{Key: localhostKey, Cert: localhostCert}, }) c.Assert(s.mux.UpsertHost(b.H), IsNil) c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) c.Assert(s.mux.Start(), IsNil) c.Assert(GETResponse(c, b.FrontendURL("/")), Equals, "hi https") // Make sure that we see right proto c.Assert(req.Header.Get("X-Forwarded-Proto"), Equals, "https") }
func (s *VESuite) TestHTTPSListenerCRUD(c *C) { called := false server := testutils.NewHandler(func(w http.ResponseWriter, r *http.Request) { called = true w.Write([]byte("Hi, I'm fine, thanks!")) }) defer server.Close() b, srv, url := "bk1", "srv1", server.URL _, err := s.client.Set(s.path("backends", b, "backend"), `{"Type": "http"}`, 0) c.Assert(err, IsNil) _, err = s.client.Set(s.path("backends", b, "servers", srv), fmt.Sprintf(`{"URL": "%s"}`, url), 0) c.Assert(err, IsNil) // Add frontend fId := "fr1" _, err = s.client.Set(s.path("frontends", fId, "frontend"), `{"Type": "http", "BackendId": "bk1", "Route": "Path(\"/path\")"}`, 0) c.Assert(err, IsNil) keyPair := NewTestKeyPair() bytes, err := secret.SealKeyPairToJSON(s.box, keyPair) c.Assert(err, IsNil) sealed := base64.StdEncoding.EncodeToString(bytes) host := "localhost" _, err = s.client.Set(s.path("hosts", host, "host"), fmt.Sprintf(`{"Name": "localhost", "Settings": {"KeyPair": "%v"}}`, sealed), 0) c.Assert(err, IsNil) // Add HTTPS listener l2 := "ls2" listener, err := engine.NewListener(l2, "https", "tcp", "localhost:32000", "", nil) c.Assert(err, IsNil) bytes, err = json.Marshal(listener) c.Assert(err, IsNil) s.client.Set(s.path("listeners", l2), string(bytes), 0) time.Sleep(time.Second) _, _, err = testutils.Get(fmt.Sprintf("%s%s", "https://localhost:32000", "/path")) c.Assert(err, IsNil) c.Assert(called, Equals, true) _, err = s.client.Delete(s.path("listeners", l2), true) c.Assert(err, IsNil) time.Sleep(time.Second) _, _, err = testutils.Get(fmt.Sprintf("%s%s", "https://localhost:32000", "/path")) c.Assert(err, NotNil) }
func (s *ServerSuite) TestServerUpdateHTTPS(c *C) { var req *http.Request e := testutils.NewHandler(func(w http.ResponseWriter, r *http.Request) { req = r w.Write([]byte("hi https")) }) defer e.Close() b := MakeBatch(Batch{ Addr: "localhost:41000", Route: `Path("/")`, URL: e.URL, Protocol: engine.HTTPS, KeyPair: &engine.KeyPair{Key: localhostKey, Cert: localhostCert}, }) b.L.Settings = &engine.HTTPSListenerSettings{TLS: engine.TLSSettings{MinVersion: "VersionTLS11"}} c.Assert(s.mux.UpsertHost(b.H), IsNil) c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) c.Assert(s.mux.Start(), IsNil) config := &tls.Config{ InsecureSkipVerify: true, // We only support tls 10 MinVersion: tls.VersionTLS10, MaxVersion: tls.VersionTLS10, } conn, err := tls.Dial("tcp", b.L.Address.Address, config) c.Assert(err, NotNil) // we got TLS error // Relax the version b.L.Settings = &engine.HTTPSListenerSettings{TLS: engine.TLSSettings{MinVersion: "VersionTLS10"}} c.Assert(s.mux.UpsertListener(b.L), IsNil) time.Sleep(20 * time.Millisecond) conn, err = tls.Dial("tcp", b.L.Address.Address, config) c.Assert(err, IsNil) fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n") status, err := bufio.NewReader(conn).ReadString('\n') c.Assert(status, Equals, "HTTP/1.0 200 OK\r\n") state := conn.ConnectionState() c.Assert(state.Version, DeepEquals, uint16(tls.VersionTLS10)) conn.Close() }
func (s *VESuite) TestHTTPListenerCRUD(c *C) { called := false server := testutils.NewHandler(func(w http.ResponseWriter, r *http.Request) { called = true w.Write([]byte("Hi, I'm fine, thanks!")) }) defer server.Close() b, srv, url := "bk1", "srv1", server.URL _, err := s.client.Set(s.path("backends", b, "backend"), `{"Type": "http"}`, 0) c.Assert(err, IsNil) _, err = s.client.Set(s.path("backends", b, "servers", srv), fmt.Sprintf(`{"URL": "%s"}`, url), 0) c.Assert(err, IsNil) // Add frontend fId := "fr1" _, err = s.client.Set(s.path("frontends", fId, "frontend"), `{"Type": "http", "BackendId": "bk1", "Route": "Path(\"/path\")"}`, 0) c.Assert(err, IsNil) time.Sleep(time.Second) response, _, err := testutils.Get(fmt.Sprintf("%s%s", s.serviceUrl, "/path")) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) // Add HTTP listener l1 := "l1" listener, err := engine.NewListener(l1, "http", "tcp", "localhost:31000", "", nil) c.Assert(err, IsNil) bytes, err := json.Marshal(listener) c.Assert(err, IsNil) s.client.Set(s.path("listeners", l1), string(bytes), 0) time.Sleep(time.Second) _, _, err = testutils.Get(fmt.Sprintf("%s%s", "http://localhost:31000", "/path")) c.Assert(err, IsNil) c.Assert(called, Equals, true) _, err = s.client.Delete(s.path("listeners", l1), true) c.Assert(err, IsNil) time.Sleep(time.Second) _, _, err = testutils.Get(fmt.Sprintf("%s%s", "http://localhost:31000", "/path")) c.Assert(err, NotNil) }
func (s *RTSuite) TestSuccess(c *C) { srv := testutils.NewHandler(func(w http.ResponseWriter, req *http.Request) { w.Write([]byte("hello")) }) defer srv.Close() lb, rt := new(c, `IsNetworkError() && Attempts() <= 2`) proxy := httptest.NewServer(rt) defer proxy.Close() lb.UpsertServer(testutils.ParseURI(srv.URL)) re, body, err := testutils.Get(proxy.URL) c.Assert(err, IsNil) c.Assert(re.StatusCode, Equals, http.StatusOK) c.Assert(string(body), Equals, "hello") }
func (s *RTSuite) TestRetryExceedAttempts(c *C) { srv := testutils.NewHandler(func(w http.ResponseWriter, req *http.Request) { w.Write([]byte("hello")) }) defer srv.Close() lb, rt := new(c, `IsNetworkError() && Attempts() <= 2`) proxy := httptest.NewServer(rt) defer proxy.Close() lb.UpsertServer(testutils.ParseURI("http://localhost:64321")) lb.UpsertServer(testutils.ParseURI("http://localhost:64322")) lb.UpsertServer(testutils.ParseURI("http://localhost:64323")) lb.UpsertServer(testutils.ParseURI(srv.URL)) re, _, err := testutils.Get(proxy.URL) c.Assert(err, IsNil) c.Assert(re.StatusCode, Equals, http.StatusBadGateway) }
func (s *ServerSuite) TestMiddlewareOrder(c *C) { var req *http.Request e := testutils.NewHandler(func(w http.ResponseWriter, r *http.Request) { req = r w.Write([]byte("done")) }) defer e.Close() c.Assert(s.mux.Start(), IsNil) b := MakeBatch(Batch{ Addr: "localhost:31000", Route: `Path("/")`, URL: e.URL, }) c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) a1 := engine.Middleware{ Priority: 0, Type: "appender", Id: "a1", Middleware: &appender{append: "a1"}, } a2 := engine.Middleware{ Priority: 1, Type: "appender", Id: "a0", Middleware: &appender{append: "a2"}, } c.Assert(s.mux.UpsertMiddleware(b.FK, a1), IsNil) c.Assert(s.mux.UpsertMiddleware(b.FK, a2), IsNil) c.Assert(GETResponse(c, b.FrontendURL("/")), Equals, "done") c.Assert(req.Header["X-Append"], DeepEquals, []string{"a1", "a2"}) }
func (s *VESuite) TestBackendUpdateSettings(c *C) { server := testutils.NewHandler(func(w http.ResponseWriter, r *http.Request) { time.Sleep(50 * time.Millisecond) w.Write([]byte("tc: update upstream options")) }) defer server.Close() b, srv, url := "bk1", "srv1", server.URL _, err := s.client.Set(s.path("backends", b, "backend"), `{"Type": "http", "Settings": {"Timeouts": {"Read":"10ms"}}}`, 0) c.Assert(err, IsNil) _, err = s.client.Set(s.path("backends", b, "servers", srv), fmt.Sprintf(`{"URL": "%s"}`, url), 0) c.Assert(err, IsNil) // Add frontend fId := "fr1" _, err = s.client.Set(s.path("frontends", fId, "frontend"), `{"Type": "http", "BackendId": "bk1", "Route": "Path(\"/path\")"}`, 0) c.Assert(err, IsNil) // Wait for the changes to take effect time.Sleep(time.Second) // Make sure request times out response, _, err := testutils.Get(fmt.Sprintf("%s%s", s.serviceUrl, "/path")) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusGatewayTimeout) // Update backend timeout _, err = s.client.Set(s.path("backends", b, "backend"), `{"Type": "http", "Settings": {"Timeouts": {"Read":"100ms"}}}`, 0) c.Assert(err, IsNil) // Wait for the changes to take effect time.Sleep(time.Second) response, body, err := testutils.Get(fmt.Sprintf("%s%s", s.serviceUrl, "/path")) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) c.Assert(string(body), Equals, "tc: update upstream options") }
func (s *ServerSuite) TestServerNoBody(c *C) { e := testutils.NewHandler(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotModified) }) defer e.Close() c.Assert(s.mux.Start(), IsNil) b := MakeBatch(Batch{ Addr: "localhost:31000", Route: `Path("/")`, URL: e.URL, }) c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) re, _, err := testutils.Get(b.FrontendURL("/")) c.Assert(err, IsNil) c.Assert(re.StatusCode, Equals, http.StatusNotModified) }
func (s *STSuite) TestChunkedEncodingSuccess(c *C) { var reqBody string var contentLength int64 srv := testutils.NewHandler(func(w http.ResponseWriter, req *http.Request) { body, err := ioutil.ReadAll(req.Body) c.Assert(err, IsNil) reqBody = string(body) contentLength = req.ContentLength w.Write([]byte("hello")) }) defer srv.Close() // forwarder will proxy the request to whatever destination fwd, err := forward.New() c.Assert(err, IsNil) // this is our redirect to server rdr := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { req.URL = testutils.ParseURI(srv.URL) fwd.ServeHTTP(w, req) }) // stream handler will forward requests to redirect st, err := New(rdr, Logger(utils.NewFileLogger(os.Stdout, utils.INFO))) c.Assert(err, IsNil) proxy := httptest.NewServer(st) defer proxy.Close() conn, err := net.Dial("tcp", testutils.ParseURI(proxy.URL).Host) c.Assert(err, IsNil) fmt.Fprintf(conn, "POST / HTTP/1.0\r\nTransfer-Encoding: chunked\r\n\r\n4\r\ntest\r\n5\r\ntest1\r\n5\r\ntest2\r\n0\r\n\r\n") status, err := bufio.NewReader(conn).ReadString('\n') c.Assert(reqBody, Equals, "testtest1test2") c.Assert(status, Equals, "HTTP/1.0 200 OK\r\n") c.Assert(contentLength, Equals, int64(len(reqBody))) }
func (s *VESuite) TestFrontendUpdateLimits(c *C) { var headers http.Header server := testutils.NewHandler(func(w http.ResponseWriter, r *http.Request) { headers = r.Header w.Write([]byte("Hello, I'm totally fine")) }) defer server.Close() b, srv, url := "bk1", "srv1", server.URL _, err := s.client.Set(s.path("backends", b, "backend"), `{"Type": "http"}`, 0) c.Assert(err, IsNil) _, err = s.client.Set(s.path("backends", b, "servers", srv), fmt.Sprintf(`{"URL": "%s"}`, url), 0) c.Assert(err, IsNil) // Add frontend fId := "fr1" _, err = s.client.Set(s.path("frontends", fId, "frontend"), `{"Type": "http", "BackendId": "bk1", "Route": "Path(\"/path\")"}`, 0) c.Assert(err, IsNil) time.Sleep(time.Second) response, _, err := testutils.Get(fmt.Sprintf("%s%s", s.serviceUrl, "/path")) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) c.Assert(response.Header.Get("X-Forwarded-For"), Not(Equals), "hello") _, err = s.client.Set( s.path("frontends", fId, "frontend"), `{"Type": "http", "BackendId": "bk1", "Route": "Path(\"/path\")", "Settings": {"Limits": {"MaxMemBodyBytes":2, "MaxBodyBytes":4}}}`, 0) c.Assert(err, IsNil) time.Sleep(time.Second) response, _, err = testutils.Get(fmt.Sprintf("%s%s", s.serviceUrl, "/path"), testutils.Body("This is longer than allowed 4 bytes")) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusRequestEntityTooLarge) }
func (s *VESuite) TestLiveBinaryUpgrade(c *C) { server := testutils.NewHandler(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello 1")) }) defer server.Close() b, srv, url := "bk1", "srv1", server.URL _, err := s.client.Set(s.path("backends", b, "backend"), `{"Type": "http"}`, 0) c.Assert(err, IsNil) _, err = s.client.Set(s.path("backends", b, "servers", srv), fmt.Sprintf(`{"URL": "%s"}`, url), 0) c.Assert(err, IsNil) // Add frontend fId := "fr1" _, err = s.client.Set(s.path("frontends", fId, "frontend"), `{"Type": "http", "BackendId": "bk1", "Route": "Path(\"/path\")"}`, 0) c.Assert(err, IsNil) keyPair := NewTestKeyPair() bytes, err := secret.SealKeyPairToJSON(s.box, keyPair) c.Assert(err, IsNil) sealed := base64.StdEncoding.EncodeToString(bytes) host := "localhost" _, err = s.client.Set(s.path("hosts", host, "host"), fmt.Sprintf(`{"Name": "localhost", "Settings": {"KeyPair": "%v"}}`, sealed), 0) c.Assert(err, IsNil) // Add HTTPS listener l2 := "ls2" listener, err := engine.NewListener(l2, "https", "tcp", "localhost:32000", "", nil) c.Assert(err, IsNil) bytes, err = json.Marshal(listener) c.Assert(err, IsNil) s.client.Set(s.path("listeners", l2), string(bytes), 0) time.Sleep(time.Second) _, body, err := testutils.Get(fmt.Sprintf("%s%s", "https://localhost:32000", "/path")) c.Assert(err, IsNil) c.Assert(string(body), Equals, "Hello 1") pidS, err := exec.Command("pidof", "vulcand").Output() c.Assert(err, IsNil) // Find a running vulcand pid, err := strconv.Atoi(strings.TrimSpace(string(pidS))) c.Assert(err, IsNil) vulcand, err := os.FindProcess(pid) c.Assert(err, IsNil) // Ask vulcand to fork a child vulcand.Signal(syscall.SIGUSR2) time.Sleep(time.Second) // Ask parent process to stop vulcand.Signal(syscall.SIGTERM) // Make sure the child is running pid2S, err := exec.Command("pidof", "vulcand").Output() c.Assert(err, IsNil) c.Assert(string(pid2S), Not(Equals), "") c.Assert(string(pid2S), Not(Equals), string(pidS)) time.Sleep(time.Second) // Make sure we are still running and responding _, body, err = testutils.Get(fmt.Sprintf("%s%s", "https://localhost:32000", "/path")) c.Assert(err, IsNil) c.Assert(string(body), Equals, "Hello 1") }
func (s *CBSuite) TestSideEffects(c *C) { srv1Chan := make(chan *http.Request, 1) var srv1Body []byte srv1 := testutils.NewHandler(func(w http.ResponseWriter, r *http.Request) { b, err := ioutil.ReadAll(r.Body) c.Assert(err, IsNil) srv1Body = b w.Write([]byte("srv1")) srv1Chan <- r }) defer srv1.Close() srv2Chan := make(chan *http.Request, 1) srv2 := testutils.NewHandler(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("srv2")) r.ParseForm() srv2Chan <- r }) defer srv2.Close() onTripped, err := NewWebhookSideEffect( Webhook{ URL: fmt.Sprintf("%s/post.json", srv1.URL), Method: "POST", Headers: map[string][]string{"Content-Type": []string{"application/json"}}, Body: []byte(`{"Key": ["val1", "val2"]}`), }) c.Assert(err, IsNil) onStandby, err := NewWebhookSideEffect( Webhook{ URL: fmt.Sprintf("%s/post", srv2.URL), Method: "POST", Form: map[string][]string{"key": []string{"val1", "val2"}}, }) c.Assert(err, IsNil) handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { w.Write([]byte("hello")) }) cb, err := New(handler, triggerNetRatio, Clock(s.clock), CheckPeriod(time.Microsecond), OnTripped(onTripped), OnStandby(onStandby)) c.Assert(err, IsNil) srv := httptest.NewServer(cb) defer srv.Close() cb.metrics = statsNetErrors(0.6) _, _, err = testutils.Get(srv.URL) c.Assert(err, IsNil) c.Assert(cb.state, Equals, cbState(stateTripped)) select { case req := <-srv1Chan: c.Assert(req.Method, Equals, "POST") c.Assert(req.URL.Path, Equals, "/post.json") c.Assert(string(srv1Body), Equals, `{"Key": ["val1", "val2"]}`) c.Assert(req.Header.Get("Content-Type"), Equals, "application/json") case <-time.After(time.Second): c.Error("timeout waiting for side effect to kick off") } // Transition to recovering state s.advanceTime(10*time.Second + time.Millisecond) cb.metrics = statsOK() testutils.Get(srv.URL) c.Assert(cb.state, Equals, cbState(stateRecovering)) // Going back to standby s.advanceTime(10*time.Second + time.Millisecond) testutils.Get(srv.URL) c.Assert(cb.state, Equals, cbState(stateStandby)) select { case req := <-srv2Chan: c.Assert(req.Method, Equals, "POST") c.Assert(req.URL.Path, Equals, "/post") c.Assert(req.Form, DeepEquals, url.Values{"key": []string{"val1", "val2"}}) case <-time.After(time.Second): c.Error("timeout waiting for side effect to kick off") } }