summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/labstack/echo/echo.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/labstack/echo/echo.go')
-rw-r--r--vendor/github.com/labstack/echo/echo.go128
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