|
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 |
}
|