func TestGzip(t *testing.T) { req, _ := http.NewRequest(vodka.GET, "/", nil) rec := httptest.NewRecorder() c := vodka.NewContext(req, vodka.NewResponse(rec), vodka.New()) h := func(c *vodka.Context) error { c.Response().Write([]byte("test")) // For Content-Type sniffing return nil } // Skip if no Accept-Encoding header Gzip()(h)(c) assert.Equal(t, http.StatusOK, rec.Code) assert.Equal(t, "test", rec.Body.String()) req, _ = http.NewRequest(vodka.GET, "/", nil) req.Header.Set(vodka.AcceptEncoding, "gzip") rec = httptest.NewRecorder() c = vodka.NewContext(req, vodka.NewResponse(rec), vodka.New()) // Gzip Gzip()(h)(c) assert.Equal(t, http.StatusOK, rec.Code) assert.Equal(t, "gzip", rec.Header().Get(vodka.ContentEncoding)) assert.Contains(t, rec.Header().Get(vodka.ContentType), vodka.TextPlain) r, err := gzip.NewReader(rec.Body) defer r.Close() if assert.NoError(t, err) { buf := new(bytes.Buffer) buf.ReadFrom(r) assert.Equal(t, "test", buf.String()) } }
func main() { // Host map hosts := make(Hosts) //----- // API //----- api := vodka.New() api.Use(mw.Logger()) api.Use(mw.Recover()) hosts["api.localhost:1323"] = api api.Get("/", func(c *vodka.Context) error { return c.String(http.StatusOK, "API") }) //------ // Blog //------ blog := vodka.New() blog.Use(mw.Logger()) blog.Use(mw.Recover()) hosts["blog.localhost:1323"] = blog blog.Get("/", func(c *vodka.Context) error { return c.String(http.StatusOK, "Blog") }) //--------- // Website //--------- site := vodka.New() site.Use(mw.Logger()) site.Use(mw.Recover()) hosts["localhost:1323"] = site site.Get("/", func(c *vodka.Context) error { return c.String(http.StatusOK, "Welcome!") }) http.ListenAndServe(":1323", hosts) }
func main() { // Echo instance e := vodka.New() // Debug mode e.Debug() //------------ // Middleware //------------ // Logger e.Use(mw.Logger()) // Recover e.Use(mw.Recover()) // Basic auth e.Use(mw.BasicAuth(func(usr, pwd string) bool { if usr == "joe" && pwd == "secret" { return true } return false })) // Gzip e.Use(mw.Gzip()) // Routes e.Get("/", hello) // Start server e.Run(":1323") }
func main() { e := vodka.New() // Middleware e.Use(middleware.Logger()) e.Use(middleware.Recover()) // Login route e.POST("/login", login) // Unauthenticated route e.GET("/", accessible) // Restricted group r := e.Group("/restricted") // Configure middleware with the custom claims type config := middleware.JWTConfig{ Claims: &jwtCustomClaims{}, SigningKey: []byte("secret"), } r.Use(middleware.JWTWithConfig(config)) r.GET("", restricted) e.Run(standard.New(":1323")) }
func main() { e := vodka.New() e.Use(mw.Logger()) e.Use(mw.Recover()) e.Static("/", "public") e.WebSocket("/ws", func(c *vodka.Context) (err error) { ws := c.Socket() msg := "" for { if err = websocket.Message.Send(ws, "Hello, Client!"); err != nil { return } if err = websocket.Message.Receive(ws, &msg); err != nil { return } fmt.Println(msg) } return }) e.Run(":1323") }
func TestCORS(t *testing.T) { e := vodka.New() req := test.NewRequest(vodka.GET, "/", nil) rec := test.NewResponseRecorder() c := e.NewContext(req, rec) cors := CORSWithConfig(CORSConfig{ AllowCredentials: true, }) h := cors(func(c vodka.Context) error { return c.String(http.StatusOK, "test") }) // No origin header h(c) assert.Equal(t, "", rec.Header().Get(vodka.HeaderAccessControlAllowOrigin)) // Empty origin header req = test.NewRequest(vodka.GET, "/", nil) rec = test.NewResponseRecorder() c = e.NewContext(req, rec) req.Header().Set(vodka.HeaderOrigin, "") h(c) assert.Equal(t, "*", rec.Header().Get(vodka.HeaderAccessControlAllowOrigin)) // Wildcard origin req = test.NewRequest(vodka.GET, "/", nil) rec = test.NewResponseRecorder() c = e.NewContext(req, rec) req.Header().Set(vodka.HeaderOrigin, "localhost") h(c) assert.Equal(t, "*", rec.Header().Get(vodka.HeaderAccessControlAllowOrigin)) // Simple request req = test.NewRequest(vodka.GET, "/", nil) rec = test.NewResponseRecorder() c = e.NewContext(req, rec) req.Header().Set(vodka.HeaderOrigin, "localhost") cors = CORSWithConfig(CORSConfig{ AllowOrigins: []string{"localhost"}, AllowCredentials: true, MaxAge: 3600, }) h = cors(func(c vodka.Context) error { return c.String(http.StatusOK, "test") }) h(c) assert.Equal(t, "localhost", rec.Header().Get(vodka.HeaderAccessControlAllowOrigin)) // Preflight request req = test.NewRequest(vodka.OPTIONS, "/", nil) rec = test.NewResponseRecorder() c = e.NewContext(req, rec) req.Header().Set(vodka.HeaderOrigin, "localhost") req.Header().Set(vodka.HeaderContentType, vodka.MIMEApplicationJSON) h(c) assert.Equal(t, "localhost", rec.Header().Get(vodka.HeaderAccessControlAllowOrigin)) assert.NotEmpty(t, rec.Header().Get(vodka.HeaderAccessControlAllowMethods)) assert.Equal(t, "true", rec.Header().Get(vodka.HeaderAccessControlAllowCredentials)) assert.Equal(t, "3600", rec.Header().Get(vodka.HeaderAccessControlMaxAge)) }
func main() { e := vodka.New() // Debug mode e.SetDebug(true) //------------------- // Custom middleware //------------------- // Stats s := NewStats() e.Use(s.Process) e.GET("/stats", s.Handle) // Endpoint to get stats // Server header e.Use(ServerHeader) // Handler e.GET("/", func(c vodka.Context) error { return c.String(http.StatusOK, "Hello, World!") }) // Start server e.Run(standard.New(":1323")) }
func TestLoggerIPAddress(t *testing.T) { e := vodka.New() req := test.NewRequest(vodka.GET, "/", nil) rec := test.NewResponseRecorder() c := e.NewContext(req, rec) buf := new(bytes.Buffer) e.Logger().SetOutput(buf) ip := "127.0.0.1" h := Logger()(func(c vodka.Context) error { return c.String(http.StatusOK, "test") }) // With X-Real-IP req.Header().Add(vodka.HeaderXRealIP, ip) h(c) assert.Contains(t, ip, buf.String()) // With X-Forwarded-For buf.Reset() req.Header().Del(vodka.HeaderXRealIP) req.Header().Add(vodka.HeaderXForwardedFor, ip) h(c) assert.Contains(t, ip, buf.String()) buf.Reset() h(c) assert.Contains(t, ip, buf.String()) }
func TestGzip(t *testing.T) { e := vodka.New() req := test.NewRequest(vodka.GET, "/", nil) rec := test.NewResponseRecorder() c := e.NewContext(req, rec) // Skip if no Accept-Encoding header h := Gzip()(func(c vodka.Context) error { c.Response().Write([]byte("test")) // For Content-Type sniffing return nil }) h(c) assert.Equal(t, "test", rec.Body.String()) req = test.NewRequest(vodka.GET, "/", nil) req.Header().Set(vodka.HeaderAcceptEncoding, "gzip") rec = test.NewResponseRecorder() c = e.NewContext(req, rec) // Gzip h(c) assert.Equal(t, "gzip", rec.Header().Get(vodka.HeaderContentEncoding)) assert.Contains(t, rec.Header().Get(vodka.HeaderContentType), vodka.MIMETextPlain) r, err := gzip.NewReader(rec.Body) defer r.Close() if assert.NoError(t, err) { buf := new(bytes.Buffer) buf.ReadFrom(r) assert.Equal(t, "test", buf.String()) } }
func TestRemoveTrailingSlash(t *testing.T) { e := vodka.New() req := test.NewRequest(vodka.GET, "/remove-slash/", nil) rec := test.NewResponseRecorder() c := e.NewContext(req, rec) h := RemoveTrailingSlash()(func(c vodka.Context) error { return nil }) h(c) assert.Equal(t, "/remove-slash", req.URL().Path()) assert.Equal(t, "/remove-slash", req.URI()) // With config req = test.NewRequest(vodka.GET, "/remove-slash/?key=value", nil) rec = test.NewResponseRecorder() c = e.NewContext(req, rec) h = RemoveTrailingSlashWithConfig(TrailingSlashConfig{ RedirectCode: http.StatusMovedPermanently, })(func(c vodka.Context) error { return nil }) h(c) assert.Equal(t, http.StatusMovedPermanently, rec.Status()) assert.Equal(t, "/remove-slash?key=value", rec.Header().Get(vodka.HeaderLocation)) // With bare URL req = test.NewRequest(vodka.GET, "http://localhost", nil) rec = test.NewResponseRecorder() c = e.NewContext(req, rec) h = RemoveTrailingSlash()(func(c vodka.Context) error { return nil }) h(c) assert.Equal(t, "", req.URL().Path()) }
func TestSecure(t *testing.T) { e := vodka.New() req := test.NewRequest(vodka.GET, "/", nil) rec := test.NewResponseRecorder() c := e.NewContext(req, rec) h := func(c vodka.Context) error { return c.String(http.StatusOK, "test") } // Default Secure()(h)(c) assert.Equal(t, "1; mode=block", rec.Header().Get(vodka.HeaderXXSSProtection)) assert.Equal(t, "nosniff", rec.Header().Get(vodka.HeaderXContentTypeOptions)) assert.Equal(t, "SAMEORIGIN", rec.Header().Get(vodka.HeaderXFrameOptions)) assert.Equal(t, "", rec.Header().Get(vodka.HeaderStrictTransportSecurity)) assert.Equal(t, "", rec.Header().Get(vodka.HeaderContentSecurityPolicy)) // Custom req.Header().Set(vodka.HeaderXForwardedProto, "https") rec = test.NewResponseRecorder() c = e.NewContext(req, rec) SecureWithConfig(SecureConfig{ XSSProtection: "", ContentTypeNosniff: "", XFrameOptions: "", HSTSMaxAge: 3600, ContentSecurityPolicy: "default-src 'self'", })(h)(c) assert.Equal(t, "", rec.Header().Get(vodka.HeaderXXSSProtection)) assert.Equal(t, "", rec.Header().Get(vodka.HeaderXContentTypeOptions)) assert.Equal(t, "", rec.Header().Get(vodka.HeaderXFrameOptions)) assert.Equal(t, "max-age=3600; includeSubdomains", rec.Header().Get(vodka.HeaderStrictTransportSecurity)) assert.Equal(t, "default-src 'self'", rec.Header().Get(vodka.HeaderContentSecurityPolicy)) }
func createMux() *vodka.Vodka { e := vodka.New() // note: we don't need to provide the middleware or static handlers // for the appengine vm version - that's taken care of by the platform return e }
func main() { e := vodka.New() e.Use(middleware.Logger()) e.Use(middleware.Recover()) e.Use(middleware.Static("../public")) e.GET("/ws", standard.WrapHandler(http.HandlerFunc(hello()))) e.Run(standard.New(":1323")) }
func main() { // Setup e := vodka.New() e.Get("/", func(c *vodka.Context) error { return c.String(http.StatusOK, "Six sick bricks tick") }) gracehttp.Serve(e.Server(":1323")) }
func main() { // Setup e := vodka.New() e.Get("/", func(c *vodka.Context) error { return c.String(http.StatusOK, "Sue sews rose on slow jor crows nose") }) graceful.ListenAndServe(e.Server(":1323"), 5*time.Second) }
func main() { v := vodka.New() v.Use(m.Logger()) v.Use(m.Recover()) v.Use(m.Gzip()) v.GET("/", HelloHandler) v.Run(fasthttp.New(":1987")) }
func main() { e := vodka.New() e.GET("/", func(c vodka.Context) error { return c.String(http.StatusOK, "Six sick bricks tick") }) std := standard.New(":1323") std.SetHandler(e) gracehttp.Serve(std.Server) }
func TestStatic(t *testing.T) { e := vodka.New() req := test.NewRequest(vodka.GET, "/", nil) rec := test.NewResponseRecorder() c := e.NewContext(req, rec) h := Static("../_fixture")(func(c vodka.Context) error { return vodka.ErrNotFound }) // Directory if assert.NoError(t, h(c)) { assert.Contains(t, rec.Body.String(), "Vodka") } // HTML5 mode req = test.NewRequest(vodka.GET, "/client", nil) rec = test.NewResponseRecorder() c = e.NewContext(req, rec) static := StaticWithConfig(StaticConfig{ Root: "../_fixture", HTML5: true, }) h = static(func(c vodka.Context) error { return vodka.ErrNotFound }) if assert.NoError(t, h(c)) { assert.Equal(t, http.StatusOK, rec.Status()) } // Browse req = test.NewRequest(vodka.GET, "/", nil) rec = test.NewResponseRecorder() c = e.NewContext(req, rec) static = StaticWithConfig(StaticConfig{ Root: "../_fixture/images", Browse: true, }) h = static(func(c vodka.Context) error { return vodka.ErrNotFound }) if assert.NoError(t, h(c)) { assert.Contains(t, rec.Body.String(), "walle") } // Not found req = test.NewRequest(vodka.GET, "/not-found", nil) rec = test.NewResponseRecorder() c = e.NewContext(req, rec) static = StaticWithConfig(StaticConfig{ Root: "../_fixture/images", }) h = static(func(c vodka.Context) error { return vodka.ErrNotFound }) assert.Error(t, h(c)) }
func main() { e := vodka.New() e.GET("/request", request) e.GET("/stream", stream) e.Run(standard.WithConfig(engine.Config{ Address: ":1323", TLSCertFile: "cert.pem", TLSKeyFile: "key.pem", })) }
func main() { e := vodka.New() e.Use(mw.Logger()) e.Use(mw.Recover()) e.Static("/", "public") e.Post("/upload", upload) e.Run(":1323") }
func main() { // Setup e := vodka.New() e.GET("/", func(c vodka.Context) error { return c.String(http.StatusOK, "Sue sews rose on slow joe crows nose") }) std := standard.New(":1323") std.SetHandler(e) graceful.ListenAndServe(std.Server, 5*time.Second) }
func TestJwt(t *testing.T) { v := vodka.New() v.Get("/nojwt/", NoJwtHandler) v.Get("/token/", TokenHandler) // Restricted group r := v.Group("/jwt/") r.Use(JWTAuther(Options{ KeyFunc: func(ctx *vodka.Context) (string, error) { return JWTContextKey, nil }, })) r.Any("", JwtHandler) recorder := httptest.NewRecorder() req, err := http.NewRequest("GET", "http://localhost:8000/token/", nil) if err != nil { t.Error(err) } v.ServeHTTP(recorder, req) token := recorder.Body.String() if len(token) == 0 { t.Error("len(token) == 0") } else { fmt.Println("token:", token) } //--------------------------------- recorder = httptest.NewRecorder() req, err = http.NewRequest("GET", "http://localhost:8000/jwt/", nil) if err != nil { t.Error(err) } req.Header.Add("Authorization", "Bearer "+token) v.ServeHTTP(recorder, req) expect(t, recorder.Code, http.StatusOK) expect(t, recorder.Body.String(), "JwtHandler") //--------------------------------- recorder = httptest.NewRecorder() req, err = http.NewRequest("GET", "http://localhost:8000/nojwt/", nil) if err != nil { t.Error(err) } v.ServeHTTP(recorder, req) expect(t, recorder.Code, http.StatusOK) expect(t, recorder.Body.String(), "NoJwtHandler") }
func main() { e := vodka.New() // the file server for rice. "app" is the folder where the files come from. assetHandler := http.FileServer(rice.MustFindBox("app").HTTPBox()) // serves the index.html from rice e.GET("/", standard.WrapHandler(assetHandler)) // servers other static files e.GET("/static/*", standard.WrapHandler(http.StripPrefix("/static/", assetHandler))) e.Run(standard.New(":3000")) }
func main() { handler := http.StripPrefix( "/static/", http.FileServer(rice.MustFindBox("app").HTTPBox()), ) e := vodka.New() e.Get("/static/*", func(c *vodka.Context) error { handler.ServeHTTP(c.Response().Writer(), c.Request()) return nil }) e.Run("localhost:1234") }
func createMux() *vodka.Vodka { e := vodka.New() e.Use(middleware.Recover()) e.Use(middleware.Logger()) e.Use(middleware.Gzip()) e.Use(middleware.Static("public")) return e }
func main() { e := vodka.New() e.Use(middleware.Logger()) e.Use(middleware.Recover()) e.Use(middleware.Static("public")) e.POST("/upload", upload) e.Run(standard.New(":1323")) }
func createMux() *vodka.Vodka { e := vodka.New() // note: we don't need to provide the middleware or static handlers, that's taken care of by the platform // app engine has it's own "main" wrapper - we just need to hook vodka into the default handler s := standard.New("") s.SetHandler(e) http.Handle("/", s) return e }
func TestNonWWWRedirect(t *testing.T) { e := vodka.New() next := func(c vodka.Context) (err error) { return c.NoContent(http.StatusOK) } req := test.NewRequest(vodka.GET, "http://www.insionng.com", nil) res := test.NewResponseRecorder() c := e.NewContext(req, res) NonWWWRedirect()(next)(c) assert.Equal(t, http.StatusMovedPermanently, res.Status()) assert.Equal(t, "http://insionng.com", res.Header().Get(vodka.HeaderLocation)) }
func TestGzipErrorReturned(t *testing.T) { e := vodka.New() e.Use(Gzip()) e.GET("/", func(c vodka.Context) error { return vodka.NewHTTPError(http.StatusInternalServerError, "error") }) req := test.NewRequest(vodka.GET, "/", nil) rec := test.NewResponseRecorder() e.ServeHTTP(req, rec) assert.Empty(t, rec.Header().Get(vodka.HeaderContentEncoding)) assert.Equal(t, "error", rec.Body.String()) }
func TestRecover(t *testing.T) { e := vodka.New() e.SetDebug(true) req, _ := http.NewRequest(vodka.GET, "/", nil) rec := httptest.NewRecorder() c := vodka.NewContext(req, vodka.NewResponse(rec), e) h := func(c *vodka.Context) error { panic("test") } Recover()(h)(c) assert.Equal(t, http.StatusInternalServerError, rec.Code) assert.Contains(t, rec.Body.String(), "panic recover") }