diff --git a/echo.go b/echo.go index d45144d8c..a0b3070e1 100644 --- a/echo.go +++ b/echo.go @@ -64,6 +64,7 @@ import ( type ( // Echo is the top-level framework instance. Echo struct { + common StdLogger *stdLog.Logger colorer *color.Color premiddleware []MiddlewareFunc @@ -125,10 +126,8 @@ type ( // Map defines a generic map of type `map[string]interface{}`. Map map[string]interface{} - // i is the interface for Echo and Group. - i interface { - GET(string, HandlerFunc, ...MiddlewareFunc) *Route - } + // Common struct for Echo & Group. + common struct{} ) // HTTP methods @@ -225,7 +224,7 @@ const ( const ( // Version of Echo - Version = "4.1.2" + Version = "4.1.3" website = "https://echo.labstack.com" // http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo banner = ` @@ -461,10 +460,10 @@ func (e *Echo) Static(prefix, root string) *Route { if root == "" { root = "." // For security we want to restrict to CWD. } - return static(e, prefix, root) + return e.static(prefix, root, e.GET) } -func static(i i, prefix, root string) *Route { +func (_ common) static(prefix, root string, get func(string, HandlerFunc, ...MiddlewareFunc) *Route) *Route { h := func(c Context) error { p, err := url.PathUnescape(c.Param("*")) if err != nil { @@ -473,21 +472,26 @@ func static(i i, prefix, root string) *Route { name := filepath.Join(root, path.Clean("/"+p)) // "/"+ for security return c.File(name) } - i.GET(prefix, h) + get(prefix, h) if prefix == "/" { - return i.GET(prefix+"*", h) + return get(prefix+"*", h) } - return i.GET(prefix+"/*", h) + return get(prefix+"/*", h) } -// File registers a new route with path to serve a static file with optional route-level middleware. -func (e *Echo) File(path, file string, m ...MiddlewareFunc) *Route { - return e.GET(path, func(c Context) error { +func (_ common) file(path, file string, get func(string, HandlerFunc, ...MiddlewareFunc) *Route, + m ...MiddlewareFunc) *Route { + return get(path, func(c Context) error { return c.File(file) }, m...) } +// File registers a new route with path to serve a static file with optional route-level middleware. +func (e *Echo) File(path, file string, m ...MiddlewareFunc) *Route { + return e.file(path, file, e.GET, m...) +} + func (e *Echo) add(host, method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route { name := handlerName(handler) router := e.findRouter(host) diff --git a/group.go b/group.go index a14667e82..e674cad4f 100644 --- a/group.go +++ b/group.go @@ -10,6 +10,7 @@ type ( // routes that share a common middleware or functionality that should be separate // from the parent echo instance while still inheriting from it. Group struct { + common host string prefix string middleware []MiddlewareFunc @@ -23,7 +24,7 @@ func (g *Group) Use(middleware ...MiddlewareFunc) { // Allow all requests to reach the group as they might get dropped if router // doesn't find a match, making none of the group middleware process. for _, p := range []string{"", "/*"} { - g.echo.Any(path.Clean(g.prefix+p), func(c Context) error { + g.Any(path.Clean(g.prefix+p), func(c Context) error { return NotFoundHandler(c) }, g.middleware...) } @@ -104,12 +105,12 @@ func (g *Group) Group(prefix string, middleware ...MiddlewareFunc) (sg *Group) { // Static implements `Echo#Static()` for sub-routes within the Group. func (g *Group) Static(prefix, root string) { - static(g, prefix, root) + g.static(prefix, root, g.GET) } // File implements `Echo#File()` for sub-routes within the Group. func (g *Group) File(path, file string) { - g.echo.File(g.prefix+path, file) + g.file(g.prefix+path, file, g.GET) } // Add implements `Echo#Add()` for sub-routes within the Group. diff --git a/middleware/logger.go b/middleware/logger.go index 83b52b26a..6fd59efbc 100644 --- a/middleware/logger.go +++ b/middleware/logger.go @@ -2,6 +2,7 @@ package middleware import ( "bytes" + "encoding/json" "io" "os" "strconv" @@ -175,7 +176,10 @@ func LoggerWithConfig(config LoggerConfig) echo.MiddlewareFunc { return buf.WriteString(s) case "error": if err != nil { - return buf.WriteString(err.Error()) + // Error may contain invalid JSON e.g. `"` + b, _ := json.Marshal(err.Error()) + b = b[1 : len(b)-1] + return buf.Write(b) } case "latency": l := stop.Sub(start)