diff options
Diffstat (limited to 'vendor/github.com/labstack/echo/echo.go')
-rw-r--r-- | vendor/github.com/labstack/echo/echo.go | 128 |
1 files changed, 88 insertions, 40 deletions
diff --git a/vendor/github.com/labstack/echo/echo.go b/vendor/github.com/labstack/echo/echo.go index 4a54b31a..41ac6b5e 100644 --- a/vendor/github.com/labstack/echo/echo.go +++ b/vendor/github.com/labstack/echo/echo.go @@ -38,6 +38,7 @@ package echo import ( "bytes" + stdContext "context" "crypto/tls" "errors" "fmt" @@ -45,6 +46,7 @@ import ( stdLog "log" "net" "net/http" + "net/url" "path" "path/filepath" "reflect" @@ -81,8 +83,7 @@ type ( Binder Binder Validator Validator Renderer Renderer - // Mutex sync.RWMutex - Logger Logger + Logger Logger } // Route contains a handler and information for matching against requests. @@ -94,9 +95,9 @@ type ( // HTTPError represents an error that occurred while handling a request. HTTPError struct { - Code int - Message interface{} - Inner error // Stores the error returned by an external dependency + Code int + Message interface{} + Internal error // Stores the error returned by an external dependency } // MiddlewareFunc defines a function to process middleware. @@ -129,15 +130,16 @@ type ( // HTTP methods const ( - CONNECT = "CONNECT" - DELETE = "DELETE" - GET = "GET" - HEAD = "HEAD" - OPTIONS = "OPTIONS" - PATCH = "PATCH" - POST = "POST" - PUT = "PUT" - TRACE = "TRACE" + CONNECT = "CONNECT" + DELETE = "DELETE" + GET = "GET" + HEAD = "HEAD" + OPTIONS = "OPTIONS" + PATCH = "PATCH" + POST = "POST" + PROPFIND = "PROPFIND" + PUT = "PUT" + TRACE = "TRACE" ) // MIME types @@ -191,6 +193,7 @@ const ( HeaderXHTTPMethodOverride = "X-HTTP-Method-Override" HeaderXRealIP = "X-Real-IP" HeaderXRequestID = "X-Request-ID" + HeaderXRequestedWith = "X-Requested-With" HeaderServer = "Server" HeaderOrigin = "Origin" @@ -214,7 +217,7 @@ const ( ) const ( - version = "3.2.6" + Version = "3.3.5" website = "https://echo.labstack.com" // http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo banner = ` @@ -238,6 +241,7 @@ var ( OPTIONS, PATCH, POST, + PROPFIND, PUT, TRACE, } @@ -251,10 +255,10 @@ var ( ErrForbidden = NewHTTPError(http.StatusForbidden) ErrMethodNotAllowed = NewHTTPError(http.StatusMethodNotAllowed) ErrStatusRequestEntityTooLarge = NewHTTPError(http.StatusRequestEntityTooLarge) - ErrValidatorNotRegistered = errors.New("Validator not registered") - ErrRendererNotRegistered = errors.New("Renderer not registered") - ErrInvalidRedirectCode = errors.New("Invalid redirect status code") - ErrCookieNotFound = errors.New("Cookie not found") + ErrValidatorNotRegistered = errors.New("validator not registered") + ErrRendererNotRegistered = errors.New("renderer not registered") + ErrInvalidRedirectCode = errors.New("invalid redirect status code") + ErrCookieNotFound = errors.New("cookie not found") ) // Error handlers @@ -321,8 +325,8 @@ func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) { if he, ok := err.(*HTTPError); ok { code = he.Code msg = he.Message - if he.Inner != nil { - msg = fmt.Sprintf("%v, %v", err, he.Inner) + if he.Internal != nil { + msg = fmt.Sprintf("%v, %v", err, he.Internal) } } else if e.Debug { msg = err.Error() @@ -443,7 +447,7 @@ func (e *Echo) Static(prefix, root string) *Route { func static(i i, prefix, root string) *Route { h := func(c Context) error { - p, err := PathUnescape(c.Param("*")) + p, err := url.PathUnescape(c.Param("*")) if err != nil { return err } @@ -530,7 +534,7 @@ func (e *Echo) Reverse(name string, params ...interface{}) string { // Routes returns the registered routes. func (e *Echo) Routes() []*Route { - routes := []*Route{} + routes := make([]*Route, 0, len(e.router.routes)) for _, v := range e.router.routes { routes = append(routes, v) } @@ -551,39 +555,48 @@ func (e *Echo) ReleaseContext(c Context) { // ServeHTTP implements `http.Handler` interface, which serves HTTP requests. func (e *Echo) ServeHTTP(w http.ResponseWriter, r *http.Request) { - // Acquire lock - // e.Mutex.RLock() - // defer e.Mutex.RUnlock() - // Acquire context c := e.pool.Get().(*context) - defer e.pool.Put(c) c.Reset(r, w) - // Middleware - h := func(c Context) error { - method := r.Method + m := r.Method + h := NotFoundHandler + + if e.premiddleware == nil { path := r.URL.RawPath if path == "" { path = r.URL.Path } - e.router.Find(method, path, c) - h := c.Handler() + e.router.Find(m, getPath(r), c) + h = c.Handler() for i := len(e.middleware) - 1; i >= 0; i-- { h = e.middleware[i](h) } - return h(c) - } - - // Premiddleware - for i := len(e.premiddleware) - 1; i >= 0; i-- { - h = e.premiddleware[i](h) + } else { + h = func(c Context) error { + path := r.URL.RawPath + if path == "" { + path = r.URL.Path + } + e.router.Find(m, getPath(r), c) + h := c.Handler() + for i := len(e.middleware) - 1; i >= 0; i-- { + h = e.middleware[i](h) + } + return h(c) + } + for i := len(e.premiddleware) - 1; i >= 0; i-- { + h = e.premiddleware[i](h) + } } // Execute chain if err := h(c); err != nil { e.HTTPErrorHandler(err, c) } + + // Release context + e.pool.Put(c) } // Start starts an HTTP server. @@ -609,6 +622,10 @@ func (e *Echo) StartTLS(address string, certFile, keyFile string) (err error) { // StartAutoTLS starts an HTTPS server using certificates automatically installed from https://letsencrypt.org. func (e *Echo) StartAutoTLS(address string) error { + if e.Listener == nil { + go http.ListenAndServe(":http", e.AutoTLSManager.HTTPHandler(nil)) + } + s := e.TLSServer s.TLSConfig = new(tls.Config) s.TLSConfig.GetCertificate = e.AutoTLSManager.GetCertificate @@ -635,7 +652,7 @@ func (e *Echo) StartServer(s *http.Server) (err error) { } if !e.HideBanner { - e.colorer.Printf(banner, e.colorer.Red("v"+version), e.colorer.Blue(website)) + e.colorer.Printf(banner, e.colorer.Red("v"+Version), e.colorer.Blue(website)) } if s.TLSConfig == nil { @@ -663,6 +680,24 @@ func (e *Echo) StartServer(s *http.Server) (err error) { return s.Serve(e.TLSListener) } +// Close immediately stops the server. +// It internally calls `http.Server#Close()`. +func (e *Echo) Close() error { + if err := e.TLSServer.Close(); err != nil { + return err + } + return e.Server.Close() +} + +// Shutdown stops server the gracefully. +// It internally calls `http.Server#Shutdown()`. +func (e *Echo) Shutdown(ctx stdContext.Context) error { + if err := e.TLSServer.Shutdown(ctx); err != nil { + return err + } + return e.Server.Shutdown(ctx) +} + // NewHTTPError creates a new HTTPError instance. func NewHTTPError(code int, message ...interface{}) *HTTPError { he := &HTTPError{Code: code, Message: http.StatusText(code)} @@ -698,6 +733,14 @@ func WrapMiddleware(m func(http.Handler) http.Handler) MiddlewareFunc { } } +func getPath(r *http.Request) string { + path := r.URL.RawPath + if path == "" { + path = r.URL.Path + } + return path +} + func handlerName(h HandlerFunc) string { t := reflect.ValueOf(h).Type() if t.Kind() == reflect.Func { @@ -706,6 +749,11 @@ func handlerName(h HandlerFunc) string { return t.String() } +// // PathUnescape is wraps `url.PathUnescape` +// func PathUnescape(s string) (string, error) { +// return url.PathUnescape(s) +// } + // tcpKeepAliveListener sets TCP keep-alive timeouts on accepted // connections. It's used by ListenAndServe and ListenAndServeTLS so // dead TCP connections (e.g. closing laptop mid-download) eventually |