mirror of
https://github.com/labstack/echo.git
synced 2024-11-28 08:38:39 +02:00
Refactored middleware and handlers
Signed-off-by: Vishal Rana <vr@labstack.com>
This commit is contained in:
parent
69a97671ad
commit
6cbabac296
@ -8,21 +8,18 @@ Echo is a fast HTTP router (zero memory allocation) and micro web framework in G
|
||||
- Middleware
|
||||
- `echo.MiddlewareFunc`
|
||||
- `func(echo.HandlerFunc) echo.HandlerFunc`
|
||||
- `echo.HandlerFunc`
|
||||
- `func(*echo.Context) *echo.HTTPError`
|
||||
- `func(*echo.Context)`
|
||||
- `func(http.Handler) http.Handler`
|
||||
- `http.Handler`
|
||||
- `http.HandlerFunc`
|
||||
- `func(http.ResponseWriter, *http.Request)`
|
||||
- `func(http.ResponseWriter, *http.Request) *echo.HTTPError`
|
||||
- Handler
|
||||
- `echo.HandlerFunc`
|
||||
- `func(*echo.Context) *echo.HTTPError`
|
||||
- `func(*echo.Context)`
|
||||
- `http.Handler`
|
||||
- `http.HandlerFunc`
|
||||
- `func(http.ResponseWriter, *http.Request)`
|
||||
- `func(http.ResponseWriter, *http.Request) *echo.HTTPError`
|
||||
- Sub routing with groups.
|
||||
- Handy encoding/decoding functions.
|
||||
- Serve static files, including index.
|
||||
|
104
echo.go
104
echo.go
@ -132,8 +132,9 @@ func New() (e *Echo) {
|
||||
//----------
|
||||
|
||||
e.MaxParam(5)
|
||||
e.NotFoundHandler(func(c *Context) {
|
||||
e.NotFoundHandler(func(c *Context) *HTTPError {
|
||||
http.Error(c.Response, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
||||
return nil
|
||||
})
|
||||
e.HTTPErrorHandler(func(he *HTTPError, c *Context) {
|
||||
if he.Code == 0 {
|
||||
@ -185,7 +186,7 @@ func (e *Echo) MaxParam(n uint8) {
|
||||
// NotFoundHandler registers a custom NotFound handler used by router in case it
|
||||
// doesn't find any registered handler for HTTP method and path.
|
||||
func (e *Echo) NotFoundHandler(h Handler) {
|
||||
e.notFoundHandler = wrapH(h)
|
||||
e.notFoundHandler = wrapHandler(h)
|
||||
}
|
||||
|
||||
// HTTPErrorHandler registers an HTTP error handler.
|
||||
@ -207,7 +208,7 @@ func (e *Echo) Renderer(r Renderer) {
|
||||
// Use adds handler to the middleware chain.
|
||||
func (e *Echo) Use(m ...Middleware) {
|
||||
for _, h := range m {
|
||||
e.middleware = append(e.middleware, wrapM(h))
|
||||
e.middleware = append(e.middleware, wrapMiddleware(h))
|
||||
}
|
||||
}
|
||||
|
||||
@ -286,7 +287,7 @@ func (e *Echo) URL(h Handler, params ...interface{}) string {
|
||||
func (e *Echo) add(method, path string, h Handler) {
|
||||
key := runtime.FuncForPC(reflect.ValueOf(h).Pointer()).Name()
|
||||
e.uris[key] = path
|
||||
e.Router.Add(method, e.prefix+path, wrapH(h), e)
|
||||
e.Router.Add(method, e.prefix+path, wrapHandler(h), e)
|
||||
}
|
||||
|
||||
// Static serves static files.
|
||||
@ -357,32 +358,17 @@ func (e *Echo) RunTLSServer(server *http.Server, certFile, keyFile string) {
|
||||
log.Fatal(server.ListenAndServeTLS(certFile, keyFile))
|
||||
}
|
||||
|
||||
// wraps Middleware
|
||||
func wrapM(m Middleware) MiddlewareFunc {
|
||||
// wraps middleware
|
||||
func wrapMiddleware(m Middleware) MiddlewareFunc {
|
||||
switch m := m.(type) {
|
||||
case MiddlewareFunc:
|
||||
return m
|
||||
case func(HandlerFunc) HandlerFunc:
|
||||
return m
|
||||
case HandlerFunc:
|
||||
return wrapHandlerFuncMW(m)
|
||||
case func(*Context) *HTTPError:
|
||||
return func(h HandlerFunc) HandlerFunc {
|
||||
return func(c *Context) *HTTPError {
|
||||
if he := m(c); he != nil {
|
||||
return he
|
||||
}
|
||||
return h(c)
|
||||
}
|
||||
}
|
||||
case func(*Context):
|
||||
return func(h HandlerFunc) HandlerFunc {
|
||||
return func(c *Context) *HTTPError {
|
||||
m(c)
|
||||
if !c.Response.committed {
|
||||
h(c)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return wrapHandlerFuncMW(m)
|
||||
case func(http.Handler) http.Handler:
|
||||
return func(h HandlerFunc) HandlerFunc {
|
||||
return func(c *Context) (he *HTTPError) {
|
||||
@ -394,61 +380,53 @@ func wrapM(m Middleware) MiddlewareFunc {
|
||||
return
|
||||
}
|
||||
}
|
||||
case http.Handler, http.HandlerFunc:
|
||||
return func(h HandlerFunc) HandlerFunc {
|
||||
return func(c *Context) *HTTPError {
|
||||
m.(http.Handler).ServeHTTP(c.Response.Writer, c.Request)
|
||||
return h(c)
|
||||
}
|
||||
}
|
||||
case http.Handler:
|
||||
return wrapHTTPHandlerFuncMW(m.ServeHTTP)
|
||||
case http.HandlerFunc:
|
||||
return wrapHTTPHandlerFuncMW(m)
|
||||
case func(http.ResponseWriter, *http.Request):
|
||||
return func(h HandlerFunc) HandlerFunc {
|
||||
return func(c *Context) *HTTPError {
|
||||
m(c.Response, c.Request)
|
||||
if !c.Response.committed {
|
||||
h(c)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
case func(http.ResponseWriter, *http.Request) *HTTPError:
|
||||
return func(h HandlerFunc) HandlerFunc {
|
||||
return func(c *Context) *HTTPError {
|
||||
if he := m(c.Response, c.Request); he != nil {
|
||||
return he
|
||||
}
|
||||
if !c.Response.committed {
|
||||
h(c)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return wrapHTTPHandlerFuncMW(m)
|
||||
default:
|
||||
panic("echo: unknown middleware")
|
||||
}
|
||||
}
|
||||
|
||||
// wraps Handler
|
||||
func wrapH(h Handler) HandlerFunc {
|
||||
// Wraps HandlerFunc middleware
|
||||
func wrapHandlerFuncMW(m HandlerFunc) MiddlewareFunc {
|
||||
return func(h HandlerFunc) HandlerFunc {
|
||||
return func(c *Context) *HTTPError {
|
||||
if he := m(c); he != nil {
|
||||
return he
|
||||
}
|
||||
return h(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wraps http.HandlerFunc middleware
|
||||
func wrapHTTPHandlerFuncMW(m http.HandlerFunc) MiddlewareFunc {
|
||||
return func(h HandlerFunc) HandlerFunc {
|
||||
return func(c *Context) *HTTPError {
|
||||
if !c.Response.committed {
|
||||
m.ServeHTTP(c.Response.Writer, c.Request)
|
||||
}
|
||||
return h(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// wraps handler
|
||||
func wrapHandler(h Handler) HandlerFunc {
|
||||
switch h := h.(type) {
|
||||
case HandlerFunc:
|
||||
return h
|
||||
case func(*Context) *HTTPError:
|
||||
return h
|
||||
case func(*Context):
|
||||
return func(c *Context) *HTTPError {
|
||||
h(c)
|
||||
return nil
|
||||
}
|
||||
case http.Handler, http.HandlerFunc:
|
||||
return func(c *Context) *HTTPError {
|
||||
h.(http.Handler).ServeHTTP(c.Response, c.Request)
|
||||
return nil
|
||||
}
|
||||
case func(http.ResponseWriter, *http.Request) *HTTPError:
|
||||
return func(c *Context) *HTTPError {
|
||||
return h(c.Response, c.Request)
|
||||
}
|
||||
case func(http.ResponseWriter, *http.Request):
|
||||
return func(c *Context) *HTTPError {
|
||||
h(c.Response, c.Request)
|
||||
|
95
echo_test.go
95
echo_test.go
@ -62,7 +62,7 @@ func TestEchoMiddleware(t *testing.T) {
|
||||
}
|
||||
}))
|
||||
|
||||
// func(echo.HandlerFunc) (echo.HandlerFunc, error)
|
||||
// func(echo.HandlerFunc) echo.HandlerFunc
|
||||
e.Use(func(h HandlerFunc) HandlerFunc {
|
||||
return func(c *Context) *HTTPError {
|
||||
b.WriteString("b")
|
||||
@ -76,49 +76,38 @@ func TestEchoMiddleware(t *testing.T) {
|
||||
return nil
|
||||
})
|
||||
|
||||
// func(*echo.Context)
|
||||
e.Use(func(c *Context) {
|
||||
b.WriteString("d")
|
||||
})
|
||||
|
||||
// func(http.Handler) http.Handler
|
||||
e.Use(func(h http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
b.WriteString("e")
|
||||
b.WriteString("d")
|
||||
h.ServeHTTP(w, r)
|
||||
})
|
||||
})
|
||||
|
||||
// http.Handler
|
||||
e.Use(http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
b.WriteString("f")
|
||||
b.WriteString("e")
|
||||
})))
|
||||
|
||||
// http.HandlerFunc
|
||||
e.Use(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
b.WriteString("g")
|
||||
b.WriteString("f")
|
||||
}))
|
||||
|
||||
// func(http.ResponseWriter, *http.Request)
|
||||
e.Use(func(w http.ResponseWriter, r *http.Request) {
|
||||
b.WriteString("h")
|
||||
})
|
||||
|
||||
// func(http.ResponseWriter, *http.Request) *HTTPError
|
||||
e.Use(func(w http.ResponseWriter, r *http.Request) *HTTPError {
|
||||
b.WriteString("i")
|
||||
return nil
|
||||
b.WriteString("g")
|
||||
})
|
||||
|
||||
// Route
|
||||
e.Get("/hello", func(c *Context) {
|
||||
c.String(http.StatusOK, "world")
|
||||
e.Get("/hello", func(c *Context) *HTTPError {
|
||||
return c.String(http.StatusOK, "world")
|
||||
})
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
r, _ := http.NewRequest(GET, "/hello", nil)
|
||||
e.ServeHTTP(w, r)
|
||||
if b.String() != "abcdefghi" {
|
||||
if b.String() != "abcdefg" {
|
||||
t.Errorf("buffer should be abcdefghi, found %s", b.String())
|
||||
}
|
||||
if w.Body.String() != "world" {
|
||||
@ -151,10 +140,10 @@ func TestEchoHandler(t *testing.T) {
|
||||
t.Error("body should be 2")
|
||||
}
|
||||
|
||||
// func(*echo.Context)
|
||||
e.Get("/3", func(c *Context) {
|
||||
c.String(http.StatusOK, "3")
|
||||
})
|
||||
// http.Handler/http.HandlerFunc
|
||||
e.Get("/3", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("3"))
|
||||
}))
|
||||
w = httptest.NewRecorder()
|
||||
r, _ = http.NewRequest(GET, "/3", nil)
|
||||
e.ServeHTTP(w, r)
|
||||
@ -162,48 +151,26 @@ func TestEchoHandler(t *testing.T) {
|
||||
t.Error("body should be 3")
|
||||
}
|
||||
|
||||
// http.Handler/http.HandlerFunc
|
||||
e.Get("/4", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// func(http.ResponseWriter, *http.Request)
|
||||
e.Get("/4", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("4"))
|
||||
}))
|
||||
})
|
||||
w = httptest.NewRecorder()
|
||||
r, _ = http.NewRequest(GET, "/4", nil)
|
||||
e.ServeHTTP(w, r)
|
||||
if w.Body.String() != "4" {
|
||||
t.Error("body should be 4")
|
||||
}
|
||||
|
||||
// func(http.ResponseWriter, *http.Request)
|
||||
e.Get("/5", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("5"))
|
||||
})
|
||||
w = httptest.NewRecorder()
|
||||
r, _ = http.NewRequest(GET, "/5", nil)
|
||||
e.ServeHTTP(w, r)
|
||||
if w.Body.String() != "5" {
|
||||
t.Error("body should be 5")
|
||||
}
|
||||
|
||||
// func(http.ResponseWriter, *http.Request) *HTTPError
|
||||
e.Get("/6", func(w http.ResponseWriter, r *http.Request) *HTTPError {
|
||||
w.Write([]byte("6"))
|
||||
return nil
|
||||
})
|
||||
w = httptest.NewRecorder()
|
||||
r, _ = http.NewRequest(GET, "/6", nil)
|
||||
e.ServeHTTP(w, r)
|
||||
if w.Body.String() != "6" {
|
||||
t.Error("body should be 6")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEchoGroup(t *testing.T) {
|
||||
b := new(bytes.Buffer)
|
||||
e := New()
|
||||
e.Use(func(*Context) {
|
||||
e.Use(func(*Context) *HTTPError {
|
||||
b.WriteString("1")
|
||||
return nil
|
||||
})
|
||||
e.Get("/users", func(*Context) {})
|
||||
e.Get("/users", func(*Context) *HTTPError { return nil })
|
||||
w := httptest.NewRecorder()
|
||||
r, _ := http.NewRequest(GET, "/users", nil)
|
||||
e.ServeHTTP(w, r)
|
||||
@ -213,10 +180,11 @@ func TestEchoGroup(t *testing.T) {
|
||||
|
||||
// Group
|
||||
g1 := e.Group("/group1")
|
||||
g1.Use(func(*Context) {
|
||||
g1.Use(func(*Context) *HTTPError {
|
||||
b.WriteString("2")
|
||||
return nil
|
||||
})
|
||||
g1.Get("/home", func(*Context) {})
|
||||
g1.Get("/home", func(*Context) *HTTPError { return nil })
|
||||
b.Reset()
|
||||
w = httptest.NewRecorder()
|
||||
r, _ = http.NewRequest(GET, "/group1/home", nil)
|
||||
@ -226,10 +194,11 @@ func TestEchoGroup(t *testing.T) {
|
||||
}
|
||||
|
||||
// Group with no parent middleware
|
||||
g2 := e.Group("/group2", func(*Context) {
|
||||
g2 := e.Group("/group2", func(*Context) *HTTPError {
|
||||
b.WriteString("3")
|
||||
return nil
|
||||
})
|
||||
g2.Get("/home", func(*Context) {})
|
||||
g2.Get("/home", func(*Context) *HTTPError { return nil })
|
||||
b.Reset()
|
||||
w = httptest.NewRecorder()
|
||||
r, _ = http.NewRequest(GET, "/group2/home", nil)
|
||||
@ -241,8 +210,8 @@ func TestEchoGroup(t *testing.T) {
|
||||
// Nested group
|
||||
g3 := e.Group("/group3")
|
||||
g4 := g3.Group("/group4")
|
||||
g4.Get("/home", func(c *Context) {
|
||||
c.NoContent(http.StatusOK)
|
||||
g4.Get("/home", func(c *Context) *HTTPError {
|
||||
return c.NoContent(http.StatusOK)
|
||||
})
|
||||
w = httptest.NewRecorder()
|
||||
r, _ = http.NewRequest(GET, "/group3/group4/home", nil)
|
||||
@ -254,7 +223,7 @@ func TestEchoGroup(t *testing.T) {
|
||||
|
||||
func TestEchoMethod(t *testing.T) {
|
||||
e := New()
|
||||
h := func(*Context) {}
|
||||
h := func(*Context) *HTTPError { return nil }
|
||||
e.Connect("/", h)
|
||||
e.Delete("/", h)
|
||||
e.Get("/", h)
|
||||
@ -268,9 +237,9 @@ func TestEchoMethod(t *testing.T) {
|
||||
|
||||
func TestEchoURL(t *testing.T) {
|
||||
e := New()
|
||||
static := func(*Context) {}
|
||||
getUser := func(*Context) {}
|
||||
getFile := func(*Context) {}
|
||||
static := func(*Context) *HTTPError { return nil }
|
||||
getUser := func(*Context) *HTTPError { return nil }
|
||||
getFile := func(*Context) *HTTPError { return nil }
|
||||
e.Get("/static/file", static)
|
||||
e.Get("/users/:id", getUser)
|
||||
e.Get("/users/:uid/files/:fid", getFile)
|
||||
@ -307,8 +276,8 @@ func TestEchoNotFound(t *testing.T) {
|
||||
}
|
||||
|
||||
// Customized NotFound handler
|
||||
e.NotFoundHandler(func(c *Context) {
|
||||
c.String(http.StatusNotFound, "not found")
|
||||
e.NotFoundHandler(func(c *Context) *HTTPError {
|
||||
return c.String(http.StatusNotFound, "not found")
|
||||
})
|
||||
w = httptest.NewRecorder()
|
||||
e.ServeHTTP(w, r)
|
||||
|
@ -15,21 +15,18 @@ Echo is a fast HTTP router (zero memory allocation) and micro web framework in G
|
||||
- Middleware
|
||||
- `echo.MiddlewareFunc`
|
||||
- `func(echo.HandlerFunc) echo.HandlerFunc`
|
||||
- `echo.HandlerFunc`
|
||||
- `func(*echo.Context) *echo.HTTPError`
|
||||
- `func(*echo.Context)`
|
||||
- `func(http.Handler) http.Handler`
|
||||
- `http.Handler`
|
||||
- `http.HandlerFunc`
|
||||
- `func(http.ResponseWriter, *http.Request)`
|
||||
- `func(http.ResponseWriter, *http.Request) *echo.HTTPError`
|
||||
- Handler
|
||||
- `echo.HandlerFunc`
|
||||
- `func(*echo.Context) *echo.HTTPError`
|
||||
- `func(*echo.Context)`
|
||||
- `http.Handler`
|
||||
- `http.HandlerFunc`
|
||||
- `func(http.ResponseWriter, *http.Request)`
|
||||
- `func(http.ResponseWriter, *http.Request) *echo.HTTPError`
|
||||
- Sub routing with groups.
|
||||
- Handy encoding/decoding functions.
|
||||
- Serve static files, including index.
|
||||
|
Loading…
Reference in New Issue
Block a user