Blame vendor/github.com/labstack/echo/v4/echo.go

Packit Service 509fd4
/*
Packit Service 509fd4
Package echo implements high performance, minimalist Go web framework.
Packit Service 509fd4
Packit Service 509fd4
Example:
Packit Service 509fd4
Packit Service 509fd4
  package main
Packit Service 509fd4
Packit Service 509fd4
  import (
Packit Service 509fd4
    "net/http"
Packit Service 509fd4
Packit Service 509fd4
    "github.com/labstack/echo/v4"
Packit Service 509fd4
    "github.com/labstack/echo/v4/middleware"
Packit Service 509fd4
  )
Packit Service 509fd4
Packit Service 509fd4
  // Handler
Packit Service 509fd4
  func hello(c echo.Context) error {
Packit Service 509fd4
    return c.String(http.StatusOK, "Hello, World!")
Packit Service 509fd4
  }
Packit Service 509fd4
Packit Service 509fd4
  func main() {
Packit Service 509fd4
    // Echo instance
Packit Service 509fd4
    e := echo.New()
Packit Service 509fd4
Packit Service 509fd4
    // Middleware
Packit Service 509fd4
    e.Use(middleware.Logger())
Packit Service 509fd4
    e.Use(middleware.Recover())
Packit Service 509fd4
Packit Service 509fd4
    // Routes
Packit Service 509fd4
    e.GET("/", hello)
Packit Service 509fd4
Packit Service 509fd4
    // Start server
Packit Service 509fd4
    e.Logger.Fatal(e.Start(":1323"))
Packit Service 509fd4
  }
Packit Service 509fd4
Packit Service 509fd4
Learn more at https://echo.labstack.com
Packit Service 509fd4
*/
Packit Service 509fd4
package echo
Packit Service 509fd4
Packit Service 509fd4
import (
Packit Service 509fd4
	"bytes"
Packit Service 509fd4
	stdContext "context"
Packit Service 509fd4
	"crypto/tls"
Packit Service 509fd4
	"errors"
Packit Service 509fd4
	"fmt"
Packit Service 509fd4
	"io"
Packit Service 509fd4
	"io/ioutil"
Packit Service 509fd4
	stdLog "log"
Packit Service 509fd4
	"net"
Packit Service 509fd4
	"net/http"
Packit Service 509fd4
	"net/url"
Packit Service 509fd4
	"path"
Packit Service 509fd4
	"path/filepath"
Packit Service 509fd4
	"reflect"
Packit Service 509fd4
	"runtime"
Packit Service 509fd4
	"sync"
Packit Service 509fd4
	"time"
Packit Service 509fd4
Packit Service 509fd4
	"github.com/labstack/gommon/color"
Packit Service 509fd4
	"github.com/labstack/gommon/log"
Packit Service 509fd4
	"golang.org/x/crypto/acme"
Packit Service 509fd4
	"golang.org/x/crypto/acme/autocert"
Packit Service 509fd4
)
Packit Service 509fd4
Packit Service 509fd4
type (
Packit Service 509fd4
	// Echo is the top-level framework instance.
Packit Service 509fd4
	Echo struct {
Packit Service 509fd4
		common
Packit Service 509fd4
		StdLogger        *stdLog.Logger
Packit Service 509fd4
		colorer          *color.Color
Packit Service 509fd4
		premiddleware    []MiddlewareFunc
Packit Service 509fd4
		middleware       []MiddlewareFunc
Packit Service 509fd4
		maxParam         *int
Packit Service 509fd4
		router           *Router
Packit Service 509fd4
		routers          map[string]*Router
Packit Service 509fd4
		notFoundHandler  HandlerFunc
Packit Service 509fd4
		pool             sync.Pool
Packit Service 509fd4
		Server           *http.Server
Packit Service 509fd4
		TLSServer        *http.Server
Packit Service 509fd4
		Listener         net.Listener
Packit Service 509fd4
		TLSListener      net.Listener
Packit Service 509fd4
		AutoTLSManager   autocert.Manager
Packit Service 509fd4
		DisableHTTP2     bool
Packit Service 509fd4
		Debug            bool
Packit Service 509fd4
		HideBanner       bool
Packit Service 509fd4
		HidePort         bool
Packit Service 509fd4
		HTTPErrorHandler HTTPErrorHandler
Packit Service 509fd4
		Binder           Binder
Packit Service 509fd4
		Validator        Validator
Packit Service 509fd4
		Renderer         Renderer
Packit Service 509fd4
		Logger           Logger
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	// Route contains a handler and information for matching against requests.
Packit Service 509fd4
	Route struct {
Packit Service 509fd4
		Method string `json:"method"`
Packit Service 509fd4
		Path   string `json:"path"`
Packit Service 509fd4
		Name   string `json:"name"`
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	// HTTPError represents an error that occurred while handling a request.
Packit Service 509fd4
	HTTPError struct {
Packit Service 509fd4
		Code     int         `json:"-"`
Packit Service 509fd4
		Message  interface{} `json:"message"`
Packit Service 509fd4
		Internal error       `json:"-"` // Stores the error returned by an external dependency
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	// MiddlewareFunc defines a function to process middleware.
Packit Service 509fd4
	MiddlewareFunc func(HandlerFunc) HandlerFunc
Packit Service 509fd4
Packit Service 509fd4
	// HandlerFunc defines a function to serve HTTP requests.
Packit Service 509fd4
	HandlerFunc func(Context) error
Packit Service 509fd4
Packit Service 509fd4
	// HTTPErrorHandler is a centralized HTTP error handler.
Packit Service 509fd4
	HTTPErrorHandler func(error, Context)
Packit Service 509fd4
Packit Service 509fd4
	// Validator is the interface that wraps the Validate function.
Packit Service 509fd4
	Validator interface {
Packit Service 509fd4
		Validate(i interface{}) error
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	// Renderer is the interface that wraps the Render function.
Packit Service 509fd4
	Renderer interface {
Packit Service 509fd4
		Render(io.Writer, string, interface{}, Context) error
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	// Map defines a generic map of type `map[string]interface{}`.
Packit Service 509fd4
	Map map[string]interface{}
Packit Service 509fd4
Packit Service 509fd4
	// Common struct for Echo & Group.
Packit Service 509fd4
	common struct{}
Packit Service 509fd4
)
Packit Service 509fd4
Packit Service 509fd4
// HTTP methods
Packit Service 509fd4
// NOTE: Deprecated, please use the stdlib constants directly instead.
Packit Service 509fd4
const (
Packit Service 509fd4
	CONNECT = http.MethodConnect
Packit Service 509fd4
	DELETE  = http.MethodDelete
Packit Service 509fd4
	GET     = http.MethodGet
Packit Service 509fd4
	HEAD    = http.MethodHead
Packit Service 509fd4
	OPTIONS = http.MethodOptions
Packit Service 509fd4
	PATCH   = http.MethodPatch
Packit Service 509fd4
	POST    = http.MethodPost
Packit Service 509fd4
	// PROPFIND = "PROPFIND"
Packit Service 509fd4
	PUT   = http.MethodPut
Packit Service 509fd4
	TRACE = http.MethodTrace
Packit Service 509fd4
)
Packit Service 509fd4
Packit Service 509fd4
// MIME types
Packit Service 509fd4
const (
Packit Service 509fd4
	MIMEApplicationJSON                  = "application/json"
Packit Service 509fd4
	MIMEApplicationJSONCharsetUTF8       = MIMEApplicationJSON + "; " + charsetUTF8
Packit Service 509fd4
	MIMEApplicationJavaScript            = "application/javascript"
Packit Service 509fd4
	MIMEApplicationJavaScriptCharsetUTF8 = MIMEApplicationJavaScript + "; " + charsetUTF8
Packit Service 509fd4
	MIMEApplicationXML                   = "application/xml"
Packit Service 509fd4
	MIMEApplicationXMLCharsetUTF8        = MIMEApplicationXML + "; " + charsetUTF8
Packit Service 509fd4
	MIMETextXML                          = "text/xml"
Packit Service 509fd4
	MIMETextXMLCharsetUTF8               = MIMETextXML + "; " + charsetUTF8
Packit Service 509fd4
	MIMEApplicationForm                  = "application/x-www-form-urlencoded"
Packit Service 509fd4
	MIMEApplicationProtobuf              = "application/protobuf"
Packit Service 509fd4
	MIMEApplicationMsgpack               = "application/msgpack"
Packit Service 509fd4
	MIMETextHTML                         = "text/html"
Packit Service 509fd4
	MIMETextHTMLCharsetUTF8              = MIMETextHTML + "; " + charsetUTF8
Packit Service 509fd4
	MIMETextPlain                        = "text/plain"
Packit Service 509fd4
	MIMETextPlainCharsetUTF8             = MIMETextPlain + "; " + charsetUTF8
Packit Service 509fd4
	MIMEMultipartForm                    = "multipart/form-data"
Packit Service 509fd4
	MIMEOctetStream                      = "application/octet-stream"
Packit Service 509fd4
)
Packit Service 509fd4
Packit Service 509fd4
const (
Packit Service 509fd4
	charsetUTF8 = "charset=UTF-8"
Packit Service 509fd4
	// PROPFIND Method can be used on collection and property resources.
Packit Service 509fd4
	PROPFIND = "PROPFIND"
Packit Service 509fd4
	// REPORT Method can be used to get information about a resource, see rfc 3253
Packit Service 509fd4
	REPORT = "REPORT"
Packit Service 509fd4
)
Packit Service 509fd4
Packit Service 509fd4
// Headers
Packit Service 509fd4
const (
Packit Service 509fd4
	HeaderAccept              = "Accept"
Packit Service 509fd4
	HeaderAcceptEncoding      = "Accept-Encoding"
Packit Service 509fd4
	HeaderAllow               = "Allow"
Packit Service 509fd4
	HeaderAuthorization       = "Authorization"
Packit Service 509fd4
	HeaderContentDisposition  = "Content-Disposition"
Packit Service 509fd4
	HeaderContentEncoding     = "Content-Encoding"
Packit Service 509fd4
	HeaderContentLength       = "Content-Length"
Packit Service 509fd4
	HeaderContentType         = "Content-Type"
Packit Service 509fd4
	HeaderCookie              = "Cookie"
Packit Service 509fd4
	HeaderSetCookie           = "Set-Cookie"
Packit Service 509fd4
	HeaderIfModifiedSince     = "If-Modified-Since"
Packit Service 509fd4
	HeaderLastModified        = "Last-Modified"
Packit Service 509fd4
	HeaderLocation            = "Location"
Packit Service 509fd4
	HeaderUpgrade             = "Upgrade"
Packit Service 509fd4
	HeaderVary                = "Vary"
Packit Service 509fd4
	HeaderWWWAuthenticate     = "WWW-Authenticate"
Packit Service 509fd4
	HeaderXForwardedFor       = "X-Forwarded-For"
Packit Service 509fd4
	HeaderXForwardedProto     = "X-Forwarded-Proto"
Packit Service 509fd4
	HeaderXForwardedProtocol  = "X-Forwarded-Protocol"
Packit Service 509fd4
	HeaderXForwardedSsl       = "X-Forwarded-Ssl"
Packit Service 509fd4
	HeaderXUrlScheme          = "X-Url-Scheme"
Packit Service 509fd4
	HeaderXHTTPMethodOverride = "X-HTTP-Method-Override"
Packit Service 509fd4
	HeaderXRealIP             = "X-Real-IP"
Packit Service 509fd4
	HeaderXRequestID          = "X-Request-ID"
Packit Service 509fd4
	HeaderXRequestedWith      = "X-Requested-With"
Packit Service 509fd4
	HeaderServer              = "Server"
Packit Service 509fd4
	HeaderOrigin              = "Origin"
Packit Service 509fd4
Packit Service 509fd4
	// Access control
Packit Service 509fd4
	HeaderAccessControlRequestMethod    = "Access-Control-Request-Method"
Packit Service 509fd4
	HeaderAccessControlRequestHeaders   = "Access-Control-Request-Headers"
Packit Service 509fd4
	HeaderAccessControlAllowOrigin      = "Access-Control-Allow-Origin"
Packit Service 509fd4
	HeaderAccessControlAllowMethods     = "Access-Control-Allow-Methods"
Packit Service 509fd4
	HeaderAccessControlAllowHeaders     = "Access-Control-Allow-Headers"
Packit Service 509fd4
	HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials"
Packit Service 509fd4
	HeaderAccessControlExposeHeaders    = "Access-Control-Expose-Headers"
Packit Service 509fd4
	HeaderAccessControlMaxAge           = "Access-Control-Max-Age"
Packit Service 509fd4
Packit Service 509fd4
	// Security
Packit Service 509fd4
	HeaderStrictTransportSecurity         = "Strict-Transport-Security"
Packit Service 509fd4
	HeaderXContentTypeOptions             = "X-Content-Type-Options"
Packit Service 509fd4
	HeaderXXSSProtection                  = "X-XSS-Protection"
Packit Service 509fd4
	HeaderXFrameOptions                   = "X-Frame-Options"
Packit Service 509fd4
	HeaderContentSecurityPolicy           = "Content-Security-Policy"
Packit Service 509fd4
	HeaderContentSecurityPolicyReportOnly = "Content-Security-Policy-Report-Only"
Packit Service 509fd4
	HeaderXCSRFToken                      = "X-CSRF-Token"
Packit Service 509fd4
	HeaderReferrerPolicy                  = "Referrer-Policy"
Packit Service 509fd4
)
Packit Service 509fd4
Packit Service 509fd4
const (
Packit Service 509fd4
	// Version of Echo
Packit Service 509fd4
	Version = "4.1.11"
Packit Service 509fd4
	website = "https://echo.labstack.com"
Packit Service 509fd4
	// http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo
Packit Service 509fd4
	banner = `
Packit Service 509fd4
   ____    __
Packit Service 509fd4
  / __/___/ /  ___
Packit Service 509fd4
 / _// __/ _ \/ _ \
Packit Service 509fd4
/___/\__/_//_/\___/ %s
Packit Service 509fd4
High performance, minimalist Go web framework
Packit Service 509fd4
%s
Packit Service 509fd4
____________________________________O/_______
Packit Service 509fd4
                                    O\
Packit Service 509fd4
`
Packit Service 509fd4
)
Packit Service 509fd4
Packit Service 509fd4
var (
Packit Service 509fd4
	methods = [...]string{
Packit Service 509fd4
		http.MethodConnect,
Packit Service 509fd4
		http.MethodDelete,
Packit Service 509fd4
		http.MethodGet,
Packit Service 509fd4
		http.MethodHead,
Packit Service 509fd4
		http.MethodOptions,
Packit Service 509fd4
		http.MethodPatch,
Packit Service 509fd4
		http.MethodPost,
Packit Service 509fd4
		PROPFIND,
Packit Service 509fd4
		http.MethodPut,
Packit Service 509fd4
		http.MethodTrace,
Packit Service 509fd4
		REPORT,
Packit Service 509fd4
	}
Packit Service 509fd4
)
Packit Service 509fd4
Packit Service 509fd4
// Errors
Packit Service 509fd4
var (
Packit Service 509fd4
	ErrUnsupportedMediaType        = NewHTTPError(http.StatusUnsupportedMediaType)
Packit Service 509fd4
	ErrNotFound                    = NewHTTPError(http.StatusNotFound)
Packit Service 509fd4
	ErrUnauthorized                = NewHTTPError(http.StatusUnauthorized)
Packit Service 509fd4
	ErrForbidden                   = NewHTTPError(http.StatusForbidden)
Packit Service 509fd4
	ErrMethodNotAllowed            = NewHTTPError(http.StatusMethodNotAllowed)
Packit Service 509fd4
	ErrStatusRequestEntityTooLarge = NewHTTPError(http.StatusRequestEntityTooLarge)
Packit Service 509fd4
	ErrTooManyRequests             = NewHTTPError(http.StatusTooManyRequests)
Packit Service 509fd4
	ErrBadRequest                  = NewHTTPError(http.StatusBadRequest)
Packit Service 509fd4
	ErrBadGateway                  = NewHTTPError(http.StatusBadGateway)
Packit Service 509fd4
	ErrInternalServerError         = NewHTTPError(http.StatusInternalServerError)
Packit Service 509fd4
	ErrRequestTimeout              = NewHTTPError(http.StatusRequestTimeout)
Packit Service 509fd4
	ErrServiceUnavailable          = NewHTTPError(http.StatusServiceUnavailable)
Packit Service 509fd4
	ErrValidatorNotRegistered      = errors.New("validator not registered")
Packit Service 509fd4
	ErrRendererNotRegistered       = errors.New("renderer not registered")
Packit Service 509fd4
	ErrInvalidRedirectCode         = errors.New("invalid redirect status code")
Packit Service 509fd4
	ErrCookieNotFound              = errors.New("cookie not found")
Packit Service 509fd4
	ErrInvalidCertOrKeyType        = errors.New("invalid cert or key type, must be string or []byte")
Packit Service 509fd4
)
Packit Service 509fd4
Packit Service 509fd4
// Error handlers
Packit Service 509fd4
var (
Packit Service 509fd4
	NotFoundHandler = func(c Context) error {
Packit Service 509fd4
		return ErrNotFound
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	MethodNotAllowedHandler = func(c Context) error {
Packit Service 509fd4
		return ErrMethodNotAllowed
Packit Service 509fd4
	}
Packit Service 509fd4
)
Packit Service 509fd4
Packit Service 509fd4
// New creates an instance of Echo.
Packit Service 509fd4
func New() (e *Echo) {
Packit Service 509fd4
	e = &Echo{
Packit Service 509fd4
		Server:    new(http.Server),
Packit Service 509fd4
		TLSServer: new(http.Server),
Packit Service 509fd4
		AutoTLSManager: autocert.Manager{
Packit Service 509fd4
			Prompt: autocert.AcceptTOS,
Packit Service 509fd4
		},
Packit Service 509fd4
		Logger:   log.New("echo"),
Packit Service 509fd4
		colorer:  color.New(),
Packit Service 509fd4
		maxParam: new(int),
Packit Service 509fd4
	}
Packit Service 509fd4
	e.Server.Handler = e
Packit Service 509fd4
	e.TLSServer.Handler = e
Packit Service 509fd4
	e.HTTPErrorHandler = e.DefaultHTTPErrorHandler
Packit Service 509fd4
	e.Binder = &DefaultBinder{}
Packit Service 509fd4
	e.Logger.SetLevel(log.ERROR)
Packit Service 509fd4
	e.StdLogger = stdLog.New(e.Logger.Output(), e.Logger.Prefix()+": ", 0)
Packit Service 509fd4
	e.pool.New = func() interface{} {
Packit Service 509fd4
		return e.NewContext(nil, nil)
Packit Service 509fd4
	}
Packit Service 509fd4
	e.router = NewRouter(e)
Packit Service 509fd4
	e.routers = map[string]*Router{}
Packit Service 509fd4
	return
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// NewContext returns a Context instance.
Packit Service 509fd4
func (e *Echo) NewContext(r *http.Request, w http.ResponseWriter) Context {
Packit Service 509fd4
	return &context{
Packit Service 509fd4
		request:  r,
Packit Service 509fd4
		response: NewResponse(w, e),
Packit Service 509fd4
		store:    make(Map),
Packit Service 509fd4
		echo:     e,
Packit Service 509fd4
		pvalues:  make([]string, *e.maxParam),
Packit Service 509fd4
		handler:  NotFoundHandler,
Packit Service 509fd4
	}
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// Router returns the default router.
Packit Service 509fd4
func (e *Echo) Router() *Router {
Packit Service 509fd4
	return e.router
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// Routers returns the map of host => router.
Packit Service 509fd4
func (e *Echo) Routers() map[string]*Router {
Packit Service 509fd4
	return e.routers
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// DefaultHTTPErrorHandler is the default HTTP error handler. It sends a JSON response
Packit Service 509fd4
// with status code.
Packit Service 509fd4
func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) {
Packit Service 509fd4
	he, ok := err.(*HTTPError)
Packit Service 509fd4
	if ok {
Packit Service 509fd4
		if he.Internal != nil {
Packit Service 509fd4
			if herr, ok := he.Internal.(*HTTPError); ok {
Packit Service 509fd4
				he = herr
Packit Service 509fd4
			}
Packit Service 509fd4
		}
Packit Service 509fd4
	} else {
Packit Service 509fd4
		he = &HTTPError{
Packit Service 509fd4
			Code:    http.StatusInternalServerError,
Packit Service 509fd4
			Message: http.StatusText(http.StatusInternalServerError),
Packit Service 509fd4
		}
Packit Service 509fd4
	}
Packit Service 509fd4
	if e.Debug {
Packit Service 509fd4
		he.Message = err.Error()
Packit Service 509fd4
	} else if m, ok := he.Message.(string); ok {
Packit Service 509fd4
		he.Message = Map{"message": m}
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	// Send response
Packit Service 509fd4
	if !c.Response().Committed {
Packit Service 509fd4
		if c.Request().Method == http.MethodHead { // Issue #608
Packit Service 509fd4
			err = c.NoContent(he.Code)
Packit Service 509fd4
		} else {
Packit Service 509fd4
			err = c.JSON(he.Code, he.Message)
Packit Service 509fd4
		}
Packit Service 509fd4
		if err != nil {
Packit Service 509fd4
			e.Logger.Error(err)
Packit Service 509fd4
		}
Packit Service 509fd4
	}
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// Pre adds middleware to the chain which is run before router.
Packit Service 509fd4
func (e *Echo) Pre(middleware ...MiddlewareFunc) {
Packit Service 509fd4
	e.premiddleware = append(e.premiddleware, middleware...)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// Use adds middleware to the chain which is run after router.
Packit Service 509fd4
func (e *Echo) Use(middleware ...MiddlewareFunc) {
Packit Service 509fd4
	e.middleware = append(e.middleware, middleware...)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// CONNECT registers a new CONNECT route for a path with matching handler in the
Packit Service 509fd4
// router with optional route-level middleware.
Packit Service 509fd4
func (e *Echo) CONNECT(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
Packit Service 509fd4
	return e.Add(http.MethodConnect, path, h, m...)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// DELETE registers a new DELETE route for a path with matching handler in the router
Packit Service 509fd4
// with optional route-level middleware.
Packit Service 509fd4
func (e *Echo) DELETE(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
Packit Service 509fd4
	return e.Add(http.MethodDelete, path, h, m...)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// GET registers a new GET route for a path with matching handler in the router
Packit Service 509fd4
// with optional route-level middleware.
Packit Service 509fd4
func (e *Echo) GET(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
Packit Service 509fd4
	return e.Add(http.MethodGet, path, h, m...)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// HEAD registers a new HEAD route for a path with matching handler in the
Packit Service 509fd4
// router with optional route-level middleware.
Packit Service 509fd4
func (e *Echo) HEAD(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
Packit Service 509fd4
	return e.Add(http.MethodHead, path, h, m...)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// OPTIONS registers a new OPTIONS route for a path with matching handler in the
Packit Service 509fd4
// router with optional route-level middleware.
Packit Service 509fd4
func (e *Echo) OPTIONS(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
Packit Service 509fd4
	return e.Add(http.MethodOptions, path, h, m...)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// PATCH registers a new PATCH route for a path with matching handler in the
Packit Service 509fd4
// router with optional route-level middleware.
Packit Service 509fd4
func (e *Echo) PATCH(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
Packit Service 509fd4
	return e.Add(http.MethodPatch, path, h, m...)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// POST registers a new POST route for a path with matching handler in the
Packit Service 509fd4
// router with optional route-level middleware.
Packit Service 509fd4
func (e *Echo) POST(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
Packit Service 509fd4
	return e.Add(http.MethodPost, path, h, m...)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// PUT registers a new PUT route for a path with matching handler in the
Packit Service 509fd4
// router with optional route-level middleware.
Packit Service 509fd4
func (e *Echo) PUT(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
Packit Service 509fd4
	return e.Add(http.MethodPut, path, h, m...)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// TRACE registers a new TRACE route for a path with matching handler in the
Packit Service 509fd4
// router with optional route-level middleware.
Packit Service 509fd4
func (e *Echo) TRACE(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
Packit Service 509fd4
	return e.Add(http.MethodTrace, path, h, m...)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// Any registers a new route for all HTTP methods and path with matching handler
Packit Service 509fd4
// in the router with optional route-level middleware.
Packit Service 509fd4
func (e *Echo) Any(path string, handler HandlerFunc, middleware ...MiddlewareFunc) []*Route {
Packit Service 509fd4
	routes := make([]*Route, len(methods))
Packit Service 509fd4
	for i, m := range methods {
Packit Service 509fd4
		routes[i] = e.Add(m, path, handler, middleware...)
Packit Service 509fd4
	}
Packit Service 509fd4
	return routes
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// Match registers a new route for multiple HTTP methods and path with matching
Packit Service 509fd4
// handler in the router with optional route-level middleware.
Packit Service 509fd4
func (e *Echo) Match(methods []string, path string, handler HandlerFunc, middleware ...MiddlewareFunc) []*Route {
Packit Service 509fd4
	routes := make([]*Route, len(methods))
Packit Service 509fd4
	for i, m := range methods {
Packit Service 509fd4
		routes[i] = e.Add(m, path, handler, middleware...)
Packit Service 509fd4
	}
Packit Service 509fd4
	return routes
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// Static registers a new route with path prefix to serve static files from the
Packit Service 509fd4
// provided root directory.
Packit Service 509fd4
func (e *Echo) Static(prefix, root string) *Route {
Packit Service 509fd4
	if root == "" {
Packit Service 509fd4
		root = "." // For security we want to restrict to CWD.
Packit Service 509fd4
	}
Packit Service 509fd4
	return e.static(prefix, root, e.GET)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
func (common) static(prefix, root string, get func(string, HandlerFunc, ...MiddlewareFunc) *Route) *Route {
Packit Service 509fd4
	h := func(c Context) error {
Packit Service 509fd4
		p, err := url.PathUnescape(c.Param("*"))
Packit Service 509fd4
		if err != nil {
Packit Service 509fd4
			return err
Packit Service 509fd4
		}
Packit Service 509fd4
		name := filepath.Join(root, path.Clean("/"+p)) // "/"+ for security
Packit Service 509fd4
		return c.File(name)
Packit Service 509fd4
	}
Packit Service 509fd4
	if prefix == "/" {
Packit Service 509fd4
		return get(prefix+"*", h)
Packit Service 509fd4
	}
Packit Service 509fd4
	return get(prefix+"/*", h)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
func (common) file(path, file string, get func(string, HandlerFunc, ...MiddlewareFunc) *Route,
Packit Service 509fd4
	m ...MiddlewareFunc) *Route {
Packit Service 509fd4
	return get(path, func(c Context) error {
Packit Service 509fd4
		return c.File(file)
Packit Service 509fd4
	}, m...)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// File registers a new route with path to serve a static file with optional route-level middleware.
Packit Service 509fd4
func (e *Echo) File(path, file string, m ...MiddlewareFunc) *Route {
Packit Service 509fd4
	return e.file(path, file, e.GET, m...)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
func (e *Echo) add(host, method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route {
Packit Service 509fd4
	name := handlerName(handler)
Packit Service 509fd4
	router := e.findRouter(host)
Packit Service 509fd4
	router.Add(method, path, func(c Context) error {
Packit Service 509fd4
		h := handler
Packit Service 509fd4
		// Chain middleware
Packit Service 509fd4
		for i := len(middleware) - 1; i >= 0; i-- {
Packit Service 509fd4
			h = middleware[i](h)
Packit Service 509fd4
		}
Packit Service 509fd4
		return h(c)
Packit Service 509fd4
	})
Packit Service 509fd4
	r := &Route{
Packit Service 509fd4
		Method: method,
Packit Service 509fd4
		Path:   path,
Packit Service 509fd4
		Name:   name,
Packit Service 509fd4
	}
Packit Service 509fd4
	e.router.routes[method+path] = r
Packit Service 509fd4
	return r
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// Add registers a new route for an HTTP method and path with matching handler
Packit Service 509fd4
// in the router with optional route-level middleware.
Packit Service 509fd4
func (e *Echo) Add(method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route {
Packit Service 509fd4
	return e.add("", method, path, handler, middleware...)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// Host creates a new router group for the provided host and optional host-level middleware.
Packit Service 509fd4
func (e *Echo) Host(name string, m ...MiddlewareFunc) (g *Group) {
Packit Service 509fd4
	e.routers[name] = NewRouter(e)
Packit Service 509fd4
	g = &Group{host: name, echo: e}
Packit Service 509fd4
	g.Use(m...)
Packit Service 509fd4
	return
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// Group creates a new router group with prefix and optional group-level middleware.
Packit Service 509fd4
func (e *Echo) Group(prefix string, m ...MiddlewareFunc) (g *Group) {
Packit Service 509fd4
	g = &Group{prefix: prefix, echo: e}
Packit Service 509fd4
	g.Use(m...)
Packit Service 509fd4
	return
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// URI generates a URI from handler.
Packit Service 509fd4
func (e *Echo) URI(handler HandlerFunc, params ...interface{}) string {
Packit Service 509fd4
	name := handlerName(handler)
Packit Service 509fd4
	return e.Reverse(name, params...)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// URL is an alias for `URI` function.
Packit Service 509fd4
func (e *Echo) URL(h HandlerFunc, params ...interface{}) string {
Packit Service 509fd4
	return e.URI(h, params...)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// Reverse generates an URL from route name and provided parameters.
Packit Service 509fd4
func (e *Echo) Reverse(name string, params ...interface{}) string {
Packit Service 509fd4
	uri := new(bytes.Buffer)
Packit Service 509fd4
	ln := len(params)
Packit Service 509fd4
	n := 0
Packit Service 509fd4
	for _, r := range e.router.routes {
Packit Service 509fd4
		if r.Name == name {
Packit Service 509fd4
			for i, l := 0, len(r.Path); i < l; i++ {
Packit Service 509fd4
				if r.Path[i] == ':' && n < ln {
Packit Service 509fd4
					for ; i < l && r.Path[i] != '/'; i++ {
Packit Service 509fd4
					}
Packit Service 509fd4
					uri.WriteString(fmt.Sprintf("%v", params[n]))
Packit Service 509fd4
					n++
Packit Service 509fd4
				}
Packit Service 509fd4
				if i < l {
Packit Service 509fd4
					uri.WriteByte(r.Path[i])
Packit Service 509fd4
				}
Packit Service 509fd4
			}
Packit Service 509fd4
			break
Packit Service 509fd4
		}
Packit Service 509fd4
	}
Packit Service 509fd4
	return uri.String()
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// Routes returns the registered routes.
Packit Service 509fd4
func (e *Echo) Routes() []*Route {
Packit Service 509fd4
	routes := make([]*Route, 0, len(e.router.routes))
Packit Service 509fd4
	for _, v := range e.router.routes {
Packit Service 509fd4
		routes = append(routes, v)
Packit Service 509fd4
	}
Packit Service 509fd4
	return routes
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// AcquireContext returns an empty `Context` instance from the pool.
Packit Service 509fd4
// You must return the context by calling `ReleaseContext()`.
Packit Service 509fd4
func (e *Echo) AcquireContext() Context {
Packit Service 509fd4
	return e.pool.Get().(Context)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// ReleaseContext returns the `Context` instance back to the pool.
Packit Service 509fd4
// You must call it after `AcquireContext()`.
Packit Service 509fd4
func (e *Echo) ReleaseContext(c Context) {
Packit Service 509fd4
	e.pool.Put(c)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// ServeHTTP implements `http.Handler` interface, which serves HTTP requests.
Packit Service 509fd4
func (e *Echo) ServeHTTP(w http.ResponseWriter, r *http.Request) {
Packit Service 509fd4
	// Acquire context
Packit Service 509fd4
	c := e.pool.Get().(*context)
Packit Service 509fd4
	c.Reset(r, w)
Packit Service 509fd4
Packit Service 509fd4
	h := NotFoundHandler
Packit Service 509fd4
Packit Service 509fd4
	if e.premiddleware == nil {
Packit Service 509fd4
		e.findRouter(r.Host).Find(r.Method, getPath(r), c)
Packit Service 509fd4
		h = c.Handler()
Packit Service 509fd4
		h = applyMiddleware(h, e.middleware...)
Packit Service 509fd4
	} else {
Packit Service 509fd4
		h = func(c Context) error {
Packit Service 509fd4
			e.findRouter(r.Host).Find(r.Method, getPath(r), c)
Packit Service 509fd4
			h := c.Handler()
Packit Service 509fd4
			h = applyMiddleware(h, e.middleware...)
Packit Service 509fd4
			return h(c)
Packit Service 509fd4
		}
Packit Service 509fd4
		h = applyMiddleware(h, e.premiddleware...)
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	// Execute chain
Packit Service 509fd4
	if err := h(c); err != nil {
Packit Service 509fd4
		e.HTTPErrorHandler(err, c)
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	// Release context
Packit Service 509fd4
	e.pool.Put(c)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// Start starts an HTTP server.
Packit Service 509fd4
func (e *Echo) Start(address string) error {
Packit Service 509fd4
	e.Server.Addr = address
Packit Service 509fd4
	return e.StartServer(e.Server)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// StartTLS starts an HTTPS server.
Packit Service 509fd4
// If `certFile` or `keyFile` is `string` the values are treated as file paths.
Packit Service 509fd4
// If `certFile` or `keyFile` is `[]byte` the values are treated as the certificate or key as-is.
Packit Service 509fd4
func (e *Echo) StartTLS(address string, certFile, keyFile interface{}) (err error) {
Packit Service 509fd4
	var cert []byte
Packit Service 509fd4
	if cert, err = filepathOrContent(certFile); err != nil {
Packit Service 509fd4
		return
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	var key []byte
Packit Service 509fd4
	if key, err = filepathOrContent(keyFile); err != nil {
Packit Service 509fd4
		return
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	s := e.TLSServer
Packit Service 509fd4
	s.TLSConfig = new(tls.Config)
Packit Service 509fd4
	s.TLSConfig.Certificates = make([]tls.Certificate, 1)
Packit Service 509fd4
	if s.TLSConfig.Certificates[0], err = tls.X509KeyPair(cert, key); err != nil {
Packit Service 509fd4
		return
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	return e.startTLS(address)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
func filepathOrContent(fileOrContent interface{}) (content []byte, err error) {
Packit Service 509fd4
	switch v := fileOrContent.(type) {
Packit Service 509fd4
	case string:
Packit Service 509fd4
		return ioutil.ReadFile(v)
Packit Service 509fd4
	case []byte:
Packit Service 509fd4
		return v, nil
Packit Service 509fd4
	default:
Packit Service 509fd4
		return nil, ErrInvalidCertOrKeyType
Packit Service 509fd4
	}
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// StartAutoTLS starts an HTTPS server using certificates automatically installed from https://letsencrypt.org.
Packit Service 509fd4
func (e *Echo) StartAutoTLS(address string) error {
Packit Service 509fd4
	s := e.TLSServer
Packit Service 509fd4
	s.TLSConfig = new(tls.Config)
Packit Service 509fd4
	s.TLSConfig.GetCertificate = e.AutoTLSManager.GetCertificate
Packit Service 509fd4
	s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, acme.ALPNProto)
Packit Service 509fd4
	return e.startTLS(address)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
func (e *Echo) startTLS(address string) error {
Packit Service 509fd4
	s := e.TLSServer
Packit Service 509fd4
	s.Addr = address
Packit Service 509fd4
	if !e.DisableHTTP2 {
Packit Service 509fd4
		s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, "h2")
Packit Service 509fd4
	}
Packit Service 509fd4
	return e.StartServer(e.TLSServer)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// StartServer starts a custom http server.
Packit Service 509fd4
func (e *Echo) StartServer(s *http.Server) (err error) {
Packit Service 509fd4
	// Setup
Packit Service 509fd4
	e.colorer.SetOutput(e.Logger.Output())
Packit Service 509fd4
	s.ErrorLog = e.StdLogger
Packit Service 509fd4
	s.Handler = e
Packit Service 509fd4
	if e.Debug {
Packit Service 509fd4
		e.Logger.SetLevel(log.DEBUG)
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	if !e.HideBanner {
Packit Service 509fd4
		e.colorer.Printf(banner, e.colorer.Red("v"+Version), e.colorer.Blue(website))
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	if s.TLSConfig == nil {
Packit Service 509fd4
		if e.Listener == nil {
Packit Service 509fd4
			e.Listener, err = newListener(s.Addr)
Packit Service 509fd4
			if err != nil {
Packit Service 509fd4
				return err
Packit Service 509fd4
			}
Packit Service 509fd4
		}
Packit Service 509fd4
		if !e.HidePort {
Packit Service 509fd4
			e.colorer.Printf("⇨ http server started on %s\n", e.colorer.Green(e.Listener.Addr()))
Packit Service 509fd4
		}
Packit Service 509fd4
		return s.Serve(e.Listener)
Packit Service 509fd4
	}
Packit Service 509fd4
	if e.TLSListener == nil {
Packit Service 509fd4
		l, err := newListener(s.Addr)
Packit Service 509fd4
		if err != nil {
Packit Service 509fd4
			return err
Packit Service 509fd4
		}
Packit Service 509fd4
		e.TLSListener = tls.NewListener(l, s.TLSConfig)
Packit Service 509fd4
	}
Packit Service 509fd4
	if !e.HidePort {
Packit Service 509fd4
		e.colorer.Printf("⇨ https server started on %s\n", e.colorer.Green(e.TLSListener.Addr()))
Packit Service 509fd4
	}
Packit Service 509fd4
	return s.Serve(e.TLSListener)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// Close immediately stops the server.
Packit Service 509fd4
// It internally calls `http.Server#Close()`.
Packit Service 509fd4
func (e *Echo) Close() error {
Packit Service 509fd4
	if err := e.TLSServer.Close(); err != nil {
Packit Service 509fd4
		return err
Packit Service 509fd4
	}
Packit Service 509fd4
	return e.Server.Close()
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// Shutdown stops the server gracefully.
Packit Service 509fd4
// It internally calls `http.Server#Shutdown()`.
Packit Service 509fd4
func (e *Echo) Shutdown(ctx stdContext.Context) error {
Packit Service 509fd4
	if err := e.TLSServer.Shutdown(ctx); err != nil {
Packit Service 509fd4
		return err
Packit Service 509fd4
	}
Packit Service 509fd4
	return e.Server.Shutdown(ctx)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// NewHTTPError creates a new HTTPError instance.
Packit Service 509fd4
func NewHTTPError(code int, message ...interface{}) *HTTPError {
Packit Service 509fd4
	he := &HTTPError{Code: code, Message: http.StatusText(code)}
Packit Service 509fd4
	if len(message) > 0 {
Packit Service 509fd4
		he.Message = message[0]
Packit Service 509fd4
	}
Packit Service 509fd4
	return he
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// Error makes it compatible with `error` interface.
Packit Service 509fd4
func (he *HTTPError) Error() string {
Packit Service 509fd4
	return fmt.Sprintf("code=%d, message=%v, internal=%v", he.Code, he.Message, he.Internal)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// SetInternal sets error to HTTPError.Internal
Packit Service 509fd4
func (he *HTTPError) SetInternal(err error) *HTTPError {
Packit Service 509fd4
	he.Internal = err
Packit Service 509fd4
	return he
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// WrapHandler wraps `http.Handler` into `echo.HandlerFunc`.
Packit Service 509fd4
func WrapHandler(h http.Handler) HandlerFunc {
Packit Service 509fd4
	return func(c Context) error {
Packit Service 509fd4
		h.ServeHTTP(c.Response(), c.Request())
Packit Service 509fd4
		return nil
Packit Service 509fd4
	}
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// WrapMiddleware wraps `func(http.Handler) http.Handler` into `echo.MiddlewareFunc`
Packit Service 509fd4
func WrapMiddleware(m func(http.Handler) http.Handler) MiddlewareFunc {
Packit Service 509fd4
	return func(next HandlerFunc) HandlerFunc {
Packit Service 509fd4
		return func(c Context) (err error) {
Packit Service 509fd4
			m(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Packit Service 509fd4
				c.SetRequest(r)
Packit Service 509fd4
				c.SetResponse(NewResponse(w, c.Echo()))
Packit Service 509fd4
				err = next(c)
Packit Service 509fd4
			})).ServeHTTP(c.Response(), c.Request())
Packit Service 509fd4
			return
Packit Service 509fd4
		}
Packit Service 509fd4
	}
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
func getPath(r *http.Request) string {
Packit Service 509fd4
	path := r.URL.RawPath
Packit Service 509fd4
	if path == "" {
Packit Service 509fd4
		path = r.URL.Path
Packit Service 509fd4
	}
Packit Service 509fd4
	return path
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
func (e *Echo) findRouter(host string) *Router {
Packit Service 509fd4
	if len(e.routers) > 0 {
Packit Service 509fd4
		if r, ok := e.routers[host]; ok {
Packit Service 509fd4
			return r
Packit Service 509fd4
		}
Packit Service 509fd4
	}
Packit Service 509fd4
	return e.router
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
func handlerName(h HandlerFunc) string {
Packit Service 509fd4
	t := reflect.ValueOf(h).Type()
Packit Service 509fd4
	if t.Kind() == reflect.Func {
Packit Service 509fd4
		return runtime.FuncForPC(reflect.ValueOf(h).Pointer()).Name()
Packit Service 509fd4
	}
Packit Service 509fd4
	return t.String()
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// // PathUnescape is wraps `url.PathUnescape`
Packit Service 509fd4
// func PathUnescape(s string) (string, error) {
Packit Service 509fd4
// 	return url.PathUnescape(s)
Packit Service 509fd4
// }
Packit Service 509fd4
Packit Service 509fd4
// tcpKeepAliveListener sets TCP keep-alive timeouts on accepted
Packit Service 509fd4
// connections. It's used by ListenAndServe and ListenAndServeTLS so
Packit Service 509fd4
// dead TCP connections (e.g. closing laptop mid-download) eventually
Packit Service 509fd4
// go away.
Packit Service 509fd4
type tcpKeepAliveListener struct {
Packit Service 509fd4
	*net.TCPListener
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
Packit Service 509fd4
	if c, err = ln.AcceptTCP(); err != nil {
Packit Service 509fd4
		return
Packit Service 509fd4
	} else if err = c.(*net.TCPConn).SetKeepAlive(true); err != nil {
Packit Service 509fd4
		return
Packit Service 509fd4
	} else if err = c.(*net.TCPConn).SetKeepAlivePeriod(3 * time.Minute); err != nil {
Packit Service 509fd4
		return
Packit Service 509fd4
	}
Packit Service 509fd4
	return
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
func newListener(address string) (*tcpKeepAliveListener, error) {
Packit Service 509fd4
	l, err := net.Listen("tcp", address)
Packit Service 509fd4
	if err != nil {
Packit Service 509fd4
		return nil, err
Packit Service 509fd4
	}
Packit Service 509fd4
	return &tcpKeepAliveListener{l.(*net.TCPListener)}, nil
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
func applyMiddleware(h HandlerFunc, middleware ...MiddlewareFunc) HandlerFunc {
Packit Service 509fd4
	for i := len(middleware) - 1; i >= 0; i-- {
Packit Service 509fd4
		h = middleware[i](h)
Packit Service 509fd4
	}
Packit Service 509fd4
	return h
Packit Service 509fd4
}