mirror of
https://github.com/labstack/echo.git
synced 2025-06-06 23:46:16 +02:00
parent
be5148ae27
commit
b5d6c05101
13
README.md
13
README.md
@ -50,13 +50,6 @@ import (
|
|||||||
"github.com/labstack/echo/middleware"
|
"github.com/labstack/echo/middleware"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Handler
|
|
||||||
func hello() echo.HandlerFunc {
|
|
||||||
return func(c echo.Context) error {
|
|
||||||
return c.String(http.StatusOK, "Hello, World!\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Echo instance
|
// Echo instance
|
||||||
e := echo.New()
|
e := echo.New()
|
||||||
@ -65,8 +58,10 @@ func main() {
|
|||||||
e.Use(middleware.Logger())
|
e.Use(middleware.Logger())
|
||||||
e.Use(middleware.Recover())
|
e.Use(middleware.Recover())
|
||||||
|
|
||||||
// Routes
|
// Route => handler
|
||||||
e.Get("/", hello())
|
e.Get("/", func(c echo.Context) error {
|
||||||
|
return c.String(http.StatusOK, "Hello, World!\n")
|
||||||
|
})
|
||||||
|
|
||||||
// Start server
|
// Start server
|
||||||
e.Run(standard.New(":1323"))
|
e.Run(standard.New(":1323"))
|
||||||
|
@ -156,7 +156,7 @@ type (
|
|||||||
pvalues []string
|
pvalues []string
|
||||||
query url.Values
|
query url.Values
|
||||||
store store
|
store store
|
||||||
handler Handler
|
handler HandlerFunc
|
||||||
echo *Echo
|
echo *Echo
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +204,7 @@ func (c *context) Value(key interface{}) interface{} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) Handle(ctx Context) error {
|
func (c *context) Handle(ctx Context) error {
|
||||||
return c.handler.Handle(ctx)
|
return c.handler(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) Request() engine.Request {
|
func (c *context) Request() engine.Request {
|
||||||
|
124
echo.go
124
echo.go
@ -62,9 +62,9 @@ type (
|
|||||||
// Echo is the top-level framework instance.
|
// Echo is the top-level framework instance.
|
||||||
Echo struct {
|
Echo struct {
|
||||||
prefix string
|
prefix string
|
||||||
middleware []Middleware
|
middleware []MiddlewareFunc
|
||||||
head Handler
|
head HandlerFunc
|
||||||
pristineHead Handler
|
pristineHead HandlerFunc
|
||||||
maxParam *int
|
maxParam *int
|
||||||
notFoundHandler HandlerFunc
|
notFoundHandler HandlerFunc
|
||||||
httpErrorHandler HTTPErrorHandler
|
httpErrorHandler HTTPErrorHandler
|
||||||
@ -89,24 +89,10 @@ type (
|
|||||||
Message string
|
Message string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Middleware defines an interface for middleware via `Handle(Handler) Handler`
|
// MiddlewareFunc defines a function to process middleware.
|
||||||
// function.
|
MiddlewareFunc func(HandlerFunc) HandlerFunc
|
||||||
Middleware interface {
|
|
||||||
Handle(Handler) Handler
|
|
||||||
}
|
|
||||||
|
|
||||||
// MiddlewareFunc is an adapter to allow the use of `func(Handler) Handler` as
|
// HandlerFunc defines a function to server HTTP requests.
|
||||||
// middleware.
|
|
||||||
MiddlewareFunc func(Handler) Handler
|
|
||||||
|
|
||||||
// Handler defines an interface to server HTTP requests via `Handle(Context)`
|
|
||||||
// function.
|
|
||||||
Handler interface {
|
|
||||||
Handle(Context) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandlerFunc is an adapter to allow the use of `func(Context)` as an HTTP
|
|
||||||
// handler.
|
|
||||||
HandlerFunc func(Context) error
|
HandlerFunc func(Context) error
|
||||||
|
|
||||||
// HTTPErrorHandler is a centralized HTTP error handler.
|
// HTTPErrorHandler is a centralized HTTP error handler.
|
||||||
@ -212,13 +198,13 @@ var (
|
|||||||
|
|
||||||
// Error handlers
|
// Error handlers
|
||||||
var (
|
var (
|
||||||
notFoundHandler = HandlerFunc(func(c Context) error {
|
notFoundHandler = func(c Context) error {
|
||||||
return ErrNotFound
|
return ErrNotFound
|
||||||
})
|
}
|
||||||
|
|
||||||
methodNotAllowedHandler = HandlerFunc(func(c Context) error {
|
methodNotAllowedHandler = func(c Context) error {
|
||||||
return ErrMethodNotAllowed
|
return ErrMethodNotAllowed
|
||||||
})
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// New creates an instance of Echo.
|
// New creates an instance of Echo.
|
||||||
@ -228,10 +214,10 @@ func New() (e *Echo) {
|
|||||||
return NewContext(nil, nil, e)
|
return NewContext(nil, nil, e)
|
||||||
}
|
}
|
||||||
e.router = NewRouter(e)
|
e.router = NewRouter(e)
|
||||||
e.middleware = []Middleware{e.router}
|
e.middleware = []MiddlewareFunc{e.router.Process}
|
||||||
e.head = HandlerFunc(func(c Context) error {
|
e.head = func(c Context) error {
|
||||||
return c.Handle(c)
|
return c.Handle(c)
|
||||||
})
|
}
|
||||||
e.pristineHead = e.head
|
e.pristineHead = e.head
|
||||||
e.chainMiddleware()
|
e.chainMiddleware()
|
||||||
|
|
||||||
@ -244,16 +230,6 @@ func New() (e *Echo) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle chains middleware.
|
|
||||||
func (f MiddlewareFunc) Handle(h Handler) Handler {
|
|
||||||
return f(h)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle serves HTTP request.
|
|
||||||
func (f HandlerFunc) Handle(c Context) error {
|
|
||||||
return f(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Router returns router.
|
// Router returns router.
|
||||||
func (e *Echo) Router() *Router {
|
func (e *Echo) Router() *Router {
|
||||||
return e.router
|
return e.router
|
||||||
@ -323,13 +299,13 @@ func (e *Echo) Debug() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pre adds middleware to the chain which is run before router.
|
// Pre adds middleware to the chain which is run before router.
|
||||||
func (e *Echo) Pre(middleware ...Middleware) {
|
func (e *Echo) Pre(middleware ...MiddlewareFunc) {
|
||||||
e.middleware = append(middleware, e.middleware...)
|
e.middleware = append(middleware, e.middleware...)
|
||||||
e.chainMiddleware()
|
e.chainMiddleware()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use adds middleware to the chain which is run after router.
|
// Use adds middleware to the chain which is run after router.
|
||||||
func (e *Echo) Use(middleware ...Middleware) {
|
func (e *Echo) Use(middleware ...MiddlewareFunc) {
|
||||||
e.middleware = append(e.middleware, middleware...)
|
e.middleware = append(e.middleware, middleware...)
|
||||||
e.chainMiddleware()
|
e.chainMiddleware()
|
||||||
}
|
}
|
||||||
@ -337,67 +313,67 @@ func (e *Echo) Use(middleware ...Middleware) {
|
|||||||
func (e *Echo) chainMiddleware() {
|
func (e *Echo) chainMiddleware() {
|
||||||
e.head = e.pristineHead
|
e.head = e.pristineHead
|
||||||
for i := len(e.middleware) - 1; i >= 0; i-- {
|
for i := len(e.middleware) - 1; i >= 0; i-- {
|
||||||
e.head = e.middleware[i].Handle(e.head)
|
e.head = e.middleware[i](e.head)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect registers a new CONNECT route for a path with matching handler in the
|
// Connect registers a new CONNECT route for a path with matching handler in the
|
||||||
// router with optional route-level middleware.
|
// router with optional route-level middleware.
|
||||||
func (e *Echo) Connect(path string, h Handler, m ...Middleware) {
|
func (e *Echo) Connect(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||||
e.add(CONNECT, path, h, m...)
|
e.add(CONNECT, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete registers a new DELETE route for a path with matching handler in the router
|
// Delete registers a new DELETE route for a path with matching handler in the router
|
||||||
// with optional route-level middleware.
|
// with optional route-level middleware.
|
||||||
func (e *Echo) Delete(path string, h Handler, m ...Middleware) {
|
func (e *Echo) Delete(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||||
e.add(DELETE, path, h, m...)
|
e.add(DELETE, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get registers a new GET route for a path with matching handler in the router
|
// Get registers a new GET route for a path with matching handler in the router
|
||||||
// with optional route-level middleware.
|
// with optional route-level middleware.
|
||||||
func (e *Echo) Get(path string, h Handler, m ...Middleware) {
|
func (e *Echo) Get(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||||
e.add(GET, path, h, m...)
|
e.add(GET, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Head registers a new HEAD route for a path with matching handler in the
|
// Head registers a new HEAD route for a path with matching handler in the
|
||||||
// router with optional route-level middleware.
|
// router with optional route-level middleware.
|
||||||
func (e *Echo) Head(path string, h Handler, m ...Middleware) {
|
func (e *Echo) Head(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||||
e.add(HEAD, path, h, m...)
|
e.add(HEAD, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Options registers a new OPTIONS route for a path with matching handler in the
|
// Options registers a new OPTIONS route for a path with matching handler in the
|
||||||
// router with optional route-level middleware.
|
// router with optional route-level middleware.
|
||||||
func (e *Echo) Options(path string, h Handler, m ...Middleware) {
|
func (e *Echo) Options(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||||
e.add(OPTIONS, path, h, m...)
|
e.add(OPTIONS, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Patch registers a new PATCH route for a path with matching handler in the
|
// Patch registers a new PATCH route for a path with matching handler in the
|
||||||
// router with optional route-level middleware.
|
// router with optional route-level middleware.
|
||||||
func (e *Echo) Patch(path string, h Handler, m ...Middleware) {
|
func (e *Echo) Patch(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||||
e.add(PATCH, path, h, m...)
|
e.add(PATCH, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Post registers a new POST route for a path with matching handler in the
|
// Post registers a new POST route for a path with matching handler in the
|
||||||
// router with optional route-level middleware.
|
// router with optional route-level middleware.
|
||||||
func (e *Echo) Post(path string, h Handler, m ...Middleware) {
|
func (e *Echo) Post(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||||
e.add(POST, path, h, m...)
|
e.add(POST, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put registers a new PUT route for a path with matching handler in the
|
// Put registers a new PUT route for a path with matching handler in the
|
||||||
// router with optional route-level middleware.
|
// router with optional route-level middleware.
|
||||||
func (e *Echo) Put(path string, h Handler, m ...Middleware) {
|
func (e *Echo) Put(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||||
e.add(PUT, path, h, m...)
|
e.add(PUT, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trace registers a new TRACE route for a path with matching handler in the
|
// Trace registers a new TRACE route for a path with matching handler in the
|
||||||
// router with optional route-level middleware.
|
// router with optional route-level middleware.
|
||||||
func (e *Echo) Trace(path string, h Handler, m ...Middleware) {
|
func (e *Echo) Trace(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||||
e.add(TRACE, path, h, m...)
|
e.add(TRACE, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Any registers a new route for all HTTP methods and path with matching handler
|
// Any registers a new route for all HTTP methods and path with matching handler
|
||||||
// in the router with optional route-level middleware.
|
// in the router with optional route-level middleware.
|
||||||
func (e *Echo) Any(path string, handler Handler, middleware ...Middleware) {
|
func (e *Echo) Any(path string, handler HandlerFunc, middleware ...MiddlewareFunc) {
|
||||||
for _, m := range methods {
|
for _, m := range methods {
|
||||||
e.add(m, path, handler, middleware...)
|
e.add(m, path, handler, middleware...)
|
||||||
}
|
}
|
||||||
@ -405,7 +381,7 @@ func (e *Echo) Any(path string, handler Handler, middleware ...Middleware) {
|
|||||||
|
|
||||||
// Match registers a new route for multiple HTTP methods and path with matching
|
// Match registers a new route for multiple HTTP methods and path with matching
|
||||||
// handler in the router with optional route-level middleware.
|
// handler in the router with optional route-level middleware.
|
||||||
func (e *Echo) Match(methods []string, path string, handler Handler, middleware ...Middleware) {
|
func (e *Echo) Match(methods []string, path string, handler HandlerFunc, middleware ...MiddlewareFunc) {
|
||||||
for _, m := range methods {
|
for _, m := range methods {
|
||||||
e.add(m, path, handler, middleware...)
|
e.add(m, path, handler, middleware...)
|
||||||
}
|
}
|
||||||
@ -413,28 +389,28 @@ func (e *Echo) Match(methods []string, path string, handler Handler, middleware
|
|||||||
|
|
||||||
// Static serves files from provided `root` directory for `/<prefix>*` HTTP path.
|
// Static serves files from provided `root` directory for `/<prefix>*` HTTP path.
|
||||||
func (e *Echo) Static(prefix, root string) {
|
func (e *Echo) Static(prefix, root string) {
|
||||||
e.Get(prefix+"*", HandlerFunc(func(c Context) error {
|
e.Get(prefix+"*", func(c Context) error {
|
||||||
return c.File(path.Join(root, c.P(0))) // Param `_`
|
return c.File(path.Join(root, c.P(0))) // Param `_`
|
||||||
}))
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// File serves provided file for `/<path>` HTTP path.
|
// File serves provided file for `/<path>` HTTP path.
|
||||||
func (e *Echo) File(path, file string) {
|
func (e *Echo) File(path, file string) {
|
||||||
e.Get(path, HandlerFunc(func(c Context) error {
|
e.Get(path, func(c Context) error {
|
||||||
return c.File(file)
|
return c.File(file)
|
||||||
}))
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Echo) add(method, path string, handler Handler, middleware ...Middleware) {
|
func (e *Echo) add(method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) {
|
||||||
name := handlerName(handler)
|
name := handlerName(handler)
|
||||||
e.router.Add(method, path, HandlerFunc(func(c Context) error {
|
e.router.Add(method, path, func(c Context) error {
|
||||||
h := handler
|
h := handler
|
||||||
// Chain middleware
|
// Chain middleware
|
||||||
for i := len(middleware) - 1; i >= 0; i-- {
|
for i := len(middleware) - 1; i >= 0; i-- {
|
||||||
h = middleware[i].Handle(h)
|
h = middleware[i](h)
|
||||||
}
|
}
|
||||||
return h.Handle(c)
|
return h(c)
|
||||||
}), e)
|
}, e)
|
||||||
r := Route{
|
r := Route{
|
||||||
Method: method,
|
Method: method,
|
||||||
Path: path,
|
Path: path,
|
||||||
@ -444,18 +420,18 @@ func (e *Echo) add(method, path string, handler Handler, middleware ...Middlewar
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Group creates a new router group with prefix and optional group-level middleware.
|
// Group creates a new router group with prefix and optional group-level middleware.
|
||||||
func (e *Echo) Group(prefix string, m ...Middleware) (g *Group) {
|
func (e *Echo) Group(prefix string, m ...MiddlewareFunc) (g *Group) {
|
||||||
g = &Group{prefix: prefix, echo: e}
|
g = &Group{prefix: prefix, echo: e}
|
||||||
g.Use(m...)
|
g.Use(m...)
|
||||||
// Dummy handler so group can be used with static middleware.
|
// Dummy handler so group can be used with static middleware.
|
||||||
g.Get("", HandlerFunc(func(c Context) error {
|
g.Get("", func(c Context) error {
|
||||||
return c.NoContent(http.StatusNotFound)
|
return c.NoContent(http.StatusNotFound)
|
||||||
}))
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// URI generates a URI from handler.
|
// URI generates a URI from handler.
|
||||||
func (e *Echo) URI(handler Handler, params ...interface{}) string {
|
func (e *Echo) URI(handler HandlerFunc, params ...interface{}) string {
|
||||||
uri := new(bytes.Buffer)
|
uri := new(bytes.Buffer)
|
||||||
ln := len(params)
|
ln := len(params)
|
||||||
n := 0
|
n := 0
|
||||||
@ -480,7 +456,7 @@ func (e *Echo) URI(handler Handler, params ...interface{}) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// URL is an alias for `URI` function.
|
// URL is an alias for `URI` function.
|
||||||
func (e *Echo) URL(h Handler, params ...interface{}) string {
|
func (e *Echo) URL(h HandlerFunc, params ...interface{}) string {
|
||||||
return e.URI(h, params...)
|
return e.URI(h, params...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,7 +482,7 @@ func (e *Echo) ServeHTTP(rq engine.Request, rs engine.Response) {
|
|||||||
c.Reset(rq, rs)
|
c.Reset(rq, rs)
|
||||||
|
|
||||||
// Execute chain
|
// Execute chain
|
||||||
if err := e.head.Handle(c); err != nil {
|
if err := e.head(c); err != nil {
|
||||||
e.httpErrorHandler(err, c)
|
e.httpErrorHandler(err, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -551,19 +527,19 @@ func (binder) Bind(i interface{}, c Context) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// WrapMiddleware wrap `echo.Handler` into `echo.MiddlewareFunc`.
|
// WrapMiddleware wrap `echo.HandlerFunc` into `echo.MiddlewareFunc`.
|
||||||
func WrapMiddleware(h Handler) MiddlewareFunc {
|
func WrapMiddleware(h HandlerFunc) MiddlewareFunc {
|
||||||
return func(next Handler) Handler {
|
return func(next HandlerFunc) HandlerFunc {
|
||||||
return HandlerFunc(func(c Context) error {
|
return func(c Context) error {
|
||||||
if err := h.Handle(c); err != nil {
|
if err := h(c); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return next.Handle(c)
|
return next(c)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handlerName(h Handler) string {
|
func handlerName(h HandlerFunc) string {
|
||||||
t := reflect.ValueOf(h).Type()
|
t := reflect.ValueOf(h).Type()
|
||||||
if t.Kind() == reflect.Func {
|
if t.Kind() == reflect.Func {
|
||||||
return runtime.FuncForPC(reflect.ValueOf(h).Pointer()).Name()
|
return runtime.FuncForPC(reflect.ValueOf(h).Pointer()).Name()
|
||||||
|
81
echo_test.go
81
echo_test.go
@ -83,31 +83,31 @@ func TestEchoMiddleware(t *testing.T) {
|
|||||||
e := New()
|
e := New()
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
|
|
||||||
e.Pre(WrapMiddleware(HandlerFunc(func(c Context) error {
|
e.Pre(WrapMiddleware(func(c Context) error {
|
||||||
assert.Empty(t, c.Path())
|
assert.Empty(t, c.Path())
|
||||||
buf.WriteString("-1")
|
buf.WriteString("-1")
|
||||||
return nil
|
return nil
|
||||||
})))
|
}))
|
||||||
|
|
||||||
e.Use(WrapMiddleware(HandlerFunc(func(c Context) error {
|
e.Use(WrapMiddleware(func(c Context) error {
|
||||||
buf.WriteString("1")
|
buf.WriteString("1")
|
||||||
return nil
|
return nil
|
||||||
})))
|
}))
|
||||||
|
|
||||||
e.Use(WrapMiddleware(HandlerFunc(func(c Context) error {
|
e.Use(WrapMiddleware(func(c Context) error {
|
||||||
buf.WriteString("2")
|
buf.WriteString("2")
|
||||||
return nil
|
return nil
|
||||||
})))
|
}))
|
||||||
|
|
||||||
e.Use(WrapMiddleware(HandlerFunc(func(c Context) error {
|
e.Use(WrapMiddleware(func(c Context) error {
|
||||||
buf.WriteString("3")
|
buf.WriteString("3")
|
||||||
return nil
|
return nil
|
||||||
})))
|
}))
|
||||||
|
|
||||||
// Route
|
// Route
|
||||||
e.Get("/", HandlerFunc(func(c Context) error {
|
e.Get("/", func(c Context) error {
|
||||||
return c.String(http.StatusOK, "OK")
|
return c.String(http.StatusOK, "OK")
|
||||||
}))
|
})
|
||||||
|
|
||||||
c, b := request(GET, "/", e)
|
c, b := request(GET, "/", e)
|
||||||
assert.Equal(t, "-1123", buf.String())
|
assert.Equal(t, "-1123", buf.String())
|
||||||
@ -117,9 +117,9 @@ func TestEchoMiddleware(t *testing.T) {
|
|||||||
|
|
||||||
func TestEchoMiddlewareError(t *testing.T) {
|
func TestEchoMiddlewareError(t *testing.T) {
|
||||||
e := New()
|
e := New()
|
||||||
e.Use(WrapMiddleware(HandlerFunc(func(c Context) error {
|
e.Use(WrapMiddleware(func(c Context) error {
|
||||||
return errors.New("error")
|
return errors.New("error")
|
||||||
})))
|
}))
|
||||||
e.Get("/", notFoundHandler)
|
e.Get("/", notFoundHandler)
|
||||||
c, _ := request(GET, "/", e)
|
c, _ := request(GET, "/", e)
|
||||||
assert.Equal(t, http.StatusInternalServerError, c)
|
assert.Equal(t, http.StatusInternalServerError, c)
|
||||||
@ -129,9 +129,9 @@ func TestEchoHandler(t *testing.T) {
|
|||||||
e := New()
|
e := New()
|
||||||
|
|
||||||
// HandlerFunc
|
// HandlerFunc
|
||||||
e.Get("/ok", HandlerFunc(func(c Context) error {
|
e.Get("/ok", func(c Context) error {
|
||||||
return c.String(http.StatusOK, "OK")
|
return c.String(http.StatusOK, "OK")
|
||||||
}))
|
})
|
||||||
|
|
||||||
c, b := request(GET, "/ok", e)
|
c, b := request(GET, "/ok", e)
|
||||||
assert.Equal(t, http.StatusOK, c)
|
assert.Equal(t, http.StatusOK, c)
|
||||||
@ -185,23 +185,23 @@ func TestEchoTrace(t *testing.T) {
|
|||||||
|
|
||||||
func TestEchoAny(t *testing.T) { // JFC
|
func TestEchoAny(t *testing.T) { // JFC
|
||||||
e := New()
|
e := New()
|
||||||
e.Any("/", HandlerFunc(func(c Context) error {
|
e.Any("/", func(c Context) error {
|
||||||
return c.String(http.StatusOK, "Any")
|
return c.String(http.StatusOK, "Any")
|
||||||
}))
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEchoMatch(t *testing.T) { // JFC
|
func TestEchoMatch(t *testing.T) { // JFC
|
||||||
e := New()
|
e := New()
|
||||||
e.Match([]string{GET, POST}, "/", HandlerFunc(func(c Context) error {
|
e.Match([]string{GET, POST}, "/", func(c Context) error {
|
||||||
return c.String(http.StatusOK, "Match")
|
return c.String(http.StatusOK, "Match")
|
||||||
}))
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEchoURL(t *testing.T) {
|
func TestEchoURL(t *testing.T) {
|
||||||
e := New()
|
e := New()
|
||||||
static := HandlerFunc(func(Context) error { return nil })
|
static := func(Context) error { return nil }
|
||||||
getUser := HandlerFunc(func(Context) error { return nil })
|
getUser := func(Context) error { return nil }
|
||||||
getFile := HandlerFunc(func(Context) error { return nil })
|
getFile := func(Context) error { return nil }
|
||||||
|
|
||||||
e.Get("/static/file", static)
|
e.Get("/static/file", static)
|
||||||
e.Get("/users/:id", getUser)
|
e.Get("/users/:id", getUser)
|
||||||
@ -224,9 +224,9 @@ func TestEchoRoutes(t *testing.T) {
|
|||||||
{POST, "/repos/:owner/:repo/git/tags", ""},
|
{POST, "/repos/:owner/:repo/git/tags", ""},
|
||||||
}
|
}
|
||||||
for _, r := range routes {
|
for _, r := range routes {
|
||||||
e.add(r.Method, r.Path, HandlerFunc(func(c Context) error {
|
e.add(r.Method, r.Path, func(c Context) error {
|
||||||
return c.String(http.StatusOK, "OK")
|
return c.String(http.StatusOK, "OK")
|
||||||
}))
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, r := range e.Routes() {
|
for i, r := range e.Routes() {
|
||||||
@ -238,15 +238,15 @@ func TestEchoRoutes(t *testing.T) {
|
|||||||
func TestEchoGroup(t *testing.T) {
|
func TestEchoGroup(t *testing.T) {
|
||||||
e := New()
|
e := New()
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
e.Use(MiddlewareFunc(func(h Handler) Handler {
|
e.Use(MiddlewareFunc(func(h HandlerFunc) HandlerFunc {
|
||||||
return HandlerFunc(func(c Context) error {
|
return func(c Context) error {
|
||||||
buf.WriteString("0")
|
buf.WriteString("0")
|
||||||
return h.Handle(c)
|
return h(c)
|
||||||
})
|
}
|
||||||
}))
|
}))
|
||||||
h := HandlerFunc(func(c Context) error {
|
h := func(c Context) error {
|
||||||
return c.NoContent(http.StatusOK)
|
return c.NoContent(http.StatusOK)
|
||||||
})
|
}
|
||||||
|
|
||||||
//--------
|
//--------
|
||||||
// Routes
|
// Routes
|
||||||
@ -256,24 +256,23 @@ func TestEchoGroup(t *testing.T) {
|
|||||||
|
|
||||||
// Group
|
// Group
|
||||||
g1 := e.Group("/group1")
|
g1 := e.Group("/group1")
|
||||||
g1.Use(WrapMiddleware(HandlerFunc(func(c Context) error {
|
g1.Use(WrapMiddleware(func(c Context) error {
|
||||||
buf.WriteString("1")
|
buf.WriteString("1")
|
||||||
return h.Handle(c)
|
return h(c)
|
||||||
|
}))
|
||||||
})))
|
|
||||||
g1.Get("", h)
|
g1.Get("", h)
|
||||||
|
|
||||||
// Nested groups with middleware
|
// Nested groups with middleware
|
||||||
g2 := e.Group("/group2")
|
g2 := e.Group("/group2")
|
||||||
g2.Use(WrapMiddleware(HandlerFunc(func(c Context) error {
|
g2.Use(WrapMiddleware(func(c Context) error {
|
||||||
buf.WriteString("2")
|
buf.WriteString("2")
|
||||||
return nil
|
return nil
|
||||||
})))
|
}))
|
||||||
g3 := g2.Group("/group3")
|
g3 := g2.Group("/group3")
|
||||||
g3.Use(WrapMiddleware(HandlerFunc(func(c Context) error {
|
g3.Use(WrapMiddleware(func(c Context) error {
|
||||||
buf.WriteString("3")
|
buf.WriteString("3")
|
||||||
return nil
|
return nil
|
||||||
})))
|
}))
|
||||||
g3.Get("", h)
|
g3.Get("", h)
|
||||||
|
|
||||||
request(GET, "/users", e)
|
request(GET, "/users", e)
|
||||||
@ -298,9 +297,9 @@ func TestEchoNotFound(t *testing.T) {
|
|||||||
|
|
||||||
func TestEchoMethodNotAllowed(t *testing.T) {
|
func TestEchoMethodNotAllowed(t *testing.T) {
|
||||||
e := New()
|
e := New()
|
||||||
e.Get("/", HandlerFunc(func(c Context) error {
|
e.Get("/", func(c Context) error {
|
||||||
return c.String(http.StatusOK, "Echo!")
|
return c.String(http.StatusOK, "Echo!")
|
||||||
}))
|
})
|
||||||
rq := test.NewRequest(POST, "/", nil)
|
rq := test.NewRequest(POST, "/", nil)
|
||||||
rec := test.NewResponseRecorder()
|
rec := test.NewResponseRecorder()
|
||||||
e.ServeHTTP(rq, rec)
|
e.ServeHTTP(rq, rec)
|
||||||
@ -317,9 +316,9 @@ func TestEchoHTTPError(t *testing.T) {
|
|||||||
func testMethod(t *testing.T, method, path string, e *Echo) {
|
func testMethod(t *testing.T, method, path string, e *Echo) {
|
||||||
m := fmt.Sprintf("%c%s", method[0], strings.ToLower(method[1:]))
|
m := fmt.Sprintf("%c%s", method[0], strings.ToLower(method[1:]))
|
||||||
p := reflect.ValueOf(path)
|
p := reflect.ValueOf(path)
|
||||||
h := reflect.ValueOf(HandlerFunc(func(c Context) error {
|
h := reflect.ValueOf(func(c Context) error {
|
||||||
return c.String(http.StatusOK, method)
|
return c.String(http.StatusOK, method)
|
||||||
}))
|
})
|
||||||
i := interface{}(e)
|
i := interface{}(e)
|
||||||
reflect.ValueOf(i).MethodByName(m).Call([]reflect.Value{p, h})
|
reflect.ValueOf(i).MethodByName(m).Call([]reflect.Value{p, h})
|
||||||
_, body := request(method, path, e)
|
_, body := request(method, path, e)
|
||||||
|
@ -162,15 +162,15 @@ func WrapHandler(h fasthttp.RequestHandler) echo.HandlerFunc {
|
|||||||
|
|
||||||
// WrapMiddleware wraps `fasthttp.RequestHandler` into `echo.MiddlewareFunc`
|
// WrapMiddleware wraps `fasthttp.RequestHandler` into `echo.MiddlewareFunc`
|
||||||
func WrapMiddleware(h fasthttp.RequestHandler) echo.MiddlewareFunc {
|
func WrapMiddleware(h fasthttp.RequestHandler) echo.MiddlewareFunc {
|
||||||
return func(next echo.Handler) echo.Handler {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return echo.HandlerFunc(func(c echo.Context) error {
|
return func(c echo.Context) error {
|
||||||
rq := c.Request().(*Request)
|
rq := c.Request().(*Request)
|
||||||
rs := c.Response().(*Response)
|
rs := c.Response().(*Response)
|
||||||
ctx := rq.RequestCtx
|
ctx := rq.RequestCtx
|
||||||
h(ctx)
|
h(ctx)
|
||||||
rs.status = ctx.Response.StatusCode()
|
rs.status = ctx.Response.StatusCode()
|
||||||
rs.size = int64(ctx.Response.Header.ContentLength())
|
rs.size = int64(ctx.Response.Header.ContentLength())
|
||||||
return next.Handle(c)
|
return next(c)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,14 +156,14 @@ func WrapHandler(h http.Handler) echo.HandlerFunc {
|
|||||||
|
|
||||||
// WrapMiddleware wraps `func(http.Handler) http.Handler` into `echo.MiddlewareFunc`
|
// WrapMiddleware wraps `func(http.Handler) http.Handler` into `echo.MiddlewareFunc`
|
||||||
func WrapMiddleware(m func(http.Handler) http.Handler) echo.MiddlewareFunc {
|
func WrapMiddleware(m func(http.Handler) http.Handler) echo.MiddlewareFunc {
|
||||||
return func(next echo.Handler) echo.Handler {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return echo.HandlerFunc(func(c echo.Context) (err error) {
|
return func(c echo.Context) (err error) {
|
||||||
rq := c.Request().(*Request)
|
rq := c.Request().(*Request)
|
||||||
rs := c.Response().(*Response)
|
rs := c.Response().(*Response)
|
||||||
m(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
m(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
err = next.Handle(c)
|
err = next(c)
|
||||||
})).ServeHTTP(rs.ResponseWriter, rq.Request)
|
})).ServeHTTP(rs.ResponseWriter, rq.Request)
|
||||||
return
|
return
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
glide.lock
generated
10
glide.lock
generated
@ -1,5 +1,5 @@
|
|||||||
hash: 44dfc8aaffca5078e71afdb209a0ef0a359a35f69fb98c7b6a2fb87a5a70e757
|
hash: 44dfc8aaffca5078e71afdb209a0ef0a359a35f69fb98c7b6a2fb87a5a70e757
|
||||||
updated: 2016-04-01T08:48:26.453457926-07:00
|
updated: 2016-04-02T13:40:33.226488832-07:00
|
||||||
imports:
|
imports:
|
||||||
- name: github.com/klauspost/compress
|
- name: github.com/klauspost/compress
|
||||||
version: 9d711f4445beb7f6488148ce04e3b4dc6e72242d
|
version: 9d711f4445beb7f6488148ce04e3b4dc6e72242d
|
||||||
@ -11,10 +11,6 @@ imports:
|
|||||||
version: 09cded8978dc9e80714c4d85b0322337b0a1e5e0
|
version: 09cded8978dc9e80714c4d85b0322337b0a1e5e0
|
||||||
- name: github.com/klauspost/crc32
|
- name: github.com/klauspost/crc32
|
||||||
version: 19b0b332c9e4516a6370a0456e6182c3b5036720
|
version: 19b0b332c9e4516a6370a0456e6182c3b5036720
|
||||||
- name: github.com/labstack/echo
|
|
||||||
version: 11134134413a234260d4e9c501803c3cc6c874d1
|
|
||||||
subpackages:
|
|
||||||
- engine
|
|
||||||
- name: github.com/labstack/gommon
|
- name: github.com/labstack/gommon
|
||||||
version: f4ba73f8bcf88df1524069c117f7878cf530ee4e
|
version: f4ba73f8bcf88df1524069c117f7878cf530ee4e
|
||||||
subpackages:
|
subpackages:
|
||||||
@ -29,7 +25,7 @@ imports:
|
|||||||
subpackages:
|
subpackages:
|
||||||
- assert
|
- assert
|
||||||
- name: github.com/valyala/fasthttp
|
- name: github.com/valyala/fasthttp
|
||||||
version: ca21b21eba267eac4489fb6b42260129727c4a1b
|
version: 8ae2d3e53c26ff32a2da8ad0c974b29cea0b0c7d
|
||||||
- name: github.com/valyala/fasttemplate
|
- name: github.com/valyala/fasttemplate
|
||||||
version: 3b874956e03f1636d171bda64b130f9135f42cff
|
version: 3b874956e03f1636d171bda64b130f9135f42cff
|
||||||
- name: golang.org/x/net
|
- name: golang.org/x/net
|
||||||
@ -38,7 +34,7 @@ imports:
|
|||||||
- context
|
- context
|
||||||
- websocket
|
- websocket
|
||||||
- name: golang.org/x/sys
|
- name: golang.org/x/sys
|
||||||
version: 320cb01ddbbf0473674c2585f9b6e245721de355
|
version: a60af9cbbc6ab800af4f2be864a31f423a0ae1f2
|
||||||
subpackages:
|
subpackages:
|
||||||
- unix
|
- unix
|
||||||
devImports: []
|
devImports: []
|
||||||
|
38
group.go
38
group.go
@ -6,94 +6,94 @@ type (
|
|||||||
// from the parent echo instance while still inheriting from it.
|
// from the parent echo instance while still inheriting from it.
|
||||||
Group struct {
|
Group struct {
|
||||||
prefix string
|
prefix string
|
||||||
middleware []Middleware
|
middleware []MiddlewareFunc
|
||||||
echo *Echo
|
echo *Echo
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Use implements `Echo#Use()` for sub-routes within the Group.
|
// Use implements `Echo#Use()` for sub-routes within the Group.
|
||||||
func (g *Group) Use(m ...Middleware) {
|
func (g *Group) Use(m ...MiddlewareFunc) {
|
||||||
g.middleware = append(g.middleware, m...)
|
g.middleware = append(g.middleware, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect implements `Echo#Connect()` for sub-routes within the Group.
|
// Connect implements `Echo#Connect()` for sub-routes within the Group.
|
||||||
func (g *Group) Connect(path string, h Handler, m ...Middleware) {
|
func (g *Group) Connect(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||||
g.add(CONNECT, path, h, m...)
|
g.add(CONNECT, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete implements `Echo#Delete()` for sub-routes within the Group.
|
// Delete implements `Echo#Delete()` for sub-routes within the Group.
|
||||||
func (g *Group) Delete(path string, h Handler, m ...Middleware) {
|
func (g *Group) Delete(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||||
g.add(DELETE, path, h, m...)
|
g.add(DELETE, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get implements `Echo#Get()` for sub-routes within the Group.
|
// Get implements `Echo#Get()` for sub-routes within the Group.
|
||||||
func (g *Group) Get(path string, h Handler, m ...Middleware) {
|
func (g *Group) Get(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||||
g.add(GET, path, h, m...)
|
g.add(GET, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Head implements `Echo#Head()` for sub-routes within the Group.
|
// Head implements `Echo#Head()` for sub-routes within the Group.
|
||||||
func (g *Group) Head(path string, h Handler, m ...Middleware) {
|
func (g *Group) Head(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||||
g.add(HEAD, path, h, m...)
|
g.add(HEAD, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Options implements `Echo#Options()` for sub-routes within the Group.
|
// Options implements `Echo#Options()` for sub-routes within the Group.
|
||||||
func (g *Group) Options(path string, h Handler, m ...Middleware) {
|
func (g *Group) Options(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||||
g.add(OPTIONS, path, h, m...)
|
g.add(OPTIONS, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Patch implements `Echo#Patch()` for sub-routes within the Group.
|
// Patch implements `Echo#Patch()` for sub-routes within the Group.
|
||||||
func (g *Group) Patch(path string, h Handler, m ...Middleware) {
|
func (g *Group) Patch(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||||
g.add(PATCH, path, h, m...)
|
g.add(PATCH, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Post implements `Echo#Post()` for sub-routes within the Group.
|
// Post implements `Echo#Post()` for sub-routes within the Group.
|
||||||
func (g *Group) Post(path string, h Handler, m ...Middleware) {
|
func (g *Group) Post(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||||
g.add(POST, path, h, m...)
|
g.add(POST, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put implements `Echo#Put()` for sub-routes within the Group.
|
// Put implements `Echo#Put()` for sub-routes within the Group.
|
||||||
func (g *Group) Put(path string, h Handler, m ...Middleware) {
|
func (g *Group) Put(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||||
g.add(PUT, path, h, m...)
|
g.add(PUT, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trace implements `Echo#Trace()` for sub-routes within the Group.
|
// Trace implements `Echo#Trace()` for sub-routes within the Group.
|
||||||
func (g *Group) Trace(path string, h Handler, m ...Middleware) {
|
func (g *Group) Trace(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||||
g.add(TRACE, path, h, m...)
|
g.add(TRACE, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Any implements `Echo#Any()` for sub-routes within the Group.
|
// Any implements `Echo#Any()` for sub-routes within the Group.
|
||||||
func (g *Group) Any(path string, handler Handler, middleware ...Middleware) {
|
func (g *Group) Any(path string, handler HandlerFunc, middleware ...MiddlewareFunc) {
|
||||||
for _, m := range methods {
|
for _, m := range methods {
|
||||||
g.add(m, path, handler, middleware...)
|
g.add(m, path, handler, middleware...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Match implements `Echo#Match()` for sub-routes within the Group.
|
// Match implements `Echo#Match()` for sub-routes within the Group.
|
||||||
func (g *Group) Match(methods []string, path string, handler Handler, middleware ...Middleware) {
|
func (g *Group) Match(methods []string, path string, handler HandlerFunc, middleware ...MiddlewareFunc) {
|
||||||
for _, m := range methods {
|
for _, m := range methods {
|
||||||
g.add(m, path, handler, middleware...)
|
g.add(m, path, handler, middleware...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group creates a new sub-group with prefix and optional sub-group-level middleware.
|
// Group creates a new sub-group with prefix and optional sub-group-level middleware.
|
||||||
func (g *Group) Group(prefix string, m ...Middleware) *Group {
|
func (g *Group) Group(prefix string, m ...MiddlewareFunc) *Group {
|
||||||
m = append(g.middleware, m...)
|
m = append(g.middleware, m...)
|
||||||
return g.echo.Group(g.prefix+prefix, m...)
|
return g.echo.Group(g.prefix+prefix, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Group) add(method, path string, handler Handler, middleware ...Middleware) {
|
func (g *Group) add(method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) {
|
||||||
path = g.prefix + path
|
path = g.prefix + path
|
||||||
name := handlerName(handler)
|
name := handlerName(handler)
|
||||||
middleware = append(g.middleware, middleware...)
|
middleware = append(g.middleware, middleware...)
|
||||||
|
|
||||||
g.echo.router.Add(method, path, HandlerFunc(func(c Context) error {
|
g.echo.router.Add(method, path, func(c Context) error {
|
||||||
h := handler
|
h := handler
|
||||||
// Chain middleware
|
// Chain middleware
|
||||||
for i := len(middleware) - 1; i >= 0; i-- {
|
for i := len(middleware) - 1; i >= 0; i-- {
|
||||||
h = middleware[i].Handle(h)
|
h = middleware[i](h)
|
||||||
}
|
}
|
||||||
return h.Handle(c)
|
return h(c)
|
||||||
}), g.echo)
|
}, g.echo)
|
||||||
r := Route{
|
r := Route{
|
||||||
Method: method,
|
Method: method,
|
||||||
Path: path,
|
Path: path,
|
||||||
|
@ -4,7 +4,7 @@ import "testing"
|
|||||||
|
|
||||||
func TestGroup(t *testing.T) {
|
func TestGroup(t *testing.T) {
|
||||||
g := New().Group("/group")
|
g := New().Group("/group")
|
||||||
h := HandlerFunc(func(Context) error { return nil })
|
h := func(Context) error { return nil }
|
||||||
g.Connect("/", h)
|
g.Connect("/", h)
|
||||||
g.Delete("/", h)
|
g.Delete("/", h)
|
||||||
g.Get("/", h)
|
g.Get("/", h)
|
||||||
|
@ -39,8 +39,8 @@ func BasicAuth(f BasicAuthFunc) echo.MiddlewareFunc {
|
|||||||
// BasicAuthFromConfig returns an HTTP basic auth middleware from config.
|
// BasicAuthFromConfig returns an HTTP basic auth middleware from config.
|
||||||
// See `BasicAuth()`.
|
// See `BasicAuth()`.
|
||||||
func BasicAuthFromConfig(config BasicAuthConfig) echo.MiddlewareFunc {
|
func BasicAuthFromConfig(config BasicAuthConfig) echo.MiddlewareFunc {
|
||||||
return func(next echo.Handler) echo.Handler {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return echo.HandlerFunc(func(c echo.Context) error {
|
return func(c echo.Context) error {
|
||||||
auth := c.Request().Header().Get(echo.Authorization)
|
auth := c.Request().Header().Get(echo.Authorization)
|
||||||
l := len(basic)
|
l := len(basic)
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ func BasicAuthFromConfig(config BasicAuthConfig) echo.MiddlewareFunc {
|
|||||||
if cred[i] == ':' {
|
if cred[i] == ':' {
|
||||||
// Verify credentials
|
// Verify credentials
|
||||||
if config.AuthFunc(cred[:i], cred[i+1:]) {
|
if config.AuthFunc(cred[:i], cred[i+1:]) {
|
||||||
return next.Handle(c)
|
return next(c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,6 +60,6 @@ func BasicAuthFromConfig(config BasicAuthConfig) echo.MiddlewareFunc {
|
|||||||
}
|
}
|
||||||
c.Response().Header().Set(echo.WWWAuthenticate, basic+" realm=Restricted")
|
c.Response().Header().Set(echo.WWWAuthenticate, basic+" realm=Restricted")
|
||||||
return echo.ErrUnauthorized
|
return echo.ErrUnauthorized
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,14 +21,14 @@ func TestBasicAuth(t *testing.T) {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
h := BasicAuth(f)(echo.HandlerFunc(func(c echo.Context) error {
|
h := BasicAuth(f)(func(c echo.Context) error {
|
||||||
return c.String(http.StatusOK, "test")
|
return c.String(http.StatusOK, "test")
|
||||||
}))
|
})
|
||||||
|
|
||||||
// Valid credentials
|
// Valid credentials
|
||||||
auth := basic + " " + base64.StdEncoding.EncodeToString([]byte("joe:secret"))
|
auth := basic + " " + base64.StdEncoding.EncodeToString([]byte("joe:secret"))
|
||||||
rq.Header().Set(echo.Authorization, auth)
|
rq.Header().Set(echo.Authorization, auth)
|
||||||
assert.NoError(t, h.Handle(c))
|
assert.NoError(t, h(c))
|
||||||
|
|
||||||
//---------------------
|
//---------------------
|
||||||
// Invalid credentials
|
// Invalid credentials
|
||||||
@ -37,20 +37,20 @@ func TestBasicAuth(t *testing.T) {
|
|||||||
// Incorrect password
|
// Incorrect password
|
||||||
auth = basic + " " + base64.StdEncoding.EncodeToString([]byte("joe:password"))
|
auth = basic + " " + base64.StdEncoding.EncodeToString([]byte("joe:password"))
|
||||||
rq.Header().Set(echo.Authorization, auth)
|
rq.Header().Set(echo.Authorization, auth)
|
||||||
he := h.Handle(c).(*echo.HTTPError)
|
he := h(c).(*echo.HTTPError)
|
||||||
assert.Equal(t, http.StatusUnauthorized, he.Code)
|
assert.Equal(t, http.StatusUnauthorized, he.Code)
|
||||||
assert.Equal(t, basic+" realm=Restricted", rs.Header().Get(echo.WWWAuthenticate))
|
assert.Equal(t, basic+" realm=Restricted", rs.Header().Get(echo.WWWAuthenticate))
|
||||||
|
|
||||||
// Empty Authorization header
|
// Empty Authorization header
|
||||||
rq.Header().Set(echo.Authorization, "")
|
rq.Header().Set(echo.Authorization, "")
|
||||||
he = h.Handle(c).(*echo.HTTPError)
|
he = h(c).(*echo.HTTPError)
|
||||||
assert.Equal(t, http.StatusUnauthorized, he.Code)
|
assert.Equal(t, http.StatusUnauthorized, he.Code)
|
||||||
assert.Equal(t, basic+" realm=Restricted", rs.Header().Get(echo.WWWAuthenticate))
|
assert.Equal(t, basic+" realm=Restricted", rs.Header().Get(echo.WWWAuthenticate))
|
||||||
|
|
||||||
// Invalid Authorization header
|
// Invalid Authorization header
|
||||||
auth = base64.StdEncoding.EncodeToString([]byte("invalid"))
|
auth = base64.StdEncoding.EncodeToString([]byte("invalid"))
|
||||||
rq.Header().Set(echo.Authorization, auth)
|
rq.Header().Set(echo.Authorization, auth)
|
||||||
he = h.Handle(c).(*echo.HTTPError)
|
he = h(c).(*echo.HTTPError)
|
||||||
assert.Equal(t, http.StatusUnauthorized, he.Code)
|
assert.Equal(t, http.StatusUnauthorized, he.Code)
|
||||||
assert.Equal(t, basic+" realm=Restricted", rs.Header().Get(echo.WWWAuthenticate))
|
assert.Equal(t, basic+" realm=Restricted", rs.Header().Get(echo.WWWAuthenticate))
|
||||||
}
|
}
|
||||||
|
@ -50,8 +50,8 @@ func GzipFromConfig(config GzipConfig) echo.MiddlewareFunc {
|
|||||||
pool := gzipPool(config)
|
pool := gzipPool(config)
|
||||||
scheme := "gzip"
|
scheme := "gzip"
|
||||||
|
|
||||||
return func(next echo.Handler) echo.Handler {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return echo.HandlerFunc(func(c echo.Context) error {
|
return func(c echo.Context) error {
|
||||||
rs := c.Response()
|
rs := c.Response()
|
||||||
rs.Header().Add(echo.Vary, echo.AcceptEncoding)
|
rs.Header().Add(echo.Vary, echo.AcceptEncoding)
|
||||||
if strings.Contains(c.Request().Header().Get(echo.AcceptEncoding), scheme) {
|
if strings.Contains(c.Request().Header().Get(echo.AcceptEncoding), scheme) {
|
||||||
@ -74,8 +74,8 @@ func GzipFromConfig(config GzipConfig) echo.MiddlewareFunc {
|
|||||||
rs.Header().Set(echo.ContentEncoding, scheme)
|
rs.Header().Set(echo.ContentEncoding, scheme)
|
||||||
rs.SetWriter(g)
|
rs.SetWriter(g)
|
||||||
}
|
}
|
||||||
return next.Handle(c)
|
return next(c)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,11 +19,11 @@ func TestGzip(t *testing.T) {
|
|||||||
c := echo.NewContext(rq, rec, e)
|
c := echo.NewContext(rq, rec, e)
|
||||||
|
|
||||||
// Skip if no Accept-Encoding header
|
// Skip if no Accept-Encoding header
|
||||||
h := Gzip()(echo.HandlerFunc(func(c echo.Context) error {
|
h := Gzip()(func(c echo.Context) error {
|
||||||
c.Response().Write([]byte("test")) // For Content-Type sniffing
|
c.Response().Write([]byte("test")) // For Content-Type sniffing
|
||||||
return nil
|
return nil
|
||||||
}))
|
})
|
||||||
h.Handle(c)
|
h(c)
|
||||||
assert.Equal(t, "test", rec.Body.String())
|
assert.Equal(t, "test", rec.Body.String())
|
||||||
|
|
||||||
rq = test.NewRequest(echo.GET, "/", nil)
|
rq = test.NewRequest(echo.GET, "/", nil)
|
||||||
@ -32,7 +32,7 @@ func TestGzip(t *testing.T) {
|
|||||||
c = echo.NewContext(rq, rec, e)
|
c = echo.NewContext(rq, rec, e)
|
||||||
|
|
||||||
// Gzip
|
// Gzip
|
||||||
h.Handle(c)
|
h(c)
|
||||||
assert.Equal(t, "gzip", rec.Header().Get(echo.ContentEncoding))
|
assert.Equal(t, "gzip", rec.Header().Get(echo.ContentEncoding))
|
||||||
assert.Contains(t, rec.Header().Get(echo.ContentType), echo.TextPlain)
|
assert.Contains(t, rec.Header().Get(echo.ContentType), echo.TextPlain)
|
||||||
r, err := gzip.NewReader(rec.Body)
|
r, err := gzip.NewReader(rec.Body)
|
||||||
@ -49,10 +49,10 @@ func TestGzipNoContent(t *testing.T) {
|
|||||||
rq := test.NewRequest(echo.GET, "/", nil)
|
rq := test.NewRequest(echo.GET, "/", nil)
|
||||||
rec := test.NewResponseRecorder()
|
rec := test.NewResponseRecorder()
|
||||||
c := echo.NewContext(rq, rec, e)
|
c := echo.NewContext(rq, rec, e)
|
||||||
h := Gzip()(echo.HandlerFunc(func(c echo.Context) error {
|
h := Gzip()(func(c echo.Context) error {
|
||||||
return c.NoContent(http.StatusOK)
|
return c.NoContent(http.StatusOK)
|
||||||
}))
|
})
|
||||||
h.Handle(c)
|
h(c)
|
||||||
|
|
||||||
assert.Empty(t, rec.Header().Get(echo.ContentEncoding))
|
assert.Empty(t, rec.Header().Get(echo.ContentEncoding))
|
||||||
assert.Empty(t, rec.Header().Get(echo.ContentType))
|
assert.Empty(t, rec.Header().Get(echo.ContentType))
|
||||||
@ -65,9 +65,9 @@ func TestGzipNoContent(t *testing.T) {
|
|||||||
func TestGzipErrorReturned(t *testing.T) {
|
func TestGzipErrorReturned(t *testing.T) {
|
||||||
e := echo.New()
|
e := echo.New()
|
||||||
e.Use(Gzip())
|
e.Use(Gzip())
|
||||||
e.Get("/", echo.HandlerFunc(func(c echo.Context) error {
|
e.Get("/", func(c echo.Context) error {
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError, "error")
|
return echo.NewHTTPError(http.StatusInternalServerError, "error")
|
||||||
}))
|
})
|
||||||
rq := test.NewRequest(echo.GET, "/", nil)
|
rq := test.NewRequest(echo.GET, "/", nil)
|
||||||
rec := test.NewResponseRecorder()
|
rec := test.NewResponseRecorder()
|
||||||
e.ServeHTTP(rq, rec)
|
e.ServeHTTP(rq, rec)
|
||||||
|
@ -74,12 +74,12 @@ func LoggerFromConfig(config LoggerConfig) echo.MiddlewareFunc {
|
|||||||
config.color.Disable()
|
config.color.Disable()
|
||||||
}
|
}
|
||||||
|
|
||||||
return func(next echo.Handler) echo.Handler {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return echo.HandlerFunc(func(c echo.Context) (err error) {
|
return func(c echo.Context) (err error) {
|
||||||
rq := c.Request()
|
rq := c.Request()
|
||||||
rs := c.Response()
|
rs := c.Response()
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
if err = next.Handle(c); err != nil {
|
if err = next(c); err != nil {
|
||||||
c.Error(err)
|
c.Error(err)
|
||||||
}
|
}
|
||||||
stop := time.Now()
|
stop := time.Now()
|
||||||
@ -129,6 +129,6 @@ func LoggerFromConfig(config LoggerConfig) echo.MiddlewareFunc {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,37 +17,37 @@ func TestLogger(t *testing.T) {
|
|||||||
rq := test.NewRequest(echo.GET, "/", nil)
|
rq := test.NewRequest(echo.GET, "/", nil)
|
||||||
rec := test.NewResponseRecorder()
|
rec := test.NewResponseRecorder()
|
||||||
c := echo.NewContext(rq, rec, e)
|
c := echo.NewContext(rq, rec, e)
|
||||||
h := Logger()(echo.HandlerFunc(func(c echo.Context) error {
|
h := Logger()(func(c echo.Context) error {
|
||||||
return c.String(http.StatusOK, "test")
|
return c.String(http.StatusOK, "test")
|
||||||
}))
|
})
|
||||||
|
|
||||||
// Status 2xx
|
// Status 2xx
|
||||||
h.Handle(c)
|
h(c)
|
||||||
|
|
||||||
// Status 3xx
|
// Status 3xx
|
||||||
rec = test.NewResponseRecorder()
|
rec = test.NewResponseRecorder()
|
||||||
c = echo.NewContext(rq, rec, e)
|
c = echo.NewContext(rq, rec, e)
|
||||||
h = Logger()(echo.HandlerFunc(func(c echo.Context) error {
|
h = Logger()(func(c echo.Context) error {
|
||||||
return c.String(http.StatusTemporaryRedirect, "test")
|
return c.String(http.StatusTemporaryRedirect, "test")
|
||||||
}))
|
})
|
||||||
h.Handle(c)
|
h(c)
|
||||||
|
|
||||||
// Status 4xx
|
// Status 4xx
|
||||||
rec = test.NewResponseRecorder()
|
rec = test.NewResponseRecorder()
|
||||||
c = echo.NewContext(rq, rec, e)
|
c = echo.NewContext(rq, rec, e)
|
||||||
h = Logger()(echo.HandlerFunc(func(c echo.Context) error {
|
h = Logger()(func(c echo.Context) error {
|
||||||
return c.String(http.StatusNotFound, "test")
|
return c.String(http.StatusNotFound, "test")
|
||||||
}))
|
})
|
||||||
h.Handle(c)
|
h(c)
|
||||||
|
|
||||||
// Status 5xx with empty path
|
// Status 5xx with empty path
|
||||||
rq = test.NewRequest(echo.GET, "", nil)
|
rq = test.NewRequest(echo.GET, "", nil)
|
||||||
rec = test.NewResponseRecorder()
|
rec = test.NewResponseRecorder()
|
||||||
c = echo.NewContext(rq, rec, e)
|
c = echo.NewContext(rq, rec, e)
|
||||||
h = Logger()(echo.HandlerFunc(func(c echo.Context) error {
|
h = Logger()(func(c echo.Context) error {
|
||||||
return errors.New("error")
|
return errors.New("error")
|
||||||
}))
|
})
|
||||||
h.Handle(c)
|
h(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLoggerIPAddress(t *testing.T) {
|
func TestLoggerIPAddress(t *testing.T) {
|
||||||
@ -58,24 +58,24 @@ func TestLoggerIPAddress(t *testing.T) {
|
|||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
e.Logger().SetOutput(buf)
|
e.Logger().SetOutput(buf)
|
||||||
ip := "127.0.0.1"
|
ip := "127.0.0.1"
|
||||||
h := Logger()(echo.HandlerFunc(func(c echo.Context) error {
|
h := Logger()(func(c echo.Context) error {
|
||||||
return c.String(http.StatusOK, "test")
|
return c.String(http.StatusOK, "test")
|
||||||
}))
|
})
|
||||||
|
|
||||||
// With X-Real-IP
|
// With X-Real-IP
|
||||||
rq.Header().Add(echo.XRealIP, ip)
|
rq.Header().Add(echo.XRealIP, ip)
|
||||||
h.Handle(c)
|
h(c)
|
||||||
assert.Contains(t, ip, buf.String())
|
assert.Contains(t, ip, buf.String())
|
||||||
|
|
||||||
// With X-Forwarded-For
|
// With X-Forwarded-For
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
rq.Header().Del(echo.XRealIP)
|
rq.Header().Del(echo.XRealIP)
|
||||||
rq.Header().Add(echo.XForwardedFor, ip)
|
rq.Header().Add(echo.XForwardedFor, ip)
|
||||||
h.Handle(c)
|
h(c)
|
||||||
assert.Contains(t, ip, buf.String())
|
assert.Contains(t, ip, buf.String())
|
||||||
|
|
||||||
// with rq.RemoteAddr
|
// with rq.RemoteAddr
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
h.Handle(c)
|
h(c)
|
||||||
assert.Contains(t, ip, buf.String())
|
assert.Contains(t, ip, buf.String())
|
||||||
}
|
}
|
||||||
|
@ -49,8 +49,8 @@ func RecoverFromConfig(config RecoverConfig) echo.MiddlewareFunc {
|
|||||||
config.StackSize = DefaultRecoverConfig.StackSize
|
config.StackSize = DefaultRecoverConfig.StackSize
|
||||||
}
|
}
|
||||||
|
|
||||||
return func(next echo.Handler) echo.Handler {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return echo.HandlerFunc(func(c echo.Context) error {
|
return func(c echo.Context) error {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
var err error
|
var err error
|
||||||
@ -68,7 +68,7 @@ func RecoverFromConfig(config RecoverConfig) echo.MiddlewareFunc {
|
|||||||
c.Error(err)
|
c.Error(err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
return next.Handle(c)
|
return next(c)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ func TestRecover(t *testing.T) {
|
|||||||
h := Recover()(echo.HandlerFunc(func(c echo.Context) error {
|
h := Recover()(echo.HandlerFunc(func(c echo.Context) error {
|
||||||
panic("test")
|
panic("test")
|
||||||
}))
|
}))
|
||||||
h.Handle(c)
|
h(c)
|
||||||
assert.Equal(t, http.StatusInternalServerError, rec.Status())
|
assert.Equal(t, http.StatusInternalServerError, rec.Status())
|
||||||
assert.Contains(t, buf.String(), "PANIC RECOVER")
|
assert.Contains(t, buf.String(), "PANIC RECOVER")
|
||||||
}
|
}
|
||||||
|
@ -9,15 +9,15 @@ import (
|
|||||||
//
|
//
|
||||||
// Usage `Echo#Pre(AddTrailingSlash())`
|
// Usage `Echo#Pre(AddTrailingSlash())`
|
||||||
func AddTrailingSlash() echo.MiddlewareFunc {
|
func AddTrailingSlash() echo.MiddlewareFunc {
|
||||||
return func(next echo.Handler) echo.Handler {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return echo.HandlerFunc(func(c echo.Context) error {
|
return func(c echo.Context) error {
|
||||||
url := c.Request().URL()
|
url := c.Request().URL()
|
||||||
path := url.Path()
|
path := url.Path()
|
||||||
if path != "/" && path[len(path)-1] != '/' {
|
if path != "/" && path[len(path)-1] != '/' {
|
||||||
url.SetPath(path + "/")
|
url.SetPath(path + "/")
|
||||||
}
|
}
|
||||||
return next.Handle(c)
|
return next(c)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,15 +26,15 @@ func AddTrailingSlash() echo.MiddlewareFunc {
|
|||||||
//
|
//
|
||||||
// Usage `Echo#Pre(RemoveTrailingSlash())`
|
// Usage `Echo#Pre(RemoveTrailingSlash())`
|
||||||
func RemoveTrailingSlash() echo.MiddlewareFunc {
|
func RemoveTrailingSlash() echo.MiddlewareFunc {
|
||||||
return func(next echo.Handler) echo.Handler {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return echo.HandlerFunc(func(c echo.Context) error {
|
return func(c echo.Context) error {
|
||||||
url := c.Request().URL()
|
url := c.Request().URL()
|
||||||
path := url.Path()
|
path := url.Path()
|
||||||
l := len(path) - 1
|
l := len(path) - 1
|
||||||
if path != "/" && path[l] == '/' {
|
if path != "/" && path[l] == '/' {
|
||||||
url.SetPath(path[:l])
|
url.SetPath(path[:l])
|
||||||
}
|
}
|
||||||
return next.Handle(c)
|
return next(c)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,10 +13,10 @@ func TestAddTrailingSlash(t *testing.T) {
|
|||||||
rq := test.NewRequest(echo.GET, "/add-slash", nil)
|
rq := test.NewRequest(echo.GET, "/add-slash", nil)
|
||||||
rc := test.NewResponseRecorder()
|
rc := test.NewResponseRecorder()
|
||||||
c := echo.NewContext(rq, rc, e)
|
c := echo.NewContext(rq, rc, e)
|
||||||
h := AddTrailingSlash()(echo.HandlerFunc(func(c echo.Context) error {
|
h := AddTrailingSlash()(func(c echo.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}))
|
})
|
||||||
h.Handle(c)
|
h(c)
|
||||||
assert.Equal(t, "/add-slash/", rq.URL().Path())
|
assert.Equal(t, "/add-slash/", rq.URL().Path())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,9 +25,9 @@ func TestRemoveTrailingSlash(t *testing.T) {
|
|||||||
rq := test.NewRequest(echo.GET, "/remove-slash/", nil)
|
rq := test.NewRequest(echo.GET, "/remove-slash/", nil)
|
||||||
rc := test.NewResponseRecorder()
|
rc := test.NewResponseRecorder()
|
||||||
c := echo.NewContext(rq, rc, e)
|
c := echo.NewContext(rq, rc, e)
|
||||||
h := RemoveTrailingSlash()(echo.HandlerFunc(func(c echo.Context) error {
|
h := RemoveTrailingSlash()(func(c echo.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}))
|
})
|
||||||
h.Handle(c)
|
h(c)
|
||||||
assert.Equal(t, "/remove-slash", rq.URL().Path())
|
assert.Equal(t, "/remove-slash", rq.URL().Path())
|
||||||
}
|
}
|
||||||
|
@ -51,8 +51,8 @@ func StaticFromConfig(config StaticConfig) echo.MiddlewareFunc {
|
|||||||
config.Index = DefaultStaticConfig.Index
|
config.Index = DefaultStaticConfig.Index
|
||||||
}
|
}
|
||||||
|
|
||||||
return func(next echo.Handler) echo.Handler {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return echo.HandlerFunc(func(c echo.Context) error {
|
return func(c echo.Context) error {
|
||||||
fs := http.Dir(config.Root)
|
fs := http.Dir(config.Root)
|
||||||
p := c.Request().URL().Path()
|
p := c.Request().URL().Path()
|
||||||
if c.P(0) != "" { // If serving from `Group`, e.g. `/static/*`
|
if c.P(0) != "" { // If serving from `Group`, e.g. `/static/*`
|
||||||
@ -61,7 +61,7 @@ func StaticFromConfig(config StaticConfig) echo.MiddlewareFunc {
|
|||||||
file := path.Clean(p)
|
file := path.Clean(p)
|
||||||
f, err := fs.Open(file)
|
f, err := fs.Open(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return next.Handle(c)
|
return next(c)
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
@ -108,11 +108,11 @@ func StaticFromConfig(config StaticConfig) echo.MiddlewareFunc {
|
|||||||
_, err = fmt.Fprintf(rs, "</pre>\n")
|
_, err = fmt.Fprintf(rs, "</pre>\n")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return next.Handle(c)
|
return next(c)
|
||||||
}
|
}
|
||||||
fi, _ = f.Stat() // Index file stat
|
fi, _ = f.Stat() // Index file stat
|
||||||
}
|
}
|
||||||
return c.ServeContent(f, fi.Name(), fi.ModTime())
|
return c.ServeContent(f, fi.Name(), fi.ModTime())
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
36
router.go
36
router.go
@ -21,15 +21,15 @@ type (
|
|||||||
kind uint8
|
kind uint8
|
||||||
children []*node
|
children []*node
|
||||||
methodHandler struct {
|
methodHandler struct {
|
||||||
connect Handler
|
connect HandlerFunc
|
||||||
delete Handler
|
delete HandlerFunc
|
||||||
get Handler
|
get HandlerFunc
|
||||||
head Handler
|
head HandlerFunc
|
||||||
options Handler
|
options HandlerFunc
|
||||||
patch Handler
|
patch HandlerFunc
|
||||||
post Handler
|
post HandlerFunc
|
||||||
put Handler
|
put HandlerFunc
|
||||||
trace Handler
|
trace HandlerFunc
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -50,14 +50,14 @@ func NewRouter(e *Echo) *Router {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle implements `echo.Middleware` which makes router a middleware.
|
// Process implements `echo.MiddlewareFunc` which makes router a middleware.
|
||||||
func (r *Router) Handle(next Handler) Handler {
|
func (r *Router) Process(next HandlerFunc) HandlerFunc {
|
||||||
return HandlerFunc(func(c Context) error {
|
return func(c Context) error {
|
||||||
method := c.Request().Method()
|
method := c.Request().Method()
|
||||||
path := c.Request().URL().Path()
|
path := c.Request().URL().Path()
|
||||||
r.Find(method, path, c)
|
r.Find(method, path, c)
|
||||||
return next.Handle(c)
|
return next(c)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Priority is super secret.
|
// Priority is super secret.
|
||||||
@ -66,7 +66,7 @@ func (r *Router) Priority() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add registers a new route for method and path with matching handler.
|
// Add registers a new route for method and path with matching handler.
|
||||||
func (r *Router) Add(method, path string, h Handler, e *Echo) {
|
func (r *Router) Add(method, path string, h HandlerFunc, e *Echo) {
|
||||||
ppath := path // Pristine path
|
ppath := path // Pristine path
|
||||||
pnames := []string{} // Param names
|
pnames := []string{} // Param names
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ func (r *Router) Add(method, path string, h Handler, e *Echo) {
|
|||||||
r.insert(method, path, h, skind, ppath, pnames, e)
|
r.insert(method, path, h, skind, ppath, pnames, e)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Router) insert(method, path string, h Handler, t kind, ppath string, pnames []string, e *Echo) {
|
func (r *Router) insert(method, path string, h HandlerFunc, t kind, ppath string, pnames []string, e *Echo) {
|
||||||
// Adjust max param
|
// Adjust max param
|
||||||
l := len(pnames)
|
l := len(pnames)
|
||||||
if *e.maxParam < l {
|
if *e.maxParam < l {
|
||||||
@ -229,7 +229,7 @@ func (n *node) findChildByKind(t kind) *node {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *node) addHandler(method string, h Handler) {
|
func (n *node) addHandler(method string, h HandlerFunc) {
|
||||||
switch method {
|
switch method {
|
||||||
case GET:
|
case GET:
|
||||||
n.methodHandler.get = h
|
n.methodHandler.get = h
|
||||||
@ -252,7 +252,7 @@ func (n *node) addHandler(method string, h Handler) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *node) findHandler(method string) Handler {
|
func (n *node) findHandler(method string) HandlerFunc {
|
||||||
switch method {
|
switch method {
|
||||||
case GET:
|
case GET:
|
||||||
return n.methodHandler.get
|
return n.methodHandler.get
|
||||||
|
104
router_test.go
104
router_test.go
@ -277,10 +277,10 @@ func TestRouterStatic(t *testing.T) {
|
|||||||
e := New()
|
e := New()
|
||||||
r := e.router
|
r := e.router
|
||||||
path := "/folders/a/files/echo.gif"
|
path := "/folders/a/files/echo.gif"
|
||||||
r.Add(GET, path, HandlerFunc(func(c Context) error {
|
r.Add(GET, path, func(c Context) error {
|
||||||
c.Set("path", path)
|
c.Set("path", path)
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
c := NewContext(nil, nil, e)
|
c := NewContext(nil, nil, e)
|
||||||
r.Find(GET, path, c)
|
r.Find(GET, path, c)
|
||||||
c.Handle(c)
|
c.Handle(c)
|
||||||
@ -290,9 +290,9 @@ func TestRouterStatic(t *testing.T) {
|
|||||||
func TestRouterParam(t *testing.T) {
|
func TestRouterParam(t *testing.T) {
|
||||||
e := New()
|
e := New()
|
||||||
r := e.router
|
r := e.router
|
||||||
r.Add(GET, "/users/:id", HandlerFunc(func(c Context) error {
|
r.Add(GET, "/users/:id", func(c Context) error {
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
c := NewContext(nil, nil, e)
|
c := NewContext(nil, nil, e)
|
||||||
r.Find(GET, "/users/1", c)
|
r.Find(GET, "/users/1", c)
|
||||||
assert.Equal(t, "1", c.P(0))
|
assert.Equal(t, "1", c.P(0))
|
||||||
@ -301,9 +301,9 @@ func TestRouterParam(t *testing.T) {
|
|||||||
func TestRouterTwoParam(t *testing.T) {
|
func TestRouterTwoParam(t *testing.T) {
|
||||||
e := New()
|
e := New()
|
||||||
r := e.router
|
r := e.router
|
||||||
r.Add(GET, "/users/:uid/files/:fid", HandlerFunc(func(Context) error {
|
r.Add(GET, "/users/:uid/files/:fid", func(Context) error {
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
c := NewContext(nil, nil, e)
|
c := NewContext(nil, nil, e)
|
||||||
|
|
||||||
r.Find(GET, "/users/1/files/1", c)
|
r.Find(GET, "/users/1/files/1", c)
|
||||||
@ -316,13 +316,13 @@ func TestRouterParamWithSlash(t *testing.T) {
|
|||||||
e := New()
|
e := New()
|
||||||
r := e.router
|
r := e.router
|
||||||
|
|
||||||
r.Add(GET, "/a/:b/c/d/:e", HandlerFunc(func(c Context) error {
|
r.Add(GET, "/a/:b/c/d/:e", func(c Context) error {
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
|
|
||||||
r.Add(GET, "/a/:b/c/:d/:f", HandlerFunc(func(c Context) error {
|
r.Add(GET, "/a/:b/c/:d/:f", func(c Context) error {
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
|
|
||||||
c := NewContext(nil, nil, e)
|
c := NewContext(nil, nil, e)
|
||||||
assert.NotPanics(t, func() {
|
assert.NotPanics(t, func() {
|
||||||
@ -335,15 +335,15 @@ func TestRouterMatchAny(t *testing.T) {
|
|||||||
r := e.router
|
r := e.router
|
||||||
|
|
||||||
// Routes
|
// Routes
|
||||||
r.Add(GET, "/", HandlerFunc(func(Context) error {
|
r.Add(GET, "/", func(Context) error {
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
r.Add(GET, "/*", HandlerFunc(func(Context) error {
|
r.Add(GET, "/*", func(Context) error {
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
r.Add(GET, "/users/*", HandlerFunc(func(Context) error {
|
r.Add(GET, "/users/*", func(Context) error {
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
c := NewContext(nil, nil, e)
|
c := NewContext(nil, nil, e)
|
||||||
|
|
||||||
r.Find(GET, "/", c)
|
r.Find(GET, "/", c)
|
||||||
@ -359,9 +359,9 @@ func TestRouterMatchAny(t *testing.T) {
|
|||||||
func TestRouterMicroParam(t *testing.T) {
|
func TestRouterMicroParam(t *testing.T) {
|
||||||
e := New()
|
e := New()
|
||||||
r := e.router
|
r := e.router
|
||||||
r.Add(GET, "/:a/:b/:c", HandlerFunc(func(c Context) error {
|
r.Add(GET, "/:a/:b/:c", func(c Context) error {
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
c := NewContext(nil, nil, e)
|
c := NewContext(nil, nil, e)
|
||||||
r.Find(GET, "/1/2/3", c)
|
r.Find(GET, "/1/2/3", c)
|
||||||
assert.Equal(t, "1", c.P(0))
|
assert.Equal(t, "1", c.P(0))
|
||||||
@ -374,9 +374,9 @@ func TestRouterMixParamMatchAny(t *testing.T) {
|
|||||||
r := e.router
|
r := e.router
|
||||||
|
|
||||||
// Route
|
// Route
|
||||||
r.Add(GET, "/users/:id/*", HandlerFunc(func(c Context) error {
|
r.Add(GET, "/users/:id/*", func(c Context) error {
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
c := NewContext(nil, nil, e)
|
c := NewContext(nil, nil, e)
|
||||||
|
|
||||||
r.Find(GET, "/users/joe/comments", c)
|
r.Find(GET, "/users/joe/comments", c)
|
||||||
@ -389,13 +389,13 @@ func TestRouterMultiRoute(t *testing.T) {
|
|||||||
r := e.router
|
r := e.router
|
||||||
|
|
||||||
// Routes
|
// Routes
|
||||||
r.Add(GET, "/users", HandlerFunc(func(c Context) error {
|
r.Add(GET, "/users", func(c Context) error {
|
||||||
c.Set("path", "/users")
|
c.Set("path", "/users")
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
r.Add(GET, "/users/:id", HandlerFunc(func(c Context) error {
|
r.Add(GET, "/users/:id", func(c Context) error {
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
c := NewContext(nil, nil, e)
|
c := NewContext(nil, nil, e)
|
||||||
|
|
||||||
// Route > /users
|
// Route > /users
|
||||||
@ -419,34 +419,34 @@ func TestRouterPriority(t *testing.T) {
|
|||||||
r := e.router
|
r := e.router
|
||||||
|
|
||||||
// Routes
|
// Routes
|
||||||
r.Add(GET, "/users", HandlerFunc(func(c Context) error {
|
r.Add(GET, "/users", func(c Context) error {
|
||||||
c.Set("a", 1)
|
c.Set("a", 1)
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
r.Add(GET, "/users/new", HandlerFunc(func(c Context) error {
|
r.Add(GET, "/users/new", func(c Context) error {
|
||||||
c.Set("b", 2)
|
c.Set("b", 2)
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
r.Add(GET, "/users/:id", HandlerFunc(func(c Context) error {
|
r.Add(GET, "/users/:id", func(c Context) error {
|
||||||
c.Set("c", 3)
|
c.Set("c", 3)
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
r.Add(GET, "/users/dew", HandlerFunc(func(c Context) error {
|
r.Add(GET, "/users/dew", func(c Context) error {
|
||||||
c.Set("d", 4)
|
c.Set("d", 4)
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
r.Add(GET, "/users/:id/files", HandlerFunc(func(c Context) error {
|
r.Add(GET, "/users/:id/files", func(c Context) error {
|
||||||
c.Set("e", 5)
|
c.Set("e", 5)
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
r.Add(GET, "/users/newsee", HandlerFunc(func(c Context) error {
|
r.Add(GET, "/users/newsee", func(c Context) error {
|
||||||
c.Set("f", 6)
|
c.Set("f", 6)
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
r.Add(GET, "/users/*", HandlerFunc(func(c Context) error {
|
r.Add(GET, "/users/*", func(c Context) error {
|
||||||
c.Set("g", 7)
|
c.Set("g", 7)
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
c := NewContext(nil, nil, e)
|
c := NewContext(nil, nil, e)
|
||||||
|
|
||||||
// Route > /users
|
// Route > /users
|
||||||
@ -493,14 +493,14 @@ func TestRouterPriorityNotFound(t *testing.T) {
|
|||||||
c := NewContext(nil, nil, e)
|
c := NewContext(nil, nil, e)
|
||||||
|
|
||||||
// Add
|
// Add
|
||||||
r.Add(GET, "/a/foo", HandlerFunc(func(c Context) error {
|
r.Add(GET, "/a/foo", func(c Context) error {
|
||||||
c.Set("a", 1)
|
c.Set("a", 1)
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
r.Add(GET, "/a/bar", HandlerFunc(func(c Context) error {
|
r.Add(GET, "/a/bar", func(c Context) error {
|
||||||
c.Set("b", 2)
|
c.Set("b", 2)
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
|
|
||||||
// Find
|
// Find
|
||||||
r.Find(GET, "/a/foo", c)
|
r.Find(GET, "/a/foo", c)
|
||||||
@ -522,16 +522,16 @@ func TestRouterParamNames(t *testing.T) {
|
|||||||
r := e.router
|
r := e.router
|
||||||
|
|
||||||
// Routes
|
// Routes
|
||||||
r.Add(GET, "/users", HandlerFunc(func(c Context) error {
|
r.Add(GET, "/users", func(c Context) error {
|
||||||
c.Set("path", "/users")
|
c.Set("path", "/users")
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
r.Add(GET, "/users/:id", HandlerFunc(func(c Context) error {
|
r.Add(GET, "/users/:id", func(c Context) error {
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
r.Add(GET, "/users/:uid/files/:fid", HandlerFunc(func(c Context) error {
|
r.Add(GET, "/users/:uid/files/:fid", func(c Context) error {
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
c := NewContext(nil, nil, e)
|
c := NewContext(nil, nil, e)
|
||||||
|
|
||||||
// Route > /users
|
// Route > /users
|
||||||
@ -557,9 +557,9 @@ func TestRouterAPI(t *testing.T) {
|
|||||||
r := e.router
|
r := e.router
|
||||||
|
|
||||||
for _, route := range api {
|
for _, route := range api {
|
||||||
r.Add(route.Method, route.Path, HandlerFunc(func(c Context) error {
|
r.Add(route.Method, route.Path, func(c Context) error {
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
}
|
}
|
||||||
c := NewContext(nil, nil, e)
|
c := NewContext(nil, nil, e)
|
||||||
for _, route := range api {
|
for _, route := range api {
|
||||||
@ -579,9 +579,9 @@ func BenchmarkRouterGitHubAPI(b *testing.B) {
|
|||||||
|
|
||||||
// Add routes
|
// Add routes
|
||||||
for _, route := range api {
|
for _, route := range api {
|
||||||
r.Add(route.Method, route.Path, HandlerFunc(func(c Context) error {
|
r.Add(route.Method, route.Path, func(c Context) error {
|
||||||
return nil
|
return nil
|
||||||
}), e)
|
}, e)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find routes
|
// Find routes
|
||||||
|
Loading…
x
Reference in New Issue
Block a user