diff --git a/website/config.json b/website/config.json deleted file mode 100644 index f0c95b0f..00000000 --- a/website/config.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "baseurl": "https://echo.labstack.com", - "languageCode": "en-us", - "title": "Fast and unfancy HTTP server framework for Go (Golang) - LabStack Echo", - "canonifyurls": true, - "googleAnalytics": "UA-85059636-2", - "permalinks": { - "guide": "/guide/:title", - "middleware": "/middleware/:title", - "recipes": "/recipes/:title" - }, - "menu": { - "side": [{ - "name": "Guide", - "pre": "", - "weight": 1, - "identifier": "guide", - "url": "guide" - },{ - "name": "Middleware", - "pre": "", - "weight": 1, - "identifier": "middleware", - "url": "middleware" - }, { - "name": "Recipes", - "pre": "", - "weight": 2, - "identifier": "recipes", - "url": "recipes" - }, { - "name": "Godoc", - "pre": "", - "weight": 3, - "identifier": "godoc", - "url": "godoc" - }] - }, - "params": { - "description": "Golang micro web framework, High performance, Minimalistic and Fast." - } -} diff --git a/website/content/godoc/echo.md b/website/content/godoc/echo.md deleted file mode 100644 index 628384f8..00000000 --- a/website/content/godoc/echo.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: echo -menu: - side: - parent: godoc - weight: 1 - url: https://godoc.org/github.com/labstack/echo ---- diff --git a/website/content/godoc/engine.md b/website/content/godoc/engine.md deleted file mode 100644 index bc1011b8..00000000 --- a/website/content/godoc/engine.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: engine -menu: - side: - parent: godoc - weight: 3 - url: https://godoc.org/github.com/labstack/echo/engine ---- diff --git a/website/content/godoc/fasthttp.md b/website/content/godoc/fasthttp.md deleted file mode 100644 index b641be34..00000000 --- a/website/content/godoc/fasthttp.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: fasthttp -menu: - side: - parent: godoc - weight: 5 - url: https://godoc.org/github.com/labstack/echo/engine/fasthttp ---- diff --git a/website/content/godoc/middleware.md b/website/content/godoc/middleware.md deleted file mode 100644 index 881b476c..00000000 --- a/website/content/godoc/middleware.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: middleware -menu: - side: - identifier: "godoc-middleware" - parent: godoc - weight: 1 - url: https://godoc.org/github.com/labstack/echo/middleware ---- diff --git a/website/content/godoc/standard.md b/website/content/godoc/standard.md deleted file mode 100644 index c7e7e87e..00000000 --- a/website/content/godoc/standard.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: standard -menu: - side: - parent: godoc - weight: 4 - url: https://godoc.org/github.com/labstack/echo/engine/standard ---- diff --git a/website/content/guide/context.md b/website/content/guide/context.md deleted file mode 100644 index 4414e9b6..00000000 --- a/website/content/guide/context.md +++ /dev/null @@ -1,73 +0,0 @@ -+++ -title = "Context" -[menu.side] - identifier = "context" - parent = "guide" - weight = 5 -+++ - -## Context - -`echo.Context` represents the context of the current HTTP request. It holds request and -response reference, path, path parameters, data, registered handler and APIs to read -request and write response. Context is 100% compatible with standard `context.Context`. -As Context is an interface, it is easy to extend it with custom APIs. - -#### Extending Context - -**Define a custom context** - -```go -type CustomContext struct { - echo.Context -} - -func (c *CustomContext) Foo() { - println("foo") -} - -func (c *CustomContext) Bar() { - println("bar") -} -``` - -**Create a middleware to extend default context** - -```go -e.Use(func(h echo.HandlerFunc) echo.HandlerFunc { - return func(c echo.Context) error { - cc := &CustomContext{c} - return h(cc) - } -}) -``` - -> This middleware should be registered before any other middleware. - -**Use in handler** - -```go -e.Get("/", func(c echo.Context) error { - cc := c.(*CustomContext) - cc.Foo() - cc.Bar() - return cc.String(200, "OK") -}) -``` - -### Standard Context - -`echo.Context` embeds standard `context.Context` interface, so all it's functions -are available right from `echo.Context`. - -*Example* - -```go -e.GET("/users/:name", func(c echo.Context) error) { - c.SetContext(context.WithValue(nil, "key", "val")) - // Pass it down... - // Use it... - val := c.Value("key").(string) - return c.String(http.StatusOK, name) -}) -``` diff --git a/website/content/guide/cookies.md b/website/content/guide/cookies.md deleted file mode 100644 index f90a5081..00000000 --- a/website/content/guide/cookies.md +++ /dev/null @@ -1,77 +0,0 @@ -+++ -title = "Cookies" -[menu.side] - name = "Cookies" - parent = "guide" - weight = 6 -+++ - -## Cookies - -Cookie is a small piece of data sent from a website and stored in the user's web -browser while the user is browsing. Every time the user loads the website, the browser -sends the cookie back to the server to notify the user's previous activity. -Cookies were designed to be a reliable mechanism for websites to remember stateful -information (such as items added in the shopping cart in an online store) or to -record the user's browsing activity (including clicking particular buttons, logging -in, or recording which pages were visited in the past). Cookies can also store -passwords and form content a user has previously entered, such as a credit card -number or an address. - -### Cookie Attributes - -Attribute | Optional -:--- | :--- -`Name` | No -`Value` | No -`Path` | Yes -`Domain` | Yes -`Expires` | Yes -`Secure` | Yes -`HTTPOnly` | Yes - -### Create a Cookie - -```go -func writeCookie(c echo.Context) error { - cookie := new(echo.Cookie) - cookie.SetName("username") - cookie.SetValue("jon") - cookie.SetExpires(time.Now().Add(24 * time.Hour)) - c.SetCookie(cookie) - return c.String(http.StatusOK, "write a cookie") -} -``` - -- Cookie is created using `new(echo.Cookie)`. -- Attributes for the cookie are set using `Setter` functions. -- Finally `c.SetCookie(cookies)` adds a `Set-Cookie` header in HTTP response. - -### Read a Cookie - -```go -func readCookie(c echo.Context) error { - cookie, err := c.Cookie("username") - if err != nil { - return err - } - fmt.Println(cookie.Name()) - fmt.Println(cookie.Value()) - return c.String(http.StatusOK, "read a cookie") -} -``` - -- Cookie is read by name using `c.Cookie("username")` from the HTTP request. -- Cookie attributes are accessed using `Getter` function. - -### Read all Cookies - -```go -func readAllCookies(c echo.Context) error { - for _, cookie := range c.Cookies() { - fmt.Println(cookie.Name()) - fmt.Println(cookie.Value()) - } - return c.String(http.StatusOK, "read all cookie") -} -``` diff --git a/website/content/guide/customization.md b/website/content/guide/customization.md deleted file mode 100644 index 77cb2e7d..00000000 --- a/website/content/guide/customization.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: Customization -menu: - side: - parent: guide - weight: 3 ---- - -## Customization - -### HTTP Error Handler - -`Echo#SetHTTPErrorHandler(h HTTPErrorHandler)` registers a custom `Echo#HTTPErrorHandler`. - -Default HTTP error handler rules: - -- If error is of type `Echo#HTTPError` it sends HTTP response with status code `HTTPError.Code` -and message `HTTPError.Message`. -- Else it sends `500 - Internal Server Error`. -- If debug mode is enabled, it uses `error.Error()` as status message. - -### Debug - -`Echo#SetDebug(on bool)` enable/disable debug mode. - -### Logging - -#### Custom Logger - -`Echo#SetLogger(l log.Logger)` - -SetLogger defines a custom logger. - -#### Log Output - -`Echo#SetLogOutput(w io.Writer)` sets the output destination for the logger. Default -value `os.Stdout` - -To completely disable logs use `Echo#SetLogOutput(io.Discard)` - -#### Log Level - -`Echo#SetLogLevel(l log.Level)` - -SetLogLevel sets the log level for the logger. Default value `5` (OFF). -Possible values: - -- `0` (DEBUG) -- `1` (INFO) -- `2` (WARN) -- `3` (ERROR) -- `4` (FATAL) -- `5` (OFF) - -### HTTP Engine - -Echo currently supports standard and [fasthttp](https://github.com/valyala/fasthttp) -server engines. Echo utilizes interfaces to abstract the internal implementation -of these servers so you can seamlessly switch from one engine to another based on -your preference. - -#### Running a standard HTTP server - -`e.Run(standard.New(":1323"))` - -#### Running a fasthttp server - -`e.Run(fasthttp.New(":1323"))` - -#### Running a server with TLS configuration - -`e.Run(.WithTLS(":1323", "", ""))` - -#### Running a server with engine configuration - -`e.Run(.WithConfig())` - -##### Configuration - -```go -Config struct { - Address string // TCP address to listen on. - Listener net.Listener // Custom `net.Listener`. If set, server accepts connections on it. - TLSCertFile string // TLS certificate file path. - TLSKeyFile string // TLS key file path. - ReadTimeout time.Duration // Maximum duration before timing out read of the request. - WriteTimeout time.Duration // Maximum duration before timing out write of the response. -} -``` - -#### Access internal server instance and configure its properties - -```go -s := standard.New(":1323") -s.MaxHeaderBytes = 1 << 20 -e.Run(s) -``` diff --git a/website/content/guide/error-handling.md b/website/content/guide/error-handling.md deleted file mode 100644 index 5bbeddf1..00000000 --- a/website/content/guide/error-handling.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Error Handling -menu: - side: - parent: guide - weight: 8 ---- - -## Error Handling - -Echo advocates centralized HTTP error handling by returning error from middleware -or handlers. - -- Log errors from a unified location -- Send customized HTTP responses - -For example, when basic auth middleware finds invalid credentials it returns -`401 - Unauthorized` error, aborting the current HTTP request. - -```go -package main - -import ( - "net/http" - - "github.com/labstack/echo" -) - -func main() { - e := echo.New() - e.Use(func(c echo.Context) error { - // Extract the credentials from HTTP request header and perform a security - // check - - // For invalid credentials - return echo.NewHTTPError(http.StatusUnauthorized) - }) - e.GET("/welcome", welcome) - e.Run(":1323") -} - -func welcome(c echo.Context) error { - return c.String(http.StatusOK, "Welcome!") -} -``` - -See how [HTTPErrorHandler](/guide/customization#http-error-handler) handles it. diff --git a/website/content/guide/faq.md b/website/content/guide/faq.md deleted file mode 100644 index a49e0c50..00000000 --- a/website/content/guide/faq.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: FAQ -menu: - side: - parent: guide - weight: 20 ---- - -## FAQ - -Q: **How to retrieve `*http.Request` and `http.ResponseWriter` from `echo.Context`?** - -- `http.Request` > `c.Request().(*standard.Request).Request` -- `http.ResponseWriter` > `c.Response()` - -> Standard engine only - -Q: **How to use standard handler `func(http.ResponseWriter, *http.Request)` with Echo?** - -```go -func handler(w http.ResponseWriter, r *http.Request) { - io.WriteString(w, "Handler!") -} - -func main() { - e := echo.New() - e.GET("/", standard.WrapHandler(http.HandlerFunc(handler))) - e.Run(standard.New(":1323")) -} -``` - -Q: **How to use fasthttp handler `func(fasthttp.RequestCtx)` with Echo?** - -```go -func handler(c *fh.RequestCtx) { - io.WriteString(c, "Handler!") -} - -func main() { - e := echo.New() - e.GET("/", fasthttp.WrapHandler(handler)) - e.Run(fasthttp.New(":1323")) -} -``` - -Q: **How to use standard middleware `func(http.Handler) http.Handler` with Echo?** - -```go -func middleware(h http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - println("Middleware!") - h.ServeHTTP(w, r) - }) -} - -func main() { - e := echo.New() - e.Use(standard.WrapMiddleware(middleware)) - e.GET("/", func(c echo.Context) error { - return c.String(http.StatusOK, "OK") - }) - e.Run(standard.New(":1323")) -} -``` - -Q: **How to use fasthttp middleware `func(http.Handler) http.Handler` with Echo?** - -```go -func middleware(h fh.RequestHandler) fh.RequestHandler { - return func(ctx *fh.RequestCtx) { - println("Middleware!") - h(ctx) - } -} - -func main() { - e := echo.New() - e.Use(fasthttp.WrapMiddleware(middleware)) - e.GET("/", func(c echo.Context) error { - return c.String(http.StatusOK, "OK") - }) - e.Run(fasthttp.New(":1323")) -} -``` - - diff --git a/website/content/guide/installation.md b/website/content/guide/installation.md deleted file mode 100644 index 20a1f83c..00000000 --- a/website/content/guide/installation.md +++ /dev/null @@ -1,21 +0,0 @@ -+++ -title = "Installation" -[menu.side] - parent = "guide" - weight = 1 -+++ - -## Installation - -Echo is developed and tested using Go `1.6.x` and `1.7.x` - -```sh -$ go get -u github.com/labstack/echo -``` - -> Ideally, you should rely on a [package manager](https://github.com/avelino/awesome-go#package-management) like glide or govendor to use a specific [version](https://github.com/labstack/echo/releases) of Echo. - -### [Migrating from v1](/guide/migrating) - -Echo follows [semantic versioning](http://semver.org) managed through GitHub releases. -Specific version of Echo can be installed using a [package manager](https://github.com/avelino/awesome-go#package-management). diff --git a/website/content/guide/migrating.md b/website/content/guide/migrating.md deleted file mode 100644 index 121f89b2..00000000 --- a/website/content/guide/migrating.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: Migrating -menu: - side: - parent: guide - weight: 2 ---- - -## Migrating from v1 - -### Change Log - -- Good news, 85% of the API remains the same. -- `Engine` interface to abstract `HTTP` server implementation, allowing -us to use HTTP servers beyond Go standard library. It currently supports standard and [fasthttp](https://github.com/valyala/fasthttp) server. -- Context, Request and Response are converted to interfaces. [More...](https://github.com/labstack/echo/issues/146) -- Handler signature is changed to `func (c echo.Context) error`. -- Dropped auto wrapping of handler and middleware to enforce compile time check. -- APIs to run middleware before or after the router, which doesn't require `Echo#Hook` API now. -- Ability to define middleware at route level. -- `Echo#HTTPError` exposed it's fields `Code` and `Message`. -- Option to specify log format in logger middleware and default logger. - -#### API - -v1 | v2 ---- | --- -`Context#Query()` | `Context#QueryParam()` -`Context#Form()` | `Context#FormValue()` - -### FAQ - -Q. How to access original objects from interfaces? - -A. Only if you need to... - -```go -// `*http.Request` -c.Request().(*standard.Request).Request - -// `*http.URL` -c.Request().URL().(*standard.URL).URL - -// Request `http.Header` -c.Request().Header().(*standard.Header).Header - -// `http.ResponseWriter` -c.Response().(*standard.Response).ResponseWriter - -// Response `http.Header` -c.Response().Header().(*standard.Header).Header -``` - -Q. How to use standard handler and middleware? - -A. - -```go -package main - -import ( - "net/http" - - "github.com/labstack/echo" - "github.com/labstack/echo/engine/standard" -) - -// Standard middleware -func middleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - println("standard middleware") - next.ServeHTTP(w, r) - }) -} - -// Standard handler -func handler(w http.ResponseWriter, r *http.Request) { - println("standard handler") -} - -func main() { - e := echo.New() - e.Use(standard.WrapMiddleware(middleware)) - e.GET("/", standard.WrapHandler(http.HandlerFunc(handler))) - e.Run(standard.New(":1323")) -} -``` - -### Next? - -- Browse through [recipes](/recipes/hello-world) freshly converted to v2. -- Read documentation and dig into test cases. diff --git a/website/content/guide/request.md b/website/content/guide/request.md deleted file mode 100644 index 27ca6ac0..00000000 --- a/website/content/guide/request.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: Request -menu: - side: - parent: guide - weight: 6 ---- - -## Request - -### Bind Request Body - -To bind request body into a provided Go type use `Context#Bind(interface{})`. -The default binder supports decoding application/json, application/xml and -application/x-www-form-urlencoded payload based on Context-Type header. - -*Example* - -TODO - -> Custom binder can be registered via `Echo#SetBinder(Binder)` - -### Query Parameter - -Query parameter can be retrieved by name using `Context#QueryParam(name string)`. - -*Example* - -```go -e.GET("/users", func(c echo.Context) error { - name := c.QueryParam("name") - return c.String(http.StatusOK, name) -}) -``` - -```sh -$ curl -G -d "name=joe" http://localhost:1323/users -``` - -### Form Parameter - -Form parameter can be retrieved by name using `Context#FormValue(name string)`. - -*Example* - -```go -e.POST("/users", func(c echo.Context) error { - name := c.FormValue("name") - return c.String(http.StatusOK, name) -}) -``` - -```sh -$ curl -d "name=joe" http://localhost:1323/users -``` - -### Path Parameter - -Registered path parameter can be retrieved either by name `Context#Param(name string) string` -or by index `Context#P(i int) string`. Getting parameter by index gives a slightly -better performance. - -*Example* - -```go -e.GET("/users/:name", func(c echo.Context) error { - // By name - name := c.Param("name") - - // By index - name := c.P(0) - - return c.String(http.StatusOK, name) -}) -``` - -```sh -$ curl http://localhost:1323/users/joe -``` - - -### Handler Path - -`Context#Path()` returns the registered path for the handler, it can be used in the -middleware for logging purpose. - -*Example* - -```go -e.Use(func(c echo.Context) error { - println(c.Path()) // Prints `/users/:name` - return nil -}) -e.GET("/users/:name", func(c echo.Context) error) { - return c.String(http.StatusOK, name) -}) -``` diff --git a/website/content/guide/routing.md b/website/content/guide/routing.md deleted file mode 100644 index 793b4f43..00000000 --- a/website/content/guide/routing.md +++ /dev/null @@ -1,114 +0,0 @@ ---- -title: Routing -menu: - side: - parent: guide - weight: 4 ---- - -## Routing - -Echo's router is [fast, optimized]({{< ref "index.md#performance">}}) and -flexible. It's based on [radix tree](http://en.wikipedia.org/wiki/Radix_tree) data -structure which makes route lookup really fast. Router leverages [sync pool](https://golang.org/pkg/sync/#Pool) -to reuse memory and achieve zero dynamic memory allocation with no GC overhead. - -Routes can be registered by specifying HTTP method, path and a matching handler. -For example, code below registers a route for method `GET`, path `/hello` and a -handler which sends `Hello, World!` HTTP response. - -```go -// Handler -func hello(c echo.Context) error { - return c.String(http.StatusOK, "Hello, World!") -} - -// Route -e.GET("/hello", hello) -``` - -You can use `Echo.Any(path string, h Handler)` to register a handler for all HTTP methods. -If you want to register it for some methods use `Echo.Match(methods []string, path string, h Handler)`. - -Echo defines handler function as `func(echo.Context) error` where `echo.Context` primarily -holds HTTP request and response interfaces. - -### Match-any - -Matches zero or more characters in the path. For example, pattern `/users/*` will -match: - -- `/users/` -- `/users/1` -- `/users/1/files/1` -- `/users/anything...` - -### Path matching order - -- Static -- Param -- Match any - -#### Example - -```go -e.GET("/users/:id", func(c echo.Context) error { - return c.String(http.StatusOK, "/users/:id") -}) - -e.GET("/users/new", func(c echo.Context) error { - return c.String(http.StatusOK, "/users/new") -}) - -e.GET("/users/1/files/*", func(c echo.Context) error { - return c.String(http.StatusOK, "/users/1/files/*") -}) -``` - -Above routes would resolve in the following order: - -- `/users/new` -- `/users/:id` -- `/users/1/files/*` - -> Routes can be written in any order. - -### Group - -`Echo#Group(prefix string, m ...Middleware) *Group` - -Routes with common prefix can be grouped to define a new sub-router with optional -middleware. In addition to specified middleware group also inherits parent middleware. -To add middleware later in the group you can use `Group.Use(m ...Middleware)`. -Groups can also be nested. - -In the code below, we create an admin group which requires basic HTTP authentication -for routes `/admin/*`. - -```go -g := e.Group("/admin") -g.Use(middleware.BasicAuth(func(username, password string) bool { - if username == "joe" && password == "secret" { - return true - } - return false -})) -``` - -### URI building - -`Echo.URI` can be used to generate URI for any handler with specified path parameters. -It's helpful to centralize all your URI patterns which ease in refactoring your -application. - -`e.URI(h, 1)` will generate `/users/1` for the route registered below - -```go -// Handler -h := func(c echo.Context) error { - return c.String(http.StatusOK, "OK") -} - -// Route -e.GET("/users/:id", h) -``` diff --git a/website/content/guide/static-files.md b/website/content/guide/static-files.md deleted file mode 100644 index bb43f063..00000000 --- a/website/content/guide/static-files.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: Static Files -menu: - side: - parent: guide - weight: 3 ---- - -Images, JavaScript, CSS, PDF, Fonts and so on... - -## Static Files - -### [Using Static Middleware]({{< ref "middleware/static.md">}}) - -### Using `Echo#Static()` - -`Echo#Static(prefix, root string)` registers a new route with path prefix to serve -static files from the provided root directory. - -*Usage 1* - -```go -e := echo.New() -e.Static("/static", "assets") -``` - -Example above will serve any file from the assets directory for path `/static/*`. For example, -a request to `/static/js/main.js` will fetch and serve `assets/js/main.js` file. - -*Usage 2* - -```go -e := echo.New() -e.Static("/", "assets") -``` - -Example above will serve any file from the assets directory for path `/*`. For example, -a request to `/js/main.js` will fetch and serve `assets/js/main.js` file. - -### Using `Echo#File()` - -`Echo#File(path, file string)` registers a new route with path to serve a static -file. - -*Usage 1* - -Serving an index page from `public/index.html` - -```go -e.File("/", "public/index.html") -``` - -*Usage 2* - -Serving a favicon from `images/favicon.ico` - -```go -e.File("/favicon.ico", "images/favicon.ico") -``` diff --git a/website/content/guide/templates.md b/website/content/guide/templates.md deleted file mode 100644 index 97e665f1..00000000 --- a/website/content/guide/templates.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: Templates -menu: - side: - parent: guide - weight: 3 ---- - -## Templates - -### Template Rendering - -`Context#Render(code int, name string, data interface{}) error` renders a template -with data and sends a text/html response with status code. Templates can be registered -using `Echo.SetRenderer()`, allowing us to use any template engine. - -Example below shows how to use Go `html/template`: - -1. Implement `echo.Renderer` interface - - ```go - type Template struct { - templates *template.Template - } - - func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error { - return t.templates.ExecuteTemplate(w, name, data) - } - ``` - -2. Pre-compile templates - - `public/views/hello.html` - - ```html - {{define "hello"}}Hello, {{.}}!{{end}} - ``` - - ```go - t := &Template{ - templates: template.Must(template.ParseGlob("public/views/*.html")), - } - ``` - -3. Register templates - - ```go - e := echo.New() - e.SetRenderer(t) - e.GET("/hello", Hello) - ``` - -4. Render a template inside your handler - - ```go - func Hello(c echo.Context) error { - return c.Render(http.StatusOK, "hello", "World") - } - ``` diff --git a/website/content/guide/testing.md b/website/content/guide/testing.md deleted file mode 100644 index b42b9aa6..00000000 --- a/website/content/guide/testing.md +++ /dev/null @@ -1,160 +0,0 @@ ---- -title: Testing -menu: - side: - parent: guide - weight: 9 ---- - -## Testing - -### Testing Handler - -`GET` `/users/:id` - -Handler below retrieves user by id from the database. If user is not found it returns -`404` error with a message. - -#### CreateUser - -`POST` `/users` - -- Accepts JSON payload -- On success `201 - Created` -- On error `500 - Internal Server Error` - -#### GetUser - -`GET` `/users/:email` - -- On success `200 - OK` -- On error `404 - Not Found` if user is not found otherwise `500 - Internal Server Error` - -`handler.go` - -```go -package handler - -import ( - "net/http" - - "github.com/labstack/echo" -) - -type ( - User struct { - Name string `json:"name" form:"name"` - Email string `json:"email" form:"email"` - } - handler struct { - db map[string]*User - } -) - -func (h *handler) createUser(c echo.Context) error { - u := new(User) - if err := c.Bind(u); err != nil { - return err - } - return c.JSON(http.StatusCreated, u) -} - -func (h *handler) getUser(c echo.Context) error { - email := c.Param("email") - user := h.db[email] - if user == nil { - return echo.NewHTTPError(http.StatusNotFound, "user not found") - } - return c.JSON(http.StatusOK, user) -} -``` - -`handler_test.go` - -```go -package handler - -import ( - "net/http" - "net/http/httptest" - "strings" - "testing" - - "github.com/labstack/echo" - "github.com/labstack/echo/engine/standard" - "github.com/stretchr/testify/assert" -) - -var ( - mockDB = map[string]*User{ - "jon@labstack.com": &User{"Jon Snow", "jon@labstack.com"}, - } - userJSON = `{"name":"Jon Snow","email":"jon@labstack.com"}` -) - -func TestCreateUser(t *testing.T) { - // Setup - e := echo.New() - req, err := http.NewRequest(echo.POST, "/users", strings.NewReader(userJSON)) - if assert.NoError(t, err) { - req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) - rec := httptest.NewRecorder() - c := e.NewContext(standard.NewRequest(req, e.Logger()), standard.NewResponse(rec, e.Logger())) - h := &handler{mockDB} - - // Assertions - if assert.NoError(t, h.createUser(c)) { - assert.Equal(t, http.StatusCreated, rec.Code) - assert.Equal(t, userJSON, rec.Body.String()) - } - } -} - -func TestGetUser(t *testing.T) { - // Setup - e := echo.New() - req := new(http.Request) - rec := httptest.NewRecorder() - c := e.NewContext(standard.NewRequest(req, e.Logger()), standard.NewResponse(rec, e.Logger())) - c.SetPath("/users/:email") - c.SetParamNames("email") - c.SetParamValues("jon@labstack.com") - h := &handler{mockDB} - - // Assertions - if assert.NoError(t, h.getUser(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, userJSON, rec.Body.String()) - } -} -``` - -#### Using Form Payload - -```go -f := make(url.Values) -f.Set("name", "Jon Snow") -f.Set("email", "jon@labstack.com") -req, err := http.NewRequest(echo.POST, "/", strings.NewReader(f.Encode())) -``` - -#### Setting Path Params - -```go -c.SetParamNames("id", "email") -c.SetParamValues("1", "jon@labstack.com") -``` - -#### Setting Query Params - -```go -q := make(url.Values) -q.Set("email", "jon@labstack.com") -req, err := http.NewRequest(echo.POST, "/?"+q.Encode(), nil) -``` - -### Testing Middleware - -*TBD* - -You can looking to built-in middleware [test cases](https://github.com/labstack/echo/tree/master/middleware). diff --git a/website/content/index.md b/website/content/index.md deleted file mode 100644 index acc25581..00000000 --- a/website/content/index.md +++ /dev/null @@ -1,291 +0,0 @@ ---- -title: Index ---- - -# Fast and unfancy HTTP server framework for Go (Golang). - -## Feature Overview - -- Optimized HTTP router which smartly prioritize routes -- Build robust and scalable RESTful APIs -- Run with standard HTTP server or FastHTTP server -- Group APIs -- Extensible middleware framework -- Define middleware at root, group or route level -- Data binding for JSON, XML and form payload -- Handy functions to send variety of HTTP responses -- Centralized HTTP error handling -- Template rendering with any template engine -- Define your format for the logger -- Highly customizable - - -## Performance - -- Environment: - - Go 1.6 - - wrk 4.0.0 - - 2 GB, 2 Core (DigitalOcean) -- Test Suite: https://github.com/vishr/web-framework-benchmark -- Date: 4/4/2016 - -Performance - -## Quick Start - -### Installation - -```sh -$ go get -u github.com/labstack/echo -``` - -### Hello, World! - -Create `server.go` - -```go -package main - -import ( - "net/http" - "github.com/labstack/echo" - "github.com/labstack/echo/engine/standard" -) - -func main() { - e := echo.New() - e.GET("/", func(c echo.Context) error { - return c.String(http.StatusOK, "Hello, World!") - }) - e.Run(standard.New(":1323")) -} -``` - -Start server - -```sh -$ go run server.go -``` - -Browse to [http://localhost:1323](http://localhost:1323) and you should see -Hello, World! on the page. - -### Routing - -```go -e.POST("/users", saveUser) -e.GET("/users/:id", getUser) -e.PUT("/users/:id", updateUser) -e.DELETE("/users/:id", deleteUser) -``` - -### Path Parameters - -```go -func getUser(c echo.Context) error { - // User ID from path `users/:id` - id := c.Param("id") -} -``` - -### Query Parameters - -`/show?team=x-men&member=wolverine` - -```go -func show(c echo.Context) error { - // Get team and member from the query string - team := c.QueryParam("team") - member := c.QueryParam("member") -} -``` - -### Form `application/x-www-form-urlencoded` - -`POST` `/save` - -name | value -:--- | :--- -name | Joe Smith -email | joe@labstack.com - -```go -func save(c echo.Context) error { - // Get name and email - name := c.FormValue("name") - email := c.FormValue("email") -} -``` - -### Form `multipart/form-data` - -`POST` `/save` - -name | value -:--- | :--- -name | Joe Smith -email | joe@labstack.com -avatar | avatar - -```go -func save(c echo.Context) error { - // Get name and email - name := c.FormValue("name") - email := c.FormValue("email") - // Get avatar - avatar, err := c.FormFile("avatar") - if err != nil { - return err - } - - // Source - src, err := avatar.Open() - if err != nil { - return err - } - defer src.Close() - - // Destination - dst, err := os.Create(avatar.Filename) - if err != nil { - return err - } - defer dst.Close() - - // Copy - if _, err = io.Copy(dst, src); err != nil { - return err - } - - return c.HTML(http.StatusOK, "Thank you!") -} -``` - -### Handling Request - -- Bind `JSON` or `XML` or `form` payload into Go struct based on `Content-Type` request header. -- Render response as `JSON` or `XML` with status code. - -```go -type User struct { - Name string `json:"name" xml:"name" form:"name"` - Email string `json:"email" xml:"email" form:"email"` -} - -e.POST("/users", func(c echo.Context) error { - u := new(User) - if err := c.Bind(u); err != nil { - return err - } - return c.JSON(http.StatusCreated, u) - // or - // return c.XML(http.StatusCreated, u) -}) -``` - -### Static Content - -Server any file from static directory for path `/static/*`. - -```go -e.Static("/static", "static") -``` - -##### [Learn More](https://echo.labstack.com/guide/static-files) - -### [Template Rendering](https://echo.labstack.com/guide/templates) - -### Middleware - -```go -// Root level middleware -e.Use(middleware.Logger()) -e.Use(middleware.Recover()) - -// Group level middleware -g := e.Group("/admin") -g.Use(middleware.BasicAuth(func(username, password string) bool { - if username == "joe" && password == "secret" { - return true - } - return false -})) - -// Route level middleware -track := func(next echo.HandlerFunc) echo.HandlerFunc { - return func(c echo.Context) error { - println("request to /users") - return next(c) - } -} -e.GET("/users", func(c echo.Context) error { - return c.String(http.StatusOK, "/users") -}, track) -``` - -#### Built-in Middleware - -Middleware | Description -:--- | :--- -[BodyLimit]({{< ref "middleware/body-limit.md">}}) | Limit request body -[Logger]({{< ref "middleware/logger.md">}}) | Log HTTP requests -[Recover]({{< ref "middleware/recover.md">}}) | Recover from panics -[Gzip]({{< ref "middleware/gzip.md">}}) | Send gzip HTTP response -[BasicAuth]({{< ref "middleware/basic-auth.md">}}) | HTTP basic authentication -[JWTAuth]({{< ref "middleware/jwt.md">}}) | JWT authentication -[Secure]({{< ref "middleware/secure.md">}}) | Protection against attacks -[CORS]({{< ref "middleware/cors.md">}}) | Cross-Origin Resource Sharing -[CSRF]({{< ref "middleware/csrf.md">}}) | Cross-Site Request Forgery -[Static]({{< ref "middleware/static.md">}}) | Serve static files -[HTTPSRedirect]({{< ref "middleware/redirect.md#httpsredirect-middleware">}}) | Redirect HTTP requests to HTTPS -[HTTPSWWWRedirect]({{< ref "middleware/redirect.md#httpswwwredirect-middleware">}}) | Redirect HTTP requests to WWW HTTPS -[WWWRedirect]({{< ref "middleware/redirect.md#wwwredirect-middleware">}}) | Redirect non WWW requests to WWW -[NonWWWRedirect]({{< ref "middleware/redirect.md#nonwwwredirect-middleware">}}) | Redirect WWW requests to non WWW -[AddTrailingSlash]({{< ref "middleware/trailing-slash.md#addtrailingslash-middleware">}}) | Add trailing slash to the request URI -[RemoveTrailingSlash]({{< ref "middleware/trailing-slash.md#removetrailingslash-middleware">}}) | Remove trailing slash from the request URI -[MethodOverride]({{< ref "middleware/method-override.md">}}) | Override request method - -#### Third-party Middleware - -Middleware | Description -:--- | :--- -[echoperm](https://github.com/xyproto/echoperm) | Keeping track of users, login states and permissions. -[echopprof](https://github.com/mtojek/echopprof) | Adapt net/http/pprof to labstack/echo. - -##### [Learn More](https://echo.labstack.com/middleware/overview) - -### Next - -- Head over to [guide](https://echo.labstack.com/guide/installation) -- Browse [recipes](https://echo.labstack.com/recipes/hello-world) - -### Need help? - -- [Hop on to chat](https://gitter.im/labstack/echo) -- [Open an issue](https://github.com/labstack/echo/issues/new) - -## Support Echo - -- ☆ the project -- [Donate](https://echo.labstack.com/support-echo) -- 🌐 spread the word -- [Contribute](#contribute:d680e8a854a7cbad6d490c445cba2eba) to the project - -## Contribute - -**Use issues for everything** - -- Report issues -- Discuss on chat before sending a pull request -- Suggest new features or enhancements -- Improve/fix documentation - -## Credits - -- [Vishal Rana](https://github.com/vishr) - Author -- [Nitin Rana](https://github.com/nr17) - Consultant -- [Contributors](https://github.com/labstack/echo/graphs/contributors) - -## License - -[MIT](https://github.com/labstack/echo/blob/master/LICENSE) diff --git a/website/content/middleware/basic-auth.md b/website/content/middleware/basic-auth.md deleted file mode 100644 index fb93a100..00000000 --- a/website/content/middleware/basic-auth.md +++ /dev/null @@ -1,58 +0,0 @@ -+++ -title = "Basic Auth" -[menu.side] - name = "BasicAuth" - parent = "middleware" - weight = 5 -+++ - -## BasicAuth Middleware - -BasicAuth middleware provides an HTTP basic authentication. - -- For valid credentials it calls the next handler. -- For invalid credentials, it sends "401 - Unauthorized" response. -- For empty or invalid `Authorization` header, it sends "400 - Bad Request" response. - -*Usage* - -```go -e := echo.New() -e.Use(middleware.BasicAuth(func(username, password string) bool { - if username == "joe" && password == "secret" { - return true - } - return false -})) -``` - -### Custom Configuration - -*Usage* - -```go -e := echo.New() -e.Use(middleware.BasicAuthWithConfig(middleware.BasicAuthConfig{}, -})) -``` - -### Configuration - -```go -BasicAuthConfig struct { - // Skipper defines a function to skip middleware. - Skipper Skipper - - // Validator is a function to validate BasicAuth credentials. - // Required. - Validator BasicAuthValidator -} -``` - -*Default Configuration* - -```go -DefaultBasicAuthConfig = BasicAuthConfig{ - Skipper: defaultSkipper, -} -``` diff --git a/website/content/middleware/body-limit.md b/website/content/middleware/body-limit.md deleted file mode 100644 index fb3d46cb..00000000 --- a/website/content/middleware/body-limit.md +++ /dev/null @@ -1,54 +0,0 @@ -+++ -title = "Body Limit" -[menu.side] - name = "BodyLimit" - parent = "middleware" - weight = 5 -+++ - -## BodyLimit Middleware - -BodyLimit middleware sets the maximum allowed size for a request body, if the -size exceeds the configured limit, it sends "413 - Request Entity Too Large" -response. The body limit is determined based on both `Content-Length` request -header and actual content read, which makes it super secure. - -Limit can be specified as `4x` or `4xB`, where x is one of the multiple from K, M, -G, T or P. - -*Usage* - -```go -e := echo.New() -e.Use(middleware.BodyLimit("2M")) -``` -### Custom Configuration - -*Usage* - -```go -e := echo.New() -e.Use(middleware.BodyLimitWithConfig(middleware.BodyLimitConfig{}, -})) -``` - -### Configuration - -```go -BodyLimitConfig struct { - // Skipper defines a function to skip middleware. - Skipper Skipper - - // Maximum allowed size for a request body, it can be specified - // as `4x` or `4xB`, where x is one of the multiple from K, M, G, T or P. - Limit string `json:"limit"` -} -``` - -*Default Configuration* - -```go -DefaultBodyLimitConfig = BodyLimitConfig{ - Skipper: defaultSkipper, -} -``` diff --git a/website/content/middleware/cors.md b/website/content/middleware/cors.md deleted file mode 100644 index 782d6631..00000000 --- a/website/content/middleware/cors.md +++ /dev/null @@ -1,79 +0,0 @@ -+++ -title = "CORS" -[menu.side] - name = "CORS" - parent = "middleware" - weight = 5 -+++ - -## CORS Middleware - -CORS middleware implements [CORS](http://www.w3.org/TR/cors) specification. -CORS gives web servers cross-domain access controls, which enable secure cross-domain -data transfers. - -*Usage* - -`e.Use(middleware.CORS())` - -### Custom Configuration - -*Usage* - -```go -e := echo.New() -e.Use(middleware.CORSWithConfig(middleware.CORSConfig{ - AllowOrigins: []string{"https://labstack.com", "https://labstack.net"}, - AllowHeaders: []string{echo.HeaderOrigin, echo.HeaderContentType, echo.HeaderAccept}, -})) -``` - -### Configuration - -```go -CORSConfig struct { - // Skipper defines a function to skip middleware. - Skipper Skipper - - // AllowOrigin defines a list of origins that may access the resource. - // Optional. Default value []string{"*"}. - AllowOrigins []string `json:"allow_origins"` - - // AllowMethods defines a list methods allowed when accessing the resource. - // This is used in response to a preflight request. - // Optional. Default value DefaultCORSConfig.AllowMethods. - AllowMethods []string `json:"allow_methods"` - - // AllowHeaders defines a list of request headers that can be used when - // making the actual request. This in response to a preflight request. - // Optional. Default value []string{}. - AllowHeaders []string `json:"allow_headers"` - - // AllowCredentials indicates whether or not the response to the request - // can be exposed when the credentials flag is true. When used as part of - // a response to a preflight request, this indicates whether or not the - // actual request can be made using credentials. - // Optional. Default value false. - AllowCredentials bool `json:"allow_credentials"` - - // ExposeHeaders defines a whitelist headers that clients are allowed to - // access. - // Optional. Default value []string{}. - ExposeHeaders []string `json:"expose_headers"` - - // MaxAge indicates how long (in seconds) the results of a preflight request - // can be cached. - // Optional. Default value 0. - MaxAge int `json:"max_age"` -} -``` - -*Default Configuration* - -```go -DefaultCORSConfig = CORSConfig{ - Skipper: defaultSkipper, - AllowOrigins: []string{"*"}, - AllowMethods: []string{echo.GET, echo.HEAD, echo.PUT, echo.PATCH, echo.POST, echo.DELETE}, -} -``` diff --git a/website/content/middleware/csrf.md b/website/content/middleware/csrf.md deleted file mode 100644 index 2c7e3c39..00000000 --- a/website/content/middleware/csrf.md +++ /dev/null @@ -1,106 +0,0 @@ -+++ -title = "CSRF" -[menu.side] - name = "CSRF" - parent = "middleware" - weight = 5 -+++ - -## CSRF Middleware - -Cross-site request forgery, also known as one-click attack or session riding and -abbreviated as CSRF (sometimes pronounced sea-surf) or XSRF, is a type of malicious -exploit of a website where unauthorized commands are transmitted from a user that -the website trusts. - -*Usage* - -`e.Use(middleware.CSRF())` - -### Custom Configuration - -*Usage* - -```go -e := echo.New() -e.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{ - TokenLookup: "header:X-XSRF-TOKEN", -})) -``` - -Example above uses `X-XSRF-TOKEN` request header to extract CSRF token. - -### Accessing CSRF Token - -#### Server-side - -CSRF token can be accessed from `Echo#Context` using `ContextKey` and passed to -the client via template. - -#### Client-side - -CSRF token can be accessed from CSRF cookie. - -### Configuration - -```go -// CSRFConfig defines the config for CSRF middleware. -CSRFConfig struct { - // Skipper defines a function to skip middleware. - Skipper Skipper - - // TokenLength is the length of the generated token. - TokenLength uint8 `json:"token_length"` - // Optional. Default value 32. - - // TokenLookup is a string in the form of ":" that is used - // to extract token from the request. - // Optional. Default value "header:X-CSRF-Token". - // Possible values: - // - "header:" - // - "form:" - // - "query:" - TokenLookup string `json:"token_lookup"` - - // Context key to store generated CSRF token into context. - // Optional. Default value "csrf". - ContextKey string `json:"context_key"` - - // Name of the CSRF cookie. This cookie will store CSRF token. - // Optional. Default value "csrf". - CookieName string `json:"cookie_name"` - - // Domain of the CSRF cookie. - // Optional. Default value none. - CookieDomain string `json:"cookie_domain"` - - // Path of the CSRF cookie. - // Optional. Default value none. - CookiePath string `json:"cookie_path"` - - // Max age (in seconds) of the CSRF cookie. - // Optional. Default value 86400 (24hr). - CookieMaxAge int `json:"cookie_max_age"` - - // Indicates if CSRF cookie is secure. - // Optional. Default value false. - CookieSecure bool `json:"cookie_secure"` - - // Indicates if CSRF cookie is HTTP only. - // Optional. Default value false. - CookieHTTPOnly bool `json:"cookie_http_only"` -} -``` - -*Default Configuration* - -```go -DefaultCSRFConfig = CSRFConfig{ - Skipper: defaultSkipper, - TokenLength: 32, - TokenLookup: "header:" + echo.HeaderXCSRFToken, - ContextKey: "csrf", - CookieName: "_csrf", - CookieMaxAge: 86400, -} -``` diff --git a/website/content/middleware/gzip.md b/website/content/middleware/gzip.md deleted file mode 100644 index 260bcfbd..00000000 --- a/website/content/middleware/gzip.md +++ /dev/null @@ -1,48 +0,0 @@ -+++ -title = "Gzip" -[menu.side] - name = "Gzip" - parent = "middleware" - weight = 5 -+++ - -## Gzip Middleware - -Gzip middleware compresses HTTP response using gzip compression scheme. - -*Usage* - -`e.Use(middleware.Gzip())` - -### Custom Configuration - -*Usage* - -```go -e := echo.New() -e.Use(middleware.GzipWithConfig(middleware.GzipConfig{ - Level: 5, -})) -``` - -### Configuration - -```go -GzipConfig struct { - // Skipper defines a function to skip middleware. - Skipper Skipper - - // Gzip compression level. - // Optional. Default value -1. - Level int `json:"level"` -} -``` - -*Default Configuration* - -```go -DefaultGzipConfig = GzipConfig{ - Skipper: defaultSkipper, - Level: -1, -} -``` diff --git a/website/content/middleware/jwt.md b/website/content/middleware/jwt.md deleted file mode 100644 index 8b3ea5d1..00000000 --- a/website/content/middleware/jwt.md +++ /dev/null @@ -1,80 +0,0 @@ -+++ -title = "JWT" -[menu.side] - name = "JWT" - parent = "middleware" - weight = 5 -+++ - -## JWT Middleware - -JWT provides a JSON Web Token (JWT) authentication middleware. - -- For valid token, it sets the user in context and calls next handler. -- For invalid token, it sends "401 - Unauthorized" response. -- For empty or invalid `Authorization` header, it sends "400 - Bad Request". - -*Usage* - -`e.Use(middleware.JWT([]byte("secret"))` - -### Custom Configuration - -*Usage* - -```go -e := echo.New() -e.Use(middleware.JWTWithConfig(middleware.JWTConfig{ - SigningKey: []byte("secret"), - TokenLookup: "query:token", -})) -``` - -### Configuration - -```go -// JWTConfig defines the config for JWT middleware. -JWTConfig struct { - // Skipper defines a function to skip middleware. - Skipper Skipper - - // Signing key to validate token. - // Required. - SigningKey interface{} `json:"signing_key"` - - // Signing method, used to check token signing method. - // Optional. Default value HS256. - SigningMethod string `json:"signing_method"` - - // Context key to store user information from the token into context. - // Optional. Default value "user". - ContextKey string `json:"context_key"` - - // Claims are extendable claims data defining token content. - // Optional. Default value jwt.MapClaims - Claims jwt.Claims - - // TokenLookup is a string in the form of ":" that is used - // to extract token from the request. - // Optional. Default value "header:Authorization". - // Possible values: - // - "header:" - // - "query:" - // - "cookie:" - TokenLookup string `json:"token_lookup"` -} -``` - -*Default Configuration* - -```go -DefaultJWTConfig = JWTConfig{ - Skipper: defaultSkipper, - SigningMethod: AlgorithmHS256, - ContextKey: "user", - TokenLookup: "header:" + echo.HeaderAuthorization, - Claims: jwt.MapClaims{}, -} -``` - -### [Recipe]({{< ref "recipes/jwt.md">}}) diff --git a/website/content/middleware/logger.md b/website/content/middleware/logger.md deleted file mode 100644 index 8a124851..00000000 --- a/website/content/middleware/logger.md +++ /dev/null @@ -1,88 +0,0 @@ -+++ -title = "Logger" -[menu.side] - name = "Logger" - parent = "middleware" - weight = 5 -+++ - -## Logger Middleware - -Logger middleware logs the information about each HTTP request. - -*Usage* - -`e.Use(middleware.Logger())` - -*Sample Output* - -```js -{"time":"2016-05-10T07:02:25-07:00","remote_ip":"::1","method":"GET","uri":"/","status":200, "latency":55653,"latency_human":"55.653µs","rx_bytes":0,"tx_bytes":13} -``` - -### Custom Configuration - -*Usage* - -```go -e := echo.New() -e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{ - Format: "method=${method}, uri=${uri}, status=${status}\n", -})) -``` - -Example above uses a `Format` which logs request method and request URI. - -*Sample Output* - -```sh -method=GET, uri=/hello, status=200 -``` - -### Configuration - -```go -LoggerConfig struct { - // Skipper defines a function to skip middleware. - Skipper Skipper - - // Log format which can be constructed using the following tags: - // - // - time_rfc3339 - // - id (Request ID - Not implemented) - // - remote_ip - // - uri - // - host - // - method - // - path - // - referer - // - user_agent - // - status - // - latency (In microseconds) - // - latency_human (Human readable) - // - bytes_in (Bytes received) - // - bytes_out (Bytes sent) - // - // Example "${remote_ip} ${status}" - // - // Optional. Default value DefaultLoggerConfig.Format. - Format string `json:"format"` - - // Output is a writer where logs are written. - // Optional. Default value os.Stdout. - Output io.Writer -} -``` - -*Default Configuration* - -```go -DefaultLoggerConfig = LoggerConfig{ - Skipper: defaultSkipper, - Format: `{"time":"${time_rfc3339}","remote_ip":"${remote_ip}",` + - `"method":"${method}","uri":"${uri}","status":${status}, "latency":${latency},` + - `"latency_human":"${latency_human}","bytes_in":${bytes_in},` + - `"bytes_out":${bytes_out}}` + "\n", - Output: os.Stdout, -} -``` diff --git a/website/content/middleware/method-override.md b/website/content/middleware/method-override.md deleted file mode 100644 index bf6a6d71..00000000 --- a/website/content/middleware/method-override.md +++ /dev/null @@ -1,51 +0,0 @@ -+++ -title = "Method Override" -[menu.side] - name = "MethodOverride" - parent = "middleware" - weight = 5 -+++ - -## MethodOverride Middleware - -MethodOverride middleware checks for the overridden method from the request and -uses it instead of the original method. - -For security reasons, only `POST` method can be overridden. - -*Usage* - -`e.Pre(middleware.MethodOverride())` - -### Custom Configuration - -*Usage* - -```go -e := echo.New() -e.Pre(middleware.MethodOverrideWithConfig(middleware.MethodOverrideConfig{ - Getter: middleware.MethodFromForm("_method"), -})) -``` - -### Configuration - -```go -MethodOverrideConfig struct { - // Skipper defines a function to skip middleware. - Skipper Skipper - - // Getter is a function that gets overridden method from the request. - // Optional. Default values MethodFromHeader(echo.HeaderXHTTPMethodOverride). - Getter MethodOverrideGetter -} -``` - -*Default Configuration* - -```go -DefaultMethodOverrideConfig = MethodOverrideConfig{ - Skipper: defaultSkipper, - Getter: MethodFromHeader(echo.HeaderXHTTPMethodOverride), -} -``` diff --git a/website/content/middleware/overview.md b/website/content/middleware/overview.md deleted file mode 100644 index fb6a5cea..00000000 --- a/website/content/middleware/overview.md +++ /dev/null @@ -1,104 +0,0 @@ -+++ -title = "Overview" -[menu.side] - name = "Overview" - parent = "middleware" - weight = 1 -+++ - -## Middleware Overview - -Middleware is a function chained in the HTTP request-response cycle with access -to `Echo#Context` which it uses to perform a specific action, for example, logging -every request or limiting the number of requests. - -Handler is processed in the end after all middleware are finished executing. - -### Middleware Levels - -#### Root Level (Before router) - -`Echo#Pre()` can be used to register a middleware which is executed before router -processes the request. It is helpful to make any changes to the request properties, -for example, adding or removing a trailing slash from the path so it matches the -route. - -The following built-in middleware should be registered at this level: - -- HTTPSRedirect -- HTTPSWWWRedirect -- WWWRedirect -- NonWWWRedirect -- AddTrailingSlash -- RemoveTrailingSlash -- MethodOverride - -> As router has not processed the request, middleware at this level won't -have access to any path related API from `echo.Context`. - -#### Root Level (After router) - -Most of the time you will register a middleware at this level using `Echo#Use()`. -This middleware is executed after router processes the request and has full access -to `echo.Context` API. - -The following built-in middleware should be registered at this level: - -- BodyLimit -- Logger -- Gzip -- Recover -- BasicAuth -- JWTAuth -- Secure -- CORS -- Static - -#### Group Level - -When creating a new group, you can register middleware just for that group. For -example, you can have an admin group which is secured by registering a BasicAuth -middleware for it. - -*Usage* - -```go -e := echo.New() -admin := e.Group("/admin", middleware.BasicAuth()) -``` - -You can also add a middleware after creating a group via `admin.Use()`. - -#### Route Level - -When defining a new route, you can optionally register middleware just for it. - -*Usage* - -```go -e := echo.New() -e.GET("/", , ) -``` - -### Skipping Middleware - -There are cases when you would like to skip a middleware based on some condition, -for that each middleware has an option to define a function `Skipper func(c echo.Context) bool`. - -*Usage* - -```go -e := echo.New() -e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{ - Skipper: func(c echo.Context) bool { - if strings.HasPrefix(c.Request().Host(), "localhost") { - return true - } - return false - }, -})) -``` - -Example above skips Logger middleware when request host starts with localhost. - -### [Writing Custom Middleware]({{< ref "recipes/middleware.md">}}) diff --git a/website/content/middleware/recover.md b/website/content/middleware/recover.md deleted file mode 100644 index fef121ab..00000000 --- a/website/content/middleware/recover.md +++ /dev/null @@ -1,64 +0,0 @@ -+++ -title = "Recover" -[menu.side] - name = "Recover" - parent = "middleware" - weight = 5 -+++ - -## Recover Middleware - -Recover middleware recovers from panics anywhere in the chain, prints stack trace -and handles the control to the centralized -[HTTPErrorHandler]({{< ref "guide/customization.md#http-error-handler">}}). - -*Usage* - -`e.Use(middleware.Recover())` - -### Custom Configuration - -*Usage* - -```go -e := echo.New() -e.Use(middleware.RecoverWithConfig(middleware.RecoverConfig{ - StackSize: 1 << 10, // 1 KB -})) -``` - -Example above uses a `StackSize` of 1 KB and default values for `DisableStackAll` -and `DisablePrintStack`. - -### Configuration - -```go -RecoverConfig struct { - // Skipper defines a function to skip middleware. - Skipper Skipper - - // Size of the stack to be printed. - // Optional. Default value 4KB. - StackSize int `json:"stack_size"` - - // DisableStackAll disables formatting stack traces of all other goroutines - // into buffer after the trace for the current goroutine. - // Optional. Default value false. - DisableStackAll bool `json:"disable_stack_all"` - - // DisablePrintStack disables printing stack trace. - // Optional. Default value as false. - DisablePrintStack bool `json:"disable_print_stack"` -} -``` - -*Default Configuration* - -```go -DefaultRecoverConfig = RecoverConfig{ - Skipper: defaultSkipper, - StackSize: 4 << 10, // 4 KB - DisableStackAll: false, - DisablePrintStack: false, -} -``` diff --git a/website/content/middleware/redirect.md b/website/content/middleware/redirect.md deleted file mode 100644 index e500177d..00000000 --- a/website/content/middleware/redirect.md +++ /dev/null @@ -1,103 +0,0 @@ -+++ -title = "Redirect" -[menu.side] - name = "Redirect" - parent = "middleware" - weight = 5 -+++ - -## HTTPSRedirect Middleware - -HTTPSRedirect middleware redirects http requests to https. -For example, http://labstack.com will be redirected to https://labstack.com. - -*Usage* - -```go -e := echo.New() -e.Pre(middleware.HTTPSRedirect()) -``` - -## HTTPSWWWRedirect Middleware - -HTTPSWWWRedirect redirects http requests to www https. -For example, http://labstack.com will be redirected to https://www.labstack.com. - -*Usage* - -```go -e := echo.New() -e.Pre(middleware.HTTPSWWWRedirect()) -``` - -## HTTPSNonWWWRedirect Middleware - -HTTPSNonWWWRedirect redirects http requests to https non www. -For example, http://www.labstack.com will be redirect to https://labstack.com. - -*Usage* - -```go -e := echo.New() -e.Pre(HTTPSNonWWWRedirect()) -``` - -## WWWRedirect Middleware - -WWWRedirect redirects non www requests to www. - -For example, http://labstack.com will be redirected to http://www.labstack.com. - -*Usage* - -```go -e := echo.New() -e.Pre(middleware.WWWRedirect()) -``` - -## NonWWWRedirect Middleware - -NonWWWRedirect redirects www requests to non www. -For example, http://www.labstack.com will be redirected to http://labstack.com. - -*Usage* - -```go -e := echo.New() -e.Pre(middleware.NonWWWRedirect()) -``` - -### Custom Configuration - -*Usage* - -```go -e := echo.New() -e.Use(middleware.HTTPSRedirectWithConfig(middleware.RedirectConfig{ - Code: http.StatusTemporaryRedirect, -})) -``` - -Example above will redirect the request HTTP to HTTPS with status code `307 - StatusTemporaryRedirect`. - -### Configuration - -```go -RedirectConfig struct { - // Skipper defines a function to skip middleware. - Skipper Skipper - - // Status code to be used when redirecting the request. - // Optional. Default value http.StatusMovedPermanently. - Code int `json:"code"` -} -``` - -*Default Configuration* - -```go -DefaultRedirectConfig = RedirectConfig{ - Skipper: defaultSkipper, - Code: http.StatusMovedPermanently, -} -``` diff --git a/website/content/middleware/secure.md b/website/content/middleware/secure.md deleted file mode 100644 index f2f0bcbd..00000000 --- a/website/content/middleware/secure.md +++ /dev/null @@ -1,97 +0,0 @@ -+++ -title = "Secure" -[menu.side] - name = "Secure" - parent = "middleware" - weight = 5 -+++ - -## Secure Middleware - -Secure middleware provides protection against cross-site scripting (XSS) attack, -content type sniffing, clickjacking, insecure connection and other code injection -attacks. - -*Usage* - -`e.Use(middleware.Secure())` - -### Custom Configuration - -*Usage* - -```go -e := echo.New() -e.Use(middleware.SecureWithConfig(middleware.SecureConfig{ - XSSProtection: "", - ContentTypeNosniff: "", - XFrameOptions: "", - HSTSMaxAge: 3600, - ContentSecurityPolicy: "default-src 'self'", -})) -``` - -Passing empty `XSSProtection`, `ContentTypeNosniff`, `XFrameOptions` or `ContentSecurityPolicy` -disables that protection. - -### Configuration - -```go -SecureConfig struct { - // Skipper defines a function to skip middleware. - Skipper Skipper - - // XSSProtection provides protection against cross-site scripting attack (XSS) - // by setting the `X-XSS-Protection` header. - // Optional. Default value "1; mode=block". - XSSProtection string `json:"xss_protection"` - - // ContentTypeNosniff provides protection against overriding Content-Type - // header by setting the `X-Content-Type-Options` header. - // Optional. Default value "nosniff". - ContentTypeNosniff string `json:"content_type_nosniff"` - - // XFrameOptions can be used to indicate whether or not a browser should - // be allowed to render a page in a ,