CalDAV support (#15)
This commit is contained in:
344
vendor/github.com/labstack/echo/echo.go
generated
vendored
344
vendor/github.com/labstack/echo/echo.go
generated
vendored
@ -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"
|
||||
@ -72,34 +74,36 @@ type (
|
||||
TLSServer *http.Server
|
||||
Listener net.Listener
|
||||
TLSListener net.Listener
|
||||
AutoTLSManager autocert.Manager
|
||||
DisableHTTP2 bool
|
||||
Debug bool
|
||||
HideBanner bool
|
||||
HidePort bool
|
||||
HTTPErrorHandler HTTPErrorHandler
|
||||
Binder Binder
|
||||
Validator Validator
|
||||
Renderer Renderer
|
||||
AutoTLSManager autocert.Manager
|
||||
Mutex sync.RWMutex
|
||||
Logger Logger
|
||||
}
|
||||
|
||||
// Route contains a handler and information for matching against requests.
|
||||
Route struct {
|
||||
Method string
|
||||
Path string
|
||||
Handler string
|
||||
Method string `json:"method"`
|
||||
Path string `json:"path"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// HTTPError represents an error that occurred while handling a request.
|
||||
HTTPError struct {
|
||||
Code int
|
||||
Message interface{}
|
||||
Code int
|
||||
Message interface{}
|
||||
Internal error // Stores the error returned by an external dependency
|
||||
}
|
||||
|
||||
// MiddlewareFunc defines a function to process middleware.
|
||||
MiddlewareFunc func(HandlerFunc) HandlerFunc
|
||||
|
||||
// HandlerFunc defines a function to server HTTP requests.
|
||||
// HandlerFunc defines a function to serve HTTP requests.
|
||||
HandlerFunc func(Context) error
|
||||
|
||||
// HTTPErrorHandler is a centralized HTTP error handler.
|
||||
@ -120,21 +124,22 @@ type (
|
||||
|
||||
// i is the interface for Echo and Group.
|
||||
i interface {
|
||||
GET(string, HandlerFunc, ...MiddlewareFunc)
|
||||
GET(string, HandlerFunc, ...MiddlewareFunc) *Route
|
||||
}
|
||||
)
|
||||
|
||||
// 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
|
||||
@ -164,28 +169,35 @@ const (
|
||||
|
||||
// Headers
|
||||
const (
|
||||
HeaderAcceptEncoding = "Accept-Encoding"
|
||||
HeaderAllow = "Allow"
|
||||
HeaderAuthorization = "Authorization"
|
||||
HeaderContentDisposition = "Content-Disposition"
|
||||
HeaderContentEncoding = "Content-Encoding"
|
||||
HeaderContentLength = "Content-Length"
|
||||
HeaderContentType = "Content-Type"
|
||||
HeaderCookie = "Cookie"
|
||||
HeaderSetCookie = "Set-Cookie"
|
||||
HeaderIfModifiedSince = "If-Modified-Since"
|
||||
HeaderLastModified = "Last-Modified"
|
||||
HeaderLocation = "Location"
|
||||
HeaderUpgrade = "Upgrade"
|
||||
HeaderVary = "Vary"
|
||||
HeaderWWWAuthenticate = "WWW-Authenticate"
|
||||
HeaderXForwardedProto = "X-Forwarded-Proto"
|
||||
HeaderXHTTPMethodOverride = "X-HTTP-Method-Override"
|
||||
HeaderXForwardedFor = "X-Forwarded-For"
|
||||
HeaderXRealIP = "X-Real-IP"
|
||||
HeaderXRequestID = "X-Request-ID"
|
||||
HeaderServer = "Server"
|
||||
HeaderOrigin = "Origin"
|
||||
HeaderAccept = "Accept"
|
||||
HeaderAcceptEncoding = "Accept-Encoding"
|
||||
HeaderAllow = "Allow"
|
||||
HeaderAuthorization = "Authorization"
|
||||
HeaderContentDisposition = "Content-Disposition"
|
||||
HeaderContentEncoding = "Content-Encoding"
|
||||
HeaderContentLength = "Content-Length"
|
||||
HeaderContentType = "Content-Type"
|
||||
HeaderCookie = "Cookie"
|
||||
HeaderSetCookie = "Set-Cookie"
|
||||
HeaderIfModifiedSince = "If-Modified-Since"
|
||||
HeaderLastModified = "Last-Modified"
|
||||
HeaderLocation = "Location"
|
||||
HeaderUpgrade = "Upgrade"
|
||||
HeaderVary = "Vary"
|
||||
HeaderWWWAuthenticate = "WWW-Authenticate"
|
||||
HeaderXForwardedFor = "X-Forwarded-For"
|
||||
HeaderXForwardedProto = "X-Forwarded-Proto"
|
||||
HeaderXForwardedProtocol = "X-Forwarded-Protocol"
|
||||
HeaderXForwardedSsl = "X-Forwarded-Ssl"
|
||||
HeaderXUrlScheme = "X-Url-Scheme"
|
||||
HeaderXHTTPMethodOverride = "X-HTTP-Method-Override"
|
||||
HeaderXRealIP = "X-Real-IP"
|
||||
HeaderXRequestID = "X-Request-ID"
|
||||
HeaderXRequestedWith = "X-Requested-With"
|
||||
HeaderServer = "Server"
|
||||
HeaderOrigin = "Origin"
|
||||
|
||||
// Access control
|
||||
HeaderAccessControlRequestMethod = "Access-Control-Request-Method"
|
||||
HeaderAccessControlRequestHeaders = "Access-Control-Request-Headers"
|
||||
HeaderAccessControlAllowOrigin = "Access-Control-Allow-Origin"
|
||||
@ -204,6 +216,22 @@ const (
|
||||
HeaderXCSRFToken = "X-CSRF-Token"
|
||||
)
|
||||
|
||||
const (
|
||||
Version = "3.3.6"
|
||||
website = "https://echo.labstack.com"
|
||||
// http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo
|
||||
banner = `
|
||||
____ __
|
||||
/ __/___/ / ___
|
||||
/ _// __/ _ \/ _ \
|
||||
/___/\__/_//_/\___/ %s
|
||||
High performance, minimalist Go web framework
|
||||
%s
|
||||
____________________________________O/_______
|
||||
O\
|
||||
`
|
||||
)
|
||||
|
||||
var (
|
||||
methods = [...]string{
|
||||
CONNECT,
|
||||
@ -213,6 +241,7 @@ var (
|
||||
OPTIONS,
|
||||
PATCH,
|
||||
POST,
|
||||
PROPFIND,
|
||||
PUT,
|
||||
TRACE,
|
||||
}
|
||||
@ -226,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
|
||||
@ -259,7 +288,7 @@ func New() (e *Echo) {
|
||||
e.TLSServer.Handler = e
|
||||
e.HTTPErrorHandler = e.DefaultHTTPErrorHandler
|
||||
e.Binder = &DefaultBinder{}
|
||||
e.Logger.SetLevel(log.OFF)
|
||||
e.Logger.SetLevel(log.ERROR)
|
||||
e.stdLogger = stdLog.New(e.Logger.Output(), e.Logger.Prefix()+": ", 0)
|
||||
e.pool.New = func() interface{} {
|
||||
return e.NewContext(nil, nil)
|
||||
@ -296,6 +325,9 @@ func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) {
|
||||
if he, ok := err.(*HTTPError); ok {
|
||||
code = he.Code
|
||||
msg = he.Message
|
||||
if he.Internal != nil {
|
||||
err = fmt.Errorf("%v, %v", err, he.Internal)
|
||||
}
|
||||
} else if e.Debug {
|
||||
msg = err.Error()
|
||||
} else {
|
||||
@ -305,19 +337,17 @@ func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) {
|
||||
msg = Map{"message": msg}
|
||||
}
|
||||
|
||||
// Send response
|
||||
if !c.Response().Committed {
|
||||
if c.Request().Method == HEAD { // Issue #608
|
||||
if err := c.NoContent(code); err != nil {
|
||||
goto ERROR
|
||||
}
|
||||
err = c.NoContent(code)
|
||||
} else {
|
||||
if err := c.JSON(code, msg); err != nil {
|
||||
goto ERROR
|
||||
}
|
||||
err = c.JSON(code, msg)
|
||||
}
|
||||
if err != nil {
|
||||
e.Logger.Error(err)
|
||||
}
|
||||
}
|
||||
ERROR:
|
||||
e.Logger.Error(err)
|
||||
}
|
||||
|
||||
// Pre adds middleware to the chain which is run before router.
|
||||
@ -332,104 +362,114 @@ func (e *Echo) Use(middleware ...MiddlewareFunc) {
|
||||
|
||||
// CONNECT registers a new CONNECT route for a path with matching handler in the
|
||||
// router with optional route-level middleware.
|
||||
func (e *Echo) CONNECT(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||
e.add(CONNECT, path, h, m...)
|
||||
func (e *Echo) CONNECT(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||
return e.Add(CONNECT, path, h, m...)
|
||||
}
|
||||
|
||||
// DELETE registers a new DELETE route for a path with matching handler in the router
|
||||
// with optional route-level middleware.
|
||||
func (e *Echo) DELETE(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||
e.add(DELETE, path, h, m...)
|
||||
func (e *Echo) DELETE(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||
return e.Add(DELETE, path, h, m...)
|
||||
}
|
||||
|
||||
// GET registers a new GET route for a path with matching handler in the router
|
||||
// with optional route-level middleware.
|
||||
func (e *Echo) GET(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||
e.add(GET, path, h, m...)
|
||||
func (e *Echo) GET(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||
return e.Add(GET, path, h, m...)
|
||||
}
|
||||
|
||||
// HEAD registers a new HEAD route for a path with matching handler in the
|
||||
// router with optional route-level middleware.
|
||||
func (e *Echo) HEAD(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||
e.add(HEAD, path, h, m...)
|
||||
func (e *Echo) HEAD(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||
return e.Add(HEAD, path, h, m...)
|
||||
}
|
||||
|
||||
// OPTIONS registers a new OPTIONS route for a path with matching handler in the
|
||||
// router with optional route-level middleware.
|
||||
func (e *Echo) OPTIONS(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||
e.add(OPTIONS, path, h, m...)
|
||||
func (e *Echo) OPTIONS(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||
return e.Add(OPTIONS, path, h, m...)
|
||||
}
|
||||
|
||||
// PATCH registers a new PATCH route for a path with matching handler in the
|
||||
// router with optional route-level middleware.
|
||||
func (e *Echo) PATCH(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||
e.add(PATCH, path, h, m...)
|
||||
func (e *Echo) PATCH(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||
return e.Add(PATCH, path, h, m...)
|
||||
}
|
||||
|
||||
// POST registers a new POST route for a path with matching handler in the
|
||||
// router with optional route-level middleware.
|
||||
func (e *Echo) POST(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||
e.add(POST, path, h, m...)
|
||||
func (e *Echo) POST(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||
return e.Add(POST, path, h, m...)
|
||||
}
|
||||
|
||||
// PUT registers a new PUT route for a path with matching handler in the
|
||||
// router with optional route-level middleware.
|
||||
func (e *Echo) PUT(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||
e.add(PUT, path, h, m...)
|
||||
func (e *Echo) PUT(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||
return e.Add(PUT, path, h, m...)
|
||||
}
|
||||
|
||||
// TRACE registers a new TRACE route for a path with matching handler in the
|
||||
// router with optional route-level middleware.
|
||||
func (e *Echo) TRACE(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
||||
e.add(TRACE, path, h, m...)
|
||||
func (e *Echo) TRACE(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||
return e.Add(TRACE, path, h, m...)
|
||||
}
|
||||
|
||||
// Any registers a new route for all HTTP methods and path with matching handler
|
||||
// in the router with optional route-level middleware.
|
||||
func (e *Echo) Any(path string, handler HandlerFunc, middleware ...MiddlewareFunc) {
|
||||
for _, m := range methods {
|
||||
e.add(m, path, handler, middleware...)
|
||||
func (e *Echo) Any(path string, handler HandlerFunc, middleware ...MiddlewareFunc) []*Route {
|
||||
routes := make([]*Route, len(methods))
|
||||
for i, m := range methods {
|
||||
routes[i] = e.Add(m, path, handler, middleware...)
|
||||
}
|
||||
return routes
|
||||
}
|
||||
|
||||
// Match registers a new route for multiple HTTP methods and path with matching
|
||||
// handler in the router with optional route-level middleware.
|
||||
func (e *Echo) Match(methods []string, path string, handler HandlerFunc, middleware ...MiddlewareFunc) {
|
||||
for _, m := range methods {
|
||||
e.add(m, path, handler, middleware...)
|
||||
func (e *Echo) Match(methods []string, path string, handler HandlerFunc, middleware ...MiddlewareFunc) []*Route {
|
||||
routes := make([]*Route, len(methods))
|
||||
for i, m := range methods {
|
||||
routes[i] = e.Add(m, path, handler, middleware...)
|
||||
}
|
||||
return routes
|
||||
}
|
||||
|
||||
// Static registers a new route with path prefix to serve static files from the
|
||||
// provided root directory.
|
||||
func (e *Echo) Static(prefix, root string) {
|
||||
func (e *Echo) Static(prefix, root string) *Route {
|
||||
if root == "" {
|
||||
root = "." // For security we want to restrict to CWD.
|
||||
}
|
||||
static(e, prefix, root)
|
||||
return static(e, prefix, root)
|
||||
}
|
||||
|
||||
func static(i i, prefix, root string) {
|
||||
func static(i i, prefix, root string) *Route {
|
||||
h := func(c Context) error {
|
||||
name := filepath.Join(root, path.Clean("/"+c.Param("*"))) // "/"+ for security
|
||||
p, err := url.PathUnescape(c.Param("*"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name := filepath.Join(root, path.Clean("/"+p)) // "/"+ for security
|
||||
return c.File(name)
|
||||
}
|
||||
i.GET(prefix, h)
|
||||
if prefix == "/" {
|
||||
i.GET(prefix+"*", h)
|
||||
} else {
|
||||
i.GET(prefix+"/*", h)
|
||||
return i.GET(prefix+"*", h)
|
||||
}
|
||||
|
||||
return i.GET(prefix+"/*", h)
|
||||
}
|
||||
|
||||
// File registers a new route with path to serve a static file.
|
||||
func (e *Echo) File(path, file string) {
|
||||
e.GET(path, func(c Context) error {
|
||||
// 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 {
|
||||
return c.File(file)
|
||||
})
|
||||
}, m...)
|
||||
}
|
||||
|
||||
func (e *Echo) add(method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) {
|
||||
// Add registers a new route for an HTTP method and path with matching handler
|
||||
// in the router with optional route-level middleware.
|
||||
func (e *Echo) Add(method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route {
|
||||
name := handlerName(handler)
|
||||
e.router.Add(method, path, func(c Context) error {
|
||||
h := handler
|
||||
@ -439,12 +479,13 @@ func (e *Echo) add(method, path string, handler HandlerFunc, middleware ...Middl
|
||||
}
|
||||
return h(c)
|
||||
})
|
||||
r := Route{
|
||||
Method: method,
|
||||
Path: path,
|
||||
Handler: name,
|
||||
r := &Route{
|
||||
Method: method,
|
||||
Path: path,
|
||||
Name: name,
|
||||
}
|
||||
e.router.routes[method+path] = r
|
||||
return r
|
||||
}
|
||||
|
||||
// Group creates a new router group with prefix and optional group-level middleware.
|
||||
@ -456,12 +497,22 @@ func (e *Echo) Group(prefix string, m ...MiddlewareFunc) (g *Group) {
|
||||
|
||||
// URI generates a URI from handler.
|
||||
func (e *Echo) URI(handler HandlerFunc, params ...interface{}) string {
|
||||
name := handlerName(handler)
|
||||
return e.Reverse(name, params...)
|
||||
}
|
||||
|
||||
// URL is an alias for `URI` function.
|
||||
func (e *Echo) URL(h HandlerFunc, params ...interface{}) string {
|
||||
return e.URI(h, params...)
|
||||
}
|
||||
|
||||
// Reverse generates an URL from route name and provided parameters.
|
||||
func (e *Echo) Reverse(name string, params ...interface{}) string {
|
||||
uri := new(bytes.Buffer)
|
||||
ln := len(params)
|
||||
n := 0
|
||||
name := handlerName(handler)
|
||||
for _, r := range e.router.routes {
|
||||
if r.Handler == name {
|
||||
if r.Name == name {
|
||||
for i, l := 0, len(r.Path); i < l; i++ {
|
||||
if r.Path[i] == ':' && n < ln {
|
||||
for ; i < l && r.Path[i] != '/'; i++ {
|
||||
@ -479,14 +530,9 @@ func (e *Echo) URI(handler HandlerFunc, params ...interface{}) string {
|
||||
return uri.String()
|
||||
}
|
||||
|
||||
// URL is an alias for `URI` function.
|
||||
func (e *Echo) URL(h HandlerFunc, params ...interface{}) string {
|
||||
return e.URI(h, params...)
|
||||
}
|
||||
|
||||
// Routes returns the registered routes.
|
||||
func (e *Echo) Routes() []Route {
|
||||
routes := []Route{}
|
||||
func (e *Echo) Routes() []*Route {
|
||||
routes := make([]*Route, 0, len(e.router.routes))
|
||||
for _, v := range e.router.routes {
|
||||
routes = append(routes, v)
|
||||
}
|
||||
@ -507,39 +553,39 @@ 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
|
||||
path := r.URL.RawPath
|
||||
if path == "" {
|
||||
path = r.URL.Path
|
||||
}
|
||||
e.router.Find(method, path, c)
|
||||
h := c.Handler()
|
||||
h := NotFoundHandler
|
||||
|
||||
if e.premiddleware == nil {
|
||||
e.router.Find(r.Method, 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 {
|
||||
e.router.Find(r.Method, 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.
|
||||
@ -565,6 +611,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
|
||||
@ -584,8 +634,15 @@ func (e *Echo) startTLS(address string) error {
|
||||
func (e *Echo) StartServer(s *http.Server) (err error) {
|
||||
// Setup
|
||||
e.colorer.SetOutput(e.Logger.Output())
|
||||
s.Handler = e
|
||||
s.ErrorLog = e.stdLogger
|
||||
s.Handler = e
|
||||
if e.Debug {
|
||||
e.Logger.SetLevel(log.DEBUG)
|
||||
}
|
||||
|
||||
if !e.HideBanner {
|
||||
e.colorer.Printf(banner, e.colorer.Red("v"+Version), e.colorer.Blue(website))
|
||||
}
|
||||
|
||||
if s.TLSConfig == nil {
|
||||
if e.Listener == nil {
|
||||
@ -594,7 +651,9 @@ func (e *Echo) StartServer(s *http.Server) (err error) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
e.colorer.Printf("⇛ http server started on %s\n", e.colorer.Green(e.Listener.Addr()))
|
||||
if !e.HidePort {
|
||||
e.colorer.Printf("⇨ http server started on %s\n", e.colorer.Green(e.Listener.Addr()))
|
||||
}
|
||||
return s.Serve(e.Listener)
|
||||
}
|
||||
if e.TLSListener == nil {
|
||||
@ -604,10 +663,30 @@ func (e *Echo) StartServer(s *http.Server) (err error) {
|
||||
}
|
||||
e.TLSListener = tls.NewListener(l, s.TLSConfig)
|
||||
}
|
||||
e.colorer.Printf("⇛ https server started on %s\n", e.colorer.Green(e.TLSListener.Addr()))
|
||||
if !e.HidePort {
|
||||
e.colorer.Printf("⇨ https server started on %s\n", e.colorer.Green(e.TLSListener.Addr()))
|
||||
}
|
||||
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)}
|
||||
@ -619,7 +698,7 @@ func NewHTTPError(code int, message ...interface{}) *HTTPError {
|
||||
|
||||
// Error makes it compatible with `error` interface.
|
||||
func (he *HTTPError) Error() string {
|
||||
return fmt.Sprintf("code=%d, message=%s", he.Code, he.Message)
|
||||
return fmt.Sprintf("code=%d, message=%v", he.Code, he.Message)
|
||||
}
|
||||
|
||||
// WrapHandler wraps `http.Handler` into `echo.HandlerFunc`.
|
||||
@ -643,6 +722,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 {
|
||||
@ -651,6 +738,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
|
||||
|
Reference in New Issue
Block a user