mirror of
https://github.com/labstack/echo.git
synced 2024-11-24 08:22:21 +02:00
Change type definition blocks to single declarations. This helps copy/pasting Echo code in examples. (#2606)
This commit is contained in:
parent
5f7bedfb86
commit
3598f295f9
8
bind.go
8
bind.go
@ -14,23 +14,21 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// Binder is the interface that wraps the Bind method.
|
// Binder is the interface that wraps the Bind method.
|
||||||
Binder interface {
|
type Binder interface {
|
||||||
Bind(i interface{}, c Context) error
|
Bind(i interface{}, c Context) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultBinder is the default implementation of the Binder interface.
|
// DefaultBinder is the default implementation of the Binder interface.
|
||||||
DefaultBinder struct{}
|
type DefaultBinder struct{}
|
||||||
|
|
||||||
// BindUnmarshaler is the interface used to wrap the UnmarshalParam method.
|
// BindUnmarshaler is the interface used to wrap the UnmarshalParam method.
|
||||||
// Types that don't implement this, but do implement encoding.TextUnmarshaler
|
// Types that don't implement this, but do implement encoding.TextUnmarshaler
|
||||||
// will use that interface instead.
|
// will use that interface instead.
|
||||||
BindUnmarshaler interface {
|
type BindUnmarshaler interface {
|
||||||
// UnmarshalParam decodes and assigns a value from an form or query param.
|
// UnmarshalParam decodes and assigns a value from an form or query param.
|
||||||
UnmarshalParam(param string) error
|
UnmarshalParam(param string) error
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// BindPathParams binds path params to bindable object
|
// BindPathParams binds path params to bindable object
|
||||||
func (b *DefaultBinder) BindPathParams(c Context, i interface{}) error {
|
func (b *DefaultBinder) BindPathParams(c Context, i interface{}) error {
|
||||||
|
18
bind_test.go
18
bind_test.go
@ -22,8 +22,7 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type bindTestStruct struct {
|
||||||
bindTestStruct struct {
|
|
||||||
I int
|
I int
|
||||||
PtrI *int
|
PtrI *int
|
||||||
I8 int8
|
I8 int8
|
||||||
@ -60,7 +59,8 @@ type (
|
|||||||
Tptr *Timestamp
|
Tptr *Timestamp
|
||||||
SA StringArray
|
SA StringArray
|
||||||
}
|
}
|
||||||
bindTestStructWithTags struct {
|
|
||||||
|
type bindTestStructWithTags struct {
|
||||||
I int `json:"I" form:"I"`
|
I int `json:"I" form:"I"`
|
||||||
PtrI *int `json:"PtrI" form:"PtrI"`
|
PtrI *int `json:"PtrI" form:"PtrI"`
|
||||||
I8 int8 `json:"I8" form:"I8"`
|
I8 int8 `json:"I8" form:"I8"`
|
||||||
@ -97,16 +97,16 @@ type (
|
|||||||
Tptr *Timestamp `json:"Tptr" form:"Tptr"`
|
Tptr *Timestamp `json:"Tptr" form:"Tptr"`
|
||||||
SA StringArray `json:"SA" form:"SA"`
|
SA StringArray `json:"SA" form:"SA"`
|
||||||
}
|
}
|
||||||
Timestamp time.Time
|
|
||||||
TA []Timestamp
|
type Timestamp time.Time
|
||||||
StringArray []string
|
type TA []Timestamp
|
||||||
Struct struct {
|
type StringArray []string
|
||||||
|
type Struct struct {
|
||||||
Foo string
|
Foo string
|
||||||
}
|
}
|
||||||
Bar struct {
|
type Bar struct {
|
||||||
Baz int `json:"baz" query:"baz"`
|
Baz int `json:"baz" query:"baz"`
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
func (t *Timestamp) UnmarshalParam(src string) error {
|
func (t *Timestamp) UnmarshalParam(src string) error {
|
||||||
ts, err := time.Parse(time.RFC3339, src)
|
ts, err := time.Parse(time.RFC3339, src)
|
||||||
|
@ -16,10 +16,9 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// Context represents the context of the current HTTP request. It holds request and
|
// Context represents the context of the current HTTP request. It holds request and
|
||||||
// response objects, path, path parameters, data and registered handler.
|
// response objects, path, path parameters, data and registered handler.
|
||||||
Context interface {
|
type Context interface {
|
||||||
// Request returns `*http.Request`.
|
// Request returns `*http.Request`.
|
||||||
Request() *http.Request
|
Request() *http.Request
|
||||||
|
|
||||||
@ -200,7 +199,7 @@ type (
|
|||||||
Reset(r *http.Request, w http.ResponseWriter)
|
Reset(r *http.Request, w http.ResponseWriter)
|
||||||
}
|
}
|
||||||
|
|
||||||
context struct {
|
type context struct {
|
||||||
request *http.Request
|
request *http.Request
|
||||||
response *Response
|
response *Response
|
||||||
path string
|
path string
|
||||||
@ -213,7 +212,6 @@ type (
|
|||||||
logger Logger
|
logger Logger
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// ContextKeyHeaderAllow is set by Router for getting value for `Allow` header in later stages of handler call chain.
|
// ContextKeyHeaderAllow is set by Router for getting value for `Allow` header in later stages of handler call chain.
|
||||||
|
@ -25,11 +25,9 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type Template struct {
|
||||||
Template struct {
|
|
||||||
templates *template.Template
|
templates *template.Template
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
var testUser = user{1, "Jon Snow"}
|
var testUser = user{1, "Jon Snow"}
|
||||||
|
|
||||||
|
39
echo.go
39
echo.go
@ -63,13 +63,12 @@ import (
|
|||||||
"golang.org/x/net/http2/h2c"
|
"golang.org/x/net/http2/h2c"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// Echo is the top-level framework instance.
|
// Echo is the top-level framework instance.
|
||||||
//
|
//
|
||||||
// Goroutine safety: Do not mutate Echo instance fields after server has started. Accessing these
|
// Goroutine safety: Do not mutate Echo instance fields after server has started. Accessing these
|
||||||
// fields from handlers/middlewares and changing field values at the same time leads to data-races.
|
// fields from handlers/middlewares and changing field values at the same time leads to data-races.
|
||||||
// Adding new routes after the server has been started is also not safe!
|
// Adding new routes after the server has been started is also not safe!
|
||||||
Echo struct {
|
type Echo struct {
|
||||||
filesystem
|
filesystem
|
||||||
common
|
common
|
||||||
// startupMutex is mutex to lock Echo instance access during server configuration and startup. Useful for to get
|
// startupMutex is mutex to lock Echo instance access during server configuration and startup. Useful for to get
|
||||||
@ -110,50 +109,49 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Route contains a handler and information for matching against requests.
|
// Route contains a handler and information for matching against requests.
|
||||||
Route struct {
|
type Route struct {
|
||||||
Method string `json:"method"`
|
Method string `json:"method"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTPError represents an error that occurred while handling a request.
|
// HTTPError represents an error that occurred while handling a request.
|
||||||
HTTPError struct {
|
type HTTPError struct {
|
||||||
Code int `json:"-"`
|
Code int `json:"-"`
|
||||||
Message interface{} `json:"message"`
|
Message interface{} `json:"message"`
|
||||||
Internal error `json:"-"` // Stores the error returned by an external dependency
|
Internal error `json:"-"` // Stores the error returned by an external dependency
|
||||||
}
|
}
|
||||||
|
|
||||||
// MiddlewareFunc defines a function to process middleware.
|
// MiddlewareFunc defines a function to process middleware.
|
||||||
MiddlewareFunc func(next HandlerFunc) HandlerFunc
|
type MiddlewareFunc func(next HandlerFunc) HandlerFunc
|
||||||
|
|
||||||
// HandlerFunc defines a function to serve HTTP requests.
|
// HandlerFunc defines a function to serve HTTP requests.
|
||||||
HandlerFunc func(c Context) error
|
type HandlerFunc func(c Context) error
|
||||||
|
|
||||||
// HTTPErrorHandler is a centralized HTTP error handler.
|
// HTTPErrorHandler is a centralized HTTP error handler.
|
||||||
HTTPErrorHandler func(err error, c Context)
|
type HTTPErrorHandler func(err error, c Context)
|
||||||
|
|
||||||
// Validator is the interface that wraps the Validate function.
|
// Validator is the interface that wraps the Validate function.
|
||||||
Validator interface {
|
type Validator interface {
|
||||||
Validate(i interface{}) error
|
Validate(i interface{}) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSONSerializer is the interface that encodes and decodes JSON to and from interfaces.
|
// JSONSerializer is the interface that encodes and decodes JSON to and from interfaces.
|
||||||
JSONSerializer interface {
|
type JSONSerializer interface {
|
||||||
Serialize(c Context, i interface{}, indent string) error
|
Serialize(c Context, i interface{}, indent string) error
|
||||||
Deserialize(c Context, i interface{}) error
|
Deserialize(c Context, i interface{}) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Renderer is the interface that wraps the Render function.
|
// Renderer is the interface that wraps the Render function.
|
||||||
Renderer interface {
|
type Renderer interface {
|
||||||
Render(io.Writer, string, interface{}, Context) error
|
Render(io.Writer, string, interface{}, Context) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map defines a generic map of type `map[string]interface{}`.
|
// Map defines a generic map of type `map[string]interface{}`.
|
||||||
Map map[string]interface{}
|
type Map map[string]interface{}
|
||||||
|
|
||||||
// Common struct for Echo & Group.
|
// Common struct for Echo & Group.
|
||||||
common struct{}
|
type common struct{}
|
||||||
)
|
|
||||||
|
|
||||||
// HTTP methods
|
// HTTP methods
|
||||||
// NOTE: Deprecated, please use the stdlib constants directly instead.
|
// NOTE: Deprecated, please use the stdlib constants directly instead.
|
||||||
@ -282,8 +280,7 @@ ____________________________________O/_______
|
|||||||
`
|
`
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var methods = [...]string{
|
||||||
methods = [...]string{
|
|
||||||
http.MethodConnect,
|
http.MethodConnect,
|
||||||
http.MethodDelete,
|
http.MethodDelete,
|
||||||
http.MethodGet,
|
http.MethodGet,
|
||||||
@ -296,7 +293,6 @@ var (
|
|||||||
http.MethodTrace,
|
http.MethodTrace,
|
||||||
REPORT,
|
REPORT,
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// Errors
|
// Errors
|
||||||
var (
|
var (
|
||||||
@ -349,13 +345,15 @@ var (
|
|||||||
ErrInvalidListenerNetwork = errors.New("invalid listener network")
|
ErrInvalidListenerNetwork = errors.New("invalid listener network")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Error handlers
|
// NotFoundHandler is the handler that router uses in case there was no matching route found. Returns an error that results
|
||||||
var (
|
// HTTP 404 status code.
|
||||||
NotFoundHandler = func(c Context) error {
|
var NotFoundHandler = func(c Context) error {
|
||||||
return ErrNotFound
|
return ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodNotAllowedHandler = func(c Context) error {
|
// MethodNotAllowedHandler is the handler thar router uses in case there was no matching route found but there was
|
||||||
|
// another matching routes for that requested URL. Returns an error that results HTTP 405 Method Not Allowed status code.
|
||||||
|
var MethodNotAllowedHandler = func(c Context) error {
|
||||||
// See RFC 7231 section 7.4.1: An origin server MUST generate an Allow field in a 405 (Method Not Allowed)
|
// See RFC 7231 section 7.4.1: An origin server MUST generate an Allow field in a 405 (Method Not Allowed)
|
||||||
// response and MAY do so in any other response. For disabled resources an empty Allow header may be returned
|
// response and MAY do so in any other response. For disabled resources an empty Allow header may be returned
|
||||||
routerAllowMethods, ok := c.Get(ContextKeyHeaderAllow).(string)
|
routerAllowMethods, ok := c.Get(ContextKeyHeaderAllow).(string)
|
||||||
@ -364,7 +362,6 @@ var (
|
|||||||
}
|
}
|
||||||
return ErrMethodNotAllowed
|
return ErrMethodNotAllowed
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// New creates an instance of Echo.
|
// New creates an instance of Echo.
|
||||||
func New() (e *Echo) {
|
func New() (e *Echo) {
|
||||||
|
@ -25,12 +25,10 @@ import (
|
|||||||
"golang.org/x/net/http2"
|
"golang.org/x/net/http2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type user struct {
|
||||||
user struct {
|
|
||||||
ID int `json:"id" xml:"id" form:"id" query:"id" param:"id" header:"id"`
|
ID int `json:"id" xml:"id" form:"id" query:"id" param:"id" header:"id"`
|
||||||
Name string `json:"name" xml:"name" form:"name" query:"name" param:"name" header:"name"`
|
Name string `json:"name" xml:"name" form:"name" query:"name" param:"name" header:"name"`
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
userJSON = `{"id":1,"name":"Jon Snow"}`
|
userJSON = `{"id":1,"name":"Jon Snow"}`
|
||||||
|
4
group.go
4
group.go
@ -7,18 +7,16 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// Group is a set of sub-routes for a specified route. It can be used for inner
|
// Group is a set of sub-routes for a specified route. It can be used for inner
|
||||||
// routes that share a common middleware or functionality that should be separate
|
// routes that share a common middleware or functionality that should be separate
|
||||||
// from the parent echo instance while still inheriting from it.
|
// from the parent echo instance while still inheriting from it.
|
||||||
Group struct {
|
type Group struct {
|
||||||
common
|
common
|
||||||
host string
|
host string
|
||||||
prefix string
|
prefix string
|
||||||
middleware []MiddlewareFunc
|
middleware []MiddlewareFunc
|
||||||
echo *Echo
|
echo *Echo
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// Use implements `Echo#Use()` for sub-routes within the Group.
|
// Use implements `Echo#Use()` for sub-routes within the Group.
|
||||||
func (g *Group) Use(middleware ...MiddlewareFunc) {
|
func (g *Group) Use(middleware ...MiddlewareFunc) {
|
||||||
|
7
log.go
7
log.go
@ -4,14 +4,12 @@
|
|||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/labstack/gommon/log"
|
"github.com/labstack/gommon/log"
|
||||||
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// Logger defines the logging interface.
|
// Logger defines the logging interface.
|
||||||
Logger interface {
|
type Logger interface {
|
||||||
Output() io.Writer
|
Output() io.Writer
|
||||||
SetOutput(w io.Writer)
|
SetOutput(w io.Writer)
|
||||||
Prefix() string
|
Prefix() string
|
||||||
@ -41,4 +39,3 @@ type (
|
|||||||
Panicj(j log.JSON)
|
Panicj(j log.JSON)
|
||||||
Panicf(format string, args ...interface{})
|
Panicf(format string, args ...interface{})
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
@ -12,9 +12,8 @@ import (
|
|||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// BasicAuthConfig defines the config for BasicAuth middleware.
|
// BasicAuthConfig defines the config for BasicAuth middleware.
|
||||||
BasicAuthConfig struct {
|
type BasicAuthConfig struct {
|
||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
|
|
||||||
@ -30,21 +29,18 @@ type (
|
|||||||
// BasicAuthValidator defines a function to validate BasicAuth credentials.
|
// BasicAuthValidator defines a function to validate BasicAuth credentials.
|
||||||
// The function should return a boolean indicating whether the credentials are valid,
|
// The function should return a boolean indicating whether the credentials are valid,
|
||||||
// and an error if any error occurs during the validation process.
|
// and an error if any error occurs during the validation process.
|
||||||
BasicAuthValidator func(string, string, echo.Context) (bool, error)
|
type BasicAuthValidator func(string, string, echo.Context) (bool, error)
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
basic = "basic"
|
basic = "basic"
|
||||||
defaultRealm = "Restricted"
|
defaultRealm = "Restricted"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
// DefaultBasicAuthConfig is the default BasicAuth middleware config.
|
// DefaultBasicAuthConfig is the default BasicAuth middleware config.
|
||||||
DefaultBasicAuthConfig = BasicAuthConfig{
|
var DefaultBasicAuthConfig = BasicAuthConfig{
|
||||||
Skipper: DefaultSkipper,
|
Skipper: DefaultSkipper,
|
||||||
Realm: defaultRealm,
|
Realm: defaultRealm,
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// BasicAuth returns an BasicAuth middleware.
|
// BasicAuth returns an BasicAuth middleware.
|
||||||
//
|
//
|
||||||
|
@ -14,9 +14,8 @@ import (
|
|||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// BodyDumpConfig defines the config for BodyDump middleware.
|
// BodyDumpConfig defines the config for BodyDump middleware.
|
||||||
BodyDumpConfig struct {
|
type BodyDumpConfig struct {
|
||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
|
|
||||||
@ -26,20 +25,17 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BodyDumpHandler receives the request and response payload.
|
// BodyDumpHandler receives the request and response payload.
|
||||||
BodyDumpHandler func(echo.Context, []byte, []byte)
|
type BodyDumpHandler func(echo.Context, []byte, []byte)
|
||||||
|
|
||||||
bodyDumpResponseWriter struct {
|
type bodyDumpResponseWriter struct {
|
||||||
io.Writer
|
io.Writer
|
||||||
http.ResponseWriter
|
http.ResponseWriter
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// DefaultBodyDumpConfig is the default BodyDump middleware config.
|
// DefaultBodyDumpConfig is the default BodyDump middleware config.
|
||||||
DefaultBodyDumpConfig = BodyDumpConfig{
|
var DefaultBodyDumpConfig = BodyDumpConfig{
|
||||||
Skipper: DefaultSkipper,
|
Skipper: DefaultSkipper,
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// BodyDump returns a BodyDump middleware.
|
// BodyDump returns a BodyDump middleware.
|
||||||
//
|
//
|
||||||
|
@ -12,9 +12,8 @@ import (
|
|||||||
"github.com/labstack/gommon/bytes"
|
"github.com/labstack/gommon/bytes"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// BodyLimitConfig defines the config for BodyLimit middleware.
|
// BodyLimitConfig defines the config for BodyLimit middleware.
|
||||||
BodyLimitConfig struct {
|
type BodyLimitConfig struct {
|
||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
|
|
||||||
@ -24,19 +23,16 @@ type (
|
|||||||
limit int64
|
limit int64
|
||||||
}
|
}
|
||||||
|
|
||||||
limitedReader struct {
|
type limitedReader struct {
|
||||||
BodyLimitConfig
|
BodyLimitConfig
|
||||||
reader io.ReadCloser
|
reader io.ReadCloser
|
||||||
read int64
|
read int64
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// DefaultBodyLimitConfig is the default BodyLimit middleware config.
|
// DefaultBodyLimitConfig is the default BodyLimit middleware config.
|
||||||
DefaultBodyLimitConfig = BodyLimitConfig{
|
var DefaultBodyLimitConfig = BodyLimitConfig{
|
||||||
Skipper: DefaultSkipper,
|
Skipper: DefaultSkipper,
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// BodyLimit returns a BodyLimit middleware.
|
// BodyLimit returns a BodyLimit middleware.
|
||||||
//
|
//
|
||||||
|
@ -16,9 +16,8 @@ import (
|
|||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// GzipConfig defines the config for Gzip middleware.
|
// GzipConfig defines the config for Gzip middleware.
|
||||||
GzipConfig struct {
|
type GzipConfig struct {
|
||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
|
|
||||||
@ -40,7 +39,7 @@ type (
|
|||||||
MinLength int
|
MinLength int
|
||||||
}
|
}
|
||||||
|
|
||||||
gzipResponseWriter struct {
|
type gzipResponseWriter struct {
|
||||||
io.Writer
|
io.Writer
|
||||||
http.ResponseWriter
|
http.ResponseWriter
|
||||||
wroteHeader bool
|
wroteHeader bool
|
||||||
@ -50,20 +49,17 @@ type (
|
|||||||
buffer *bytes.Buffer
|
buffer *bytes.Buffer
|
||||||
code int
|
code int
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
gzipScheme = "gzip"
|
gzipScheme = "gzip"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
// DefaultGzipConfig is the default Gzip middleware config.
|
// DefaultGzipConfig is the default Gzip middleware config.
|
||||||
DefaultGzipConfig = GzipConfig{
|
var DefaultGzipConfig = GzipConfig{
|
||||||
Skipper: DefaultSkipper,
|
Skipper: DefaultSkipper,
|
||||||
Level: -1,
|
Level: -1,
|
||||||
MinLength: 0,
|
MinLength: 0,
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// Gzip returns a middleware which compresses HTTP response using gzip compression
|
// Gzip returns a middleware which compresses HTTP response using gzip compression
|
||||||
// scheme.
|
// scheme.
|
||||||
|
@ -12,9 +12,8 @@ import (
|
|||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// CORSConfig defines the config for CORS middleware.
|
// CORSConfig defines the config for CORS middleware.
|
||||||
CORSConfig struct {
|
type CORSConfig struct {
|
||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
|
|
||||||
@ -109,16 +108,13 @@ type (
|
|||||||
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
|
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
|
||||||
MaxAge int `yaml:"max_age"`
|
MaxAge int `yaml:"max_age"`
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// DefaultCORSConfig is the default CORS middleware config.
|
// DefaultCORSConfig is the default CORS middleware config.
|
||||||
DefaultCORSConfig = CORSConfig{
|
var DefaultCORSConfig = CORSConfig{
|
||||||
Skipper: DefaultSkipper,
|
Skipper: DefaultSkipper,
|
||||||
AllowOrigins: []string{"*"},
|
AllowOrigins: []string{"*"},
|
||||||
AllowMethods: []string{http.MethodGet, http.MethodHead, http.MethodPut, http.MethodPatch, http.MethodPost, http.MethodDelete},
|
AllowMethods: []string{http.MethodGet, http.MethodHead, http.MethodPut, http.MethodPatch, http.MethodPost, http.MethodDelete},
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// CORS returns a Cross-Origin Resource Sharing (CORS) middleware.
|
// CORS returns a Cross-Origin Resource Sharing (CORS) middleware.
|
||||||
// See also [MDN: Cross-Origin Resource Sharing (CORS)].
|
// See also [MDN: Cross-Origin Resource Sharing (CORS)].
|
||||||
|
@ -11,9 +11,8 @@ import (
|
|||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// CSRFConfig defines the config for CSRF middleware.
|
// CSRFConfig defines the config for CSRF middleware.
|
||||||
CSRFConfig struct {
|
type CSRFConfig struct {
|
||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
|
|
||||||
@ -69,15 +68,13 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CSRFErrorHandler is a function which is executed for creating custom errors.
|
// CSRFErrorHandler is a function which is executed for creating custom errors.
|
||||||
CSRFErrorHandler func(err error, c echo.Context) error
|
type CSRFErrorHandler func(err error, c echo.Context) error
|
||||||
)
|
|
||||||
|
|
||||||
// ErrCSRFInvalid is returned when CSRF check fails
|
// ErrCSRFInvalid is returned when CSRF check fails
|
||||||
var ErrCSRFInvalid = echo.NewHTTPError(http.StatusForbidden, "invalid csrf token")
|
var ErrCSRFInvalid = echo.NewHTTPError(http.StatusForbidden, "invalid csrf token")
|
||||||
|
|
||||||
var (
|
|
||||||
// DefaultCSRFConfig is the default CSRF middleware config.
|
// DefaultCSRFConfig is the default CSRF middleware config.
|
||||||
DefaultCSRFConfig = CSRFConfig{
|
var DefaultCSRFConfig = CSRFConfig{
|
||||||
Skipper: DefaultSkipper,
|
Skipper: DefaultSkipper,
|
||||||
TokenLength: 32,
|
TokenLength: 32,
|
||||||
TokenLookup: "header:" + echo.HeaderXCSRFToken,
|
TokenLookup: "header:" + echo.HeaderXCSRFToken,
|
||||||
@ -86,7 +83,6 @@ var (
|
|||||||
CookieMaxAge: 86400,
|
CookieMaxAge: 86400,
|
||||||
CookieSameSite: http.SameSiteDefaultMode,
|
CookieSameSite: http.SameSiteDefaultMode,
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// CSRF returns a Cross-Site Request Forgery (CSRF) middleware.
|
// CSRF returns a Cross-Site Request Forgery (CSRF) middleware.
|
||||||
// See: https://en.wikipedia.org/wiki/Cross-site_request_forgery
|
// See: https://en.wikipedia.org/wiki/Cross-site_request_forgery
|
||||||
|
@ -12,16 +12,14 @@ import (
|
|||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// DecompressConfig defines the config for Decompress middleware.
|
// DecompressConfig defines the config for Decompress middleware.
|
||||||
DecompressConfig struct {
|
type DecompressConfig struct {
|
||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
|
|
||||||
// GzipDecompressPool defines an interface to provide the sync.Pool used to create/store Gzip readers
|
// GzipDecompressPool defines an interface to provide the sync.Pool used to create/store Gzip readers
|
||||||
GzipDecompressPool Decompressor
|
GzipDecompressPool Decompressor
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// GZIPEncoding content-encoding header if set to "gzip", decompress body contents.
|
// GZIPEncoding content-encoding header if set to "gzip", decompress body contents.
|
||||||
const GZIPEncoding string = "gzip"
|
const GZIPEncoding string = "gzip"
|
||||||
@ -31,13 +29,11 @@ type Decompressor interface {
|
|||||||
gzipDecompressPool() sync.Pool
|
gzipDecompressPool() sync.Pool
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
// DefaultDecompressConfig defines the config for decompress middleware
|
// DefaultDecompressConfig defines the config for decompress middleware
|
||||||
DefaultDecompressConfig = DecompressConfig{
|
var DefaultDecompressConfig = DecompressConfig{
|
||||||
Skipper: DefaultSkipper,
|
Skipper: DefaultSkipper,
|
||||||
GzipDecompressPool: &DefaultGzipDecompressPool{},
|
GzipDecompressPool: &DefaultGzipDecompressPool{},
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// DefaultGzipDecompressPool is the default implementation of Decompressor interface
|
// DefaultGzipDecompressPool is the default implementation of Decompressor interface
|
||||||
type DefaultGzipDecompressPool struct {
|
type DefaultGzipDecompressPool struct {
|
||||||
|
@ -15,9 +15,8 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// JWTConfig defines the config for JWT middleware.
|
// JWTConfig defines the config for JWT middleware.
|
||||||
JWTConfig struct {
|
type JWTConfig struct {
|
||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
|
|
||||||
@ -115,29 +114,27 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// JWTSuccessHandler defines a function which is executed for a valid token.
|
// JWTSuccessHandler defines a function which is executed for a valid token.
|
||||||
JWTSuccessHandler func(c echo.Context)
|
type JWTSuccessHandler func(c echo.Context)
|
||||||
|
|
||||||
// JWTErrorHandler defines a function which is executed for an invalid token.
|
// JWTErrorHandler defines a function which is executed for an invalid token.
|
||||||
JWTErrorHandler func(err error) error
|
type JWTErrorHandler func(err error) error
|
||||||
|
|
||||||
// JWTErrorHandlerWithContext is almost identical to JWTErrorHandler, but it's passed the current context.
|
// JWTErrorHandlerWithContext is almost identical to JWTErrorHandler, but it's passed the current context.
|
||||||
JWTErrorHandlerWithContext func(err error, c echo.Context) error
|
type JWTErrorHandlerWithContext func(err error, c echo.Context) error
|
||||||
)
|
|
||||||
|
|
||||||
// Algorithms
|
// Algorithms
|
||||||
const (
|
const (
|
||||||
AlgorithmHS256 = "HS256"
|
AlgorithmHS256 = "HS256"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Errors
|
// ErrJWTMissing is error that is returned when no JWToken was extracted from the request.
|
||||||
var (
|
var ErrJWTMissing = echo.NewHTTPError(http.StatusBadRequest, "missing or malformed jwt")
|
||||||
ErrJWTMissing = echo.NewHTTPError(http.StatusBadRequest, "missing or malformed jwt")
|
|
||||||
ErrJWTInvalid = echo.NewHTTPError(http.StatusUnauthorized, "invalid or expired jwt")
|
// ErrJWTInvalid is error that is returned when middleware could not parse JWT correctly.
|
||||||
)
|
var ErrJWTInvalid = echo.NewHTTPError(http.StatusUnauthorized, "invalid or expired jwt")
|
||||||
|
|
||||||
var (
|
|
||||||
// DefaultJWTConfig is the default JWT auth middleware config.
|
// DefaultJWTConfig is the default JWT auth middleware config.
|
||||||
DefaultJWTConfig = JWTConfig{
|
var DefaultJWTConfig = JWTConfig{
|
||||||
Skipper: DefaultSkipper,
|
Skipper: DefaultSkipper,
|
||||||
SigningMethod: AlgorithmHS256,
|
SigningMethod: AlgorithmHS256,
|
||||||
ContextKey: "user",
|
ContextKey: "user",
|
||||||
@ -147,7 +144,6 @@ var (
|
|||||||
Claims: jwt.MapClaims{},
|
Claims: jwt.MapClaims{},
|
||||||
KeyFunc: nil,
|
KeyFunc: nil,
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// JWT returns a JSON Web Token (JWT) auth middleware.
|
// JWT returns a JSON Web Token (JWT) auth middleware.
|
||||||
//
|
//
|
||||||
|
@ -9,9 +9,8 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// KeyAuthConfig defines the config for KeyAuth middleware.
|
// KeyAuthConfig defines the config for KeyAuth middleware.
|
||||||
KeyAuthConfig struct {
|
type KeyAuthConfig struct {
|
||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
|
|
||||||
@ -52,26 +51,23 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// KeyAuthValidator defines a function to validate KeyAuth credentials.
|
// KeyAuthValidator defines a function to validate KeyAuth credentials.
|
||||||
KeyAuthValidator func(auth string, c echo.Context) (bool, error)
|
type KeyAuthValidator func(auth string, c echo.Context) (bool, error)
|
||||||
|
|
||||||
// KeyAuthErrorHandler defines a function which is executed for an invalid key.
|
// KeyAuthErrorHandler defines a function which is executed for an invalid key.
|
||||||
KeyAuthErrorHandler func(err error, c echo.Context) error
|
type KeyAuthErrorHandler func(err error, c echo.Context) error
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// DefaultKeyAuthConfig is the default KeyAuth middleware config.
|
|
||||||
DefaultKeyAuthConfig = KeyAuthConfig{
|
|
||||||
Skipper: DefaultSkipper,
|
|
||||||
KeyLookup: "header:" + echo.HeaderAuthorization,
|
|
||||||
AuthScheme: "Bearer",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// ErrKeyAuthMissing is error type when KeyAuth middleware is unable to extract value from lookups
|
// ErrKeyAuthMissing is error type when KeyAuth middleware is unable to extract value from lookups
|
||||||
type ErrKeyAuthMissing struct {
|
type ErrKeyAuthMissing struct {
|
||||||
Err error
|
Err error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DefaultKeyAuthConfig is the default KeyAuth middleware config.
|
||||||
|
var DefaultKeyAuthConfig = KeyAuthConfig{
|
||||||
|
Skipper: DefaultSkipper,
|
||||||
|
KeyLookup: "header:" + echo.HeaderAuthorization,
|
||||||
|
AuthScheme: "Bearer",
|
||||||
|
}
|
||||||
|
|
||||||
// Error returns errors text
|
// Error returns errors text
|
||||||
func (e *ErrKeyAuthMissing) Error() string {
|
func (e *ErrKeyAuthMissing) Error() string {
|
||||||
return e.Err.Error()
|
return e.Err.Error()
|
||||||
|
@ -17,9 +17,8 @@ import (
|
|||||||
"github.com/valyala/fasttemplate"
|
"github.com/valyala/fasttemplate"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// LoggerConfig defines the config for Logger middleware.
|
// LoggerConfig defines the config for Logger middleware.
|
||||||
LoggerConfig struct {
|
type LoggerConfig struct {
|
||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
|
|
||||||
@ -74,11 +73,9 @@ type (
|
|||||||
colorer *color.Color
|
colorer *color.Color
|
||||||
pool *sync.Pool
|
pool *sync.Pool
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// DefaultLoggerConfig is the default Logger middleware config.
|
// DefaultLoggerConfig is the default Logger middleware config.
|
||||||
DefaultLoggerConfig = LoggerConfig{
|
var DefaultLoggerConfig = LoggerConfig{
|
||||||
Skipper: DefaultSkipper,
|
Skipper: DefaultSkipper,
|
||||||
Format: `{"time":"${time_rfc3339_nano}","id":"${id}","remote_ip":"${remote_ip}",` +
|
Format: `{"time":"${time_rfc3339_nano}","id":"${id}","remote_ip":"${remote_ip}",` +
|
||||||
`"host":"${host}","method":"${method}","uri":"${uri}","user_agent":"${user_agent}",` +
|
`"host":"${host}","method":"${method}","uri":"${uri}","user_agent":"${user_agent}",` +
|
||||||
@ -87,7 +84,6 @@ var (
|
|||||||
CustomTimeFormat: "2006-01-02 15:04:05.00000",
|
CustomTimeFormat: "2006-01-02 15:04:05.00000",
|
||||||
colorer: color.New(),
|
colorer: color.New(),
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// Logger returns a middleware that logs HTTP requests.
|
// Logger returns a middleware that logs HTTP requests.
|
||||||
func Logger() echo.MiddlewareFunc {
|
func Logger() echo.MiddlewareFunc {
|
||||||
|
@ -9,9 +9,8 @@ import (
|
|||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// MethodOverrideConfig defines the config for MethodOverride middleware.
|
// MethodOverrideConfig defines the config for MethodOverride middleware.
|
||||||
MethodOverrideConfig struct {
|
type MethodOverrideConfig struct {
|
||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
|
|
||||||
@ -21,16 +20,13 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MethodOverrideGetter is a function that gets overridden method from the request
|
// MethodOverrideGetter is a function that gets overridden method from the request
|
||||||
MethodOverrideGetter func(echo.Context) string
|
type MethodOverrideGetter func(echo.Context) string
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// DefaultMethodOverrideConfig is the default MethodOverride middleware config.
|
// DefaultMethodOverrideConfig is the default MethodOverride middleware config.
|
||||||
DefaultMethodOverrideConfig = MethodOverrideConfig{
|
var DefaultMethodOverrideConfig = MethodOverrideConfig{
|
||||||
Skipper: DefaultSkipper,
|
Skipper: DefaultSkipper,
|
||||||
Getter: MethodFromHeader(echo.HeaderXHTTPMethodOverride),
|
Getter: MethodFromHeader(echo.HeaderXHTTPMethodOverride),
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// MethodOverride returns a MethodOverride middleware.
|
// MethodOverride returns a MethodOverride middleware.
|
||||||
// MethodOverride middleware checks for the overridden method from the request and
|
// MethodOverride middleware checks for the overridden method from the request and
|
||||||
|
@ -12,14 +12,12 @@ import (
|
|||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// Skipper defines a function to skip middleware. Returning true skips processing
|
// Skipper defines a function to skip middleware. Returning true skips processing
|
||||||
// the middleware.
|
// the middleware.
|
||||||
Skipper func(c echo.Context) bool
|
type Skipper func(c echo.Context) bool
|
||||||
|
|
||||||
// BeforeFunc defines a function which is executed just before the middleware.
|
// BeforeFunc defines a function which is executed just before the middleware.
|
||||||
BeforeFunc func(c echo.Context)
|
type BeforeFunc func(c echo.Context)
|
||||||
)
|
|
||||||
|
|
||||||
func captureTokens(pattern *regexp.Regexp, input string) *strings.Replacer {
|
func captureTokens(pattern *regexp.Regexp, input string) *strings.Replacer {
|
||||||
groups := pattern.FindAllStringSubmatch(input, -1)
|
groups := pattern.FindAllStringSubmatch(input, -1)
|
||||||
@ -56,7 +54,7 @@ func rewriteURL(rewriteRegex map[*regexp.Regexp]string, req *http.Request) error
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Depending how HTTP request is sent RequestURI could contain Scheme://Host/path or be just /path.
|
// Depending on how HTTP request is sent RequestURI could contain Scheme://Host/path or be just /path.
|
||||||
// We only want to use path part for rewriting and therefore trim prefix if it exists
|
// We only want to use path part for rewriting and therefore trim prefix if it exists
|
||||||
rawURI := req.RequestURI
|
rawURI := req.RequestURI
|
||||||
if rawURI != "" && rawURI[0] != '/' {
|
if rawURI != "" && rawURI[0] != '/' {
|
||||||
|
@ -22,9 +22,8 @@ import (
|
|||||||
|
|
||||||
// TODO: Handle TLS proxy
|
// TODO: Handle TLS proxy
|
||||||
|
|
||||||
type (
|
|
||||||
// ProxyConfig defines the config for Proxy middleware.
|
// ProxyConfig defines the config for Proxy middleware.
|
||||||
ProxyConfig struct {
|
type ProxyConfig struct {
|
||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
|
|
||||||
@ -88,14 +87,14 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ProxyTarget defines the upstream target.
|
// ProxyTarget defines the upstream target.
|
||||||
ProxyTarget struct {
|
type ProxyTarget struct {
|
||||||
Name string
|
Name string
|
||||||
URL *url.URL
|
URL *url.URL
|
||||||
Meta echo.Map
|
Meta echo.Map
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProxyBalancer defines an interface to implement a load balancing technique.
|
// ProxyBalancer defines an interface to implement a load balancing technique.
|
||||||
ProxyBalancer interface {
|
type ProxyBalancer interface {
|
||||||
AddTarget(*ProxyTarget) bool
|
AddTarget(*ProxyTarget) bool
|
||||||
RemoveTarget(string) bool
|
RemoveTarget(string) bool
|
||||||
Next(echo.Context) *ProxyTarget
|
Next(echo.Context) *ProxyTarget
|
||||||
@ -103,36 +102,33 @@ type (
|
|||||||
|
|
||||||
// TargetProvider defines an interface that gives the opportunity for balancer
|
// TargetProvider defines an interface that gives the opportunity for balancer
|
||||||
// to return custom errors when selecting target.
|
// to return custom errors when selecting target.
|
||||||
TargetProvider interface {
|
type TargetProvider interface {
|
||||||
NextTarget(echo.Context) (*ProxyTarget, error)
|
NextTarget(echo.Context) (*ProxyTarget, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
commonBalancer struct {
|
type commonBalancer struct {
|
||||||
targets []*ProxyTarget
|
targets []*ProxyTarget
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// RandomBalancer implements a random load balancing technique.
|
// RandomBalancer implements a random load balancing technique.
|
||||||
randomBalancer struct {
|
type randomBalancer struct {
|
||||||
commonBalancer
|
commonBalancer
|
||||||
random *rand.Rand
|
random *rand.Rand
|
||||||
}
|
}
|
||||||
|
|
||||||
// RoundRobinBalancer implements a round-robin load balancing technique.
|
// RoundRobinBalancer implements a round-robin load balancing technique.
|
||||||
roundRobinBalancer struct {
|
type roundRobinBalancer struct {
|
||||||
commonBalancer
|
commonBalancer
|
||||||
// tracking the index on `targets` slice for the next `*ProxyTarget` to be used
|
// tracking the index on `targets` slice for the next `*ProxyTarget` to be used
|
||||||
i int
|
i int
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// DefaultProxyConfig is the default Proxy middleware config.
|
// DefaultProxyConfig is the default Proxy middleware config.
|
||||||
DefaultProxyConfig = ProxyConfig{
|
var DefaultProxyConfig = ProxyConfig{
|
||||||
Skipper: DefaultSkipper,
|
Skipper: DefaultSkipper,
|
||||||
ContextKey: "target",
|
ContextKey: "target",
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
func proxyRaw(t *ProxyTarget, c echo.Context) http.Handler {
|
func proxyRaw(t *ProxyTarget, c echo.Context) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -12,17 +12,14 @@ import (
|
|||||||
"golang.org/x/time/rate"
|
"golang.org/x/time/rate"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// RateLimiterStore is the interface to be implemented by custom stores.
|
// RateLimiterStore is the interface to be implemented by custom stores.
|
||||||
RateLimiterStore interface {
|
type RateLimiterStore interface {
|
||||||
// Stores for the rate limiter have to implement the Allow method
|
// Stores for the rate limiter have to implement the Allow method
|
||||||
Allow(identifier string) (bool, error)
|
Allow(identifier string) (bool, error)
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
// RateLimiterConfig defines the configuration for the rate limiter
|
// RateLimiterConfig defines the configuration for the rate limiter
|
||||||
RateLimiterConfig struct {
|
type RateLimiterConfig struct {
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
BeforeFunc BeforeFunc
|
BeforeFunc BeforeFunc
|
||||||
// IdentifierExtractor uses echo.Context to extract the identifier for a visitor
|
// IdentifierExtractor uses echo.Context to extract the identifier for a visitor
|
||||||
@ -34,17 +31,15 @@ type (
|
|||||||
// DenyHandler provides a handler to be called when RateLimiter denies access
|
// DenyHandler provides a handler to be called when RateLimiter denies access
|
||||||
DenyHandler func(context echo.Context, identifier string, err error) error
|
DenyHandler func(context echo.Context, identifier string, err error) error
|
||||||
}
|
}
|
||||||
// Extractor is used to extract data from echo.Context
|
|
||||||
Extractor func(context echo.Context) (string, error)
|
|
||||||
)
|
|
||||||
|
|
||||||
// errors
|
// Extractor is used to extract data from echo.Context
|
||||||
var (
|
type Extractor func(context echo.Context) (string, error)
|
||||||
|
|
||||||
// ErrRateLimitExceeded denotes an error raised when rate limit is exceeded
|
// ErrRateLimitExceeded denotes an error raised when rate limit is exceeded
|
||||||
ErrRateLimitExceeded = echo.NewHTTPError(http.StatusTooManyRequests, "rate limit exceeded")
|
var ErrRateLimitExceeded = echo.NewHTTPError(http.StatusTooManyRequests, "rate limit exceeded")
|
||||||
|
|
||||||
// ErrExtractorError denotes an error raised when extractor function is unsuccessful
|
// ErrExtractorError denotes an error raised when extractor function is unsuccessful
|
||||||
ErrExtractorError = echo.NewHTTPError(http.StatusForbidden, "error while extracting identifier")
|
var ErrExtractorError = echo.NewHTTPError(http.StatusForbidden, "error while extracting identifier")
|
||||||
)
|
|
||||||
|
|
||||||
// DefaultRateLimiterConfig defines default values for RateLimiterConfig
|
// DefaultRateLimiterConfig defines default values for RateLimiterConfig
|
||||||
var DefaultRateLimiterConfig = RateLimiterConfig{
|
var DefaultRateLimiterConfig = RateLimiterConfig{
|
||||||
@ -153,9 +148,8 @@ func RateLimiterWithConfig(config RateLimiterConfig) echo.MiddlewareFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
|
||||||
// RateLimiterMemoryStore is the built-in store implementation for RateLimiter
|
// RateLimiterMemoryStore is the built-in store implementation for RateLimiter
|
||||||
RateLimiterMemoryStore struct {
|
type RateLimiterMemoryStore struct {
|
||||||
visitors map[string]*Visitor
|
visitors map[string]*Visitor
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
rate rate.Limit // for more info check out Limiter docs - https://pkg.go.dev/golang.org/x/time/rate#Limit.
|
rate rate.Limit // for more info check out Limiter docs - https://pkg.go.dev/golang.org/x/time/rate#Limit.
|
||||||
@ -166,12 +160,12 @@ type (
|
|||||||
|
|
||||||
timeNow func() time.Time
|
timeNow func() time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
// Visitor signifies a unique user's limiter details
|
// Visitor signifies a unique user's limiter details
|
||||||
Visitor struct {
|
type Visitor struct {
|
||||||
*rate.Limiter
|
*rate.Limiter
|
||||||
lastSeen time.Time
|
lastSeen time.Time
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NewRateLimiterMemoryStore returns an instance of RateLimiterMemoryStore with
|
NewRateLimiterMemoryStore returns an instance of RateLimiterMemoryStore with
|
||||||
|
@ -12,12 +12,11 @@ import (
|
|||||||
"github.com/labstack/gommon/log"
|
"github.com/labstack/gommon/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// LogErrorFunc defines a function for custom logging in the middleware.
|
// LogErrorFunc defines a function for custom logging in the middleware.
|
||||||
LogErrorFunc func(c echo.Context, err error, stack []byte) error
|
type LogErrorFunc func(c echo.Context, err error, stack []byte) error
|
||||||
|
|
||||||
// RecoverConfig defines the config for Recover middleware.
|
// RecoverConfig defines the config for Recover middleware.
|
||||||
RecoverConfig struct {
|
type RecoverConfig struct {
|
||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
|
|
||||||
@ -48,11 +47,9 @@ type (
|
|||||||
// Optional. Default value false.
|
// Optional. Default value false.
|
||||||
DisableErrorHandler bool `yaml:"disable_error_handler"`
|
DisableErrorHandler bool `yaml:"disable_error_handler"`
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// DefaultRecoverConfig is the default Recover middleware config.
|
// DefaultRecoverConfig is the default Recover middleware config.
|
||||||
DefaultRecoverConfig = RecoverConfig{
|
var DefaultRecoverConfig = RecoverConfig{
|
||||||
Skipper: DefaultSkipper,
|
Skipper: DefaultSkipper,
|
||||||
StackSize: 4 << 10, // 4 KB
|
StackSize: 4 << 10, // 4 KB
|
||||||
DisableStackAll: false,
|
DisableStackAll: false,
|
||||||
@ -61,7 +58,6 @@ var (
|
|||||||
LogErrorFunc: nil,
|
LogErrorFunc: nil,
|
||||||
DisableErrorHandler: false,
|
DisableErrorHandler: false,
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// Recover returns a middleware which recovers from panics anywhere in the chain
|
// Recover returns a middleware which recovers from panics anywhere in the chain
|
||||||
// and handles the control to the centralized HTTPErrorHandler.
|
// and handles the control to the centralized HTTPErrorHandler.
|
||||||
|
@ -7,9 +7,8 @@ import (
|
|||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// RequestIDConfig defines the config for RequestID middleware.
|
// RequestIDConfig defines the config for RequestID middleware.
|
||||||
RequestIDConfig struct {
|
type RequestIDConfig struct {
|
||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
|
|
||||||
@ -23,16 +22,13 @@ type (
|
|||||||
// TargetHeader defines what header to look for to populate the id
|
// TargetHeader defines what header to look for to populate the id
|
||||||
TargetHeader string
|
TargetHeader string
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// DefaultRequestIDConfig is the default RequestID middleware config.
|
// DefaultRequestIDConfig is the default RequestID middleware config.
|
||||||
DefaultRequestIDConfig = RequestIDConfig{
|
var DefaultRequestIDConfig = RequestIDConfig{
|
||||||
Skipper: DefaultSkipper,
|
Skipper: DefaultSkipper,
|
||||||
Generator: generator,
|
Generator: generator,
|
||||||
TargetHeader: echo.HeaderXRequestID,
|
TargetHeader: echo.HeaderXRequestID,
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// RequestID returns a X-Request-ID middleware.
|
// RequestID returns a X-Request-ID middleware.
|
||||||
func RequestID() echo.MiddlewareFunc {
|
func RequestID() echo.MiddlewareFunc {
|
||||||
|
@ -9,9 +9,8 @@ import (
|
|||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// RewriteConfig defines the config for Rewrite middleware.
|
// RewriteConfig defines the config for Rewrite middleware.
|
||||||
RewriteConfig struct {
|
type RewriteConfig struct {
|
||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
|
|
||||||
@ -32,14 +31,11 @@ type (
|
|||||||
// "^/api/.+?/(.*)": "/v2/$1",
|
// "^/api/.+?/(.*)": "/v2/$1",
|
||||||
RegexRules map[*regexp.Regexp]string `yaml:"-"`
|
RegexRules map[*regexp.Regexp]string `yaml:"-"`
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// DefaultRewriteConfig is the default Rewrite middleware config.
|
// DefaultRewriteConfig is the default Rewrite middleware config.
|
||||||
DefaultRewriteConfig = RewriteConfig{
|
var DefaultRewriteConfig = RewriteConfig{
|
||||||
Skipper: DefaultSkipper,
|
Skipper: DefaultSkipper,
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// Rewrite returns a Rewrite middleware.
|
// Rewrite returns a Rewrite middleware.
|
||||||
//
|
//
|
||||||
|
@ -9,9 +9,8 @@ import (
|
|||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// SecureConfig defines the config for Secure middleware.
|
// SecureConfig defines the config for Secure middleware.
|
||||||
SecureConfig struct {
|
type SecureConfig struct {
|
||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
|
|
||||||
@ -75,18 +74,15 @@ type (
|
|||||||
// Optional. Default value "".
|
// Optional. Default value "".
|
||||||
ReferrerPolicy string `yaml:"referrer_policy"`
|
ReferrerPolicy string `yaml:"referrer_policy"`
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// DefaultSecureConfig is the default Secure middleware config.
|
// DefaultSecureConfig is the default Secure middleware config.
|
||||||
DefaultSecureConfig = SecureConfig{
|
var DefaultSecureConfig = SecureConfig{
|
||||||
Skipper: DefaultSkipper,
|
Skipper: DefaultSkipper,
|
||||||
XSSProtection: "1; mode=block",
|
XSSProtection: "1; mode=block",
|
||||||
ContentTypeNosniff: "nosniff",
|
ContentTypeNosniff: "nosniff",
|
||||||
XFrameOptions: "SAMEORIGIN",
|
XFrameOptions: "SAMEORIGIN",
|
||||||
HSTSPreloadEnabled: false,
|
HSTSPreloadEnabled: false,
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// Secure returns a Secure middleware.
|
// Secure returns a Secure middleware.
|
||||||
// Secure middleware provides protection against cross-site scripting (XSS) attack,
|
// Secure middleware provides protection against cross-site scripting (XSS) attack,
|
||||||
|
@ -9,9 +9,8 @@ import (
|
|||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// TrailingSlashConfig defines the config for TrailingSlash middleware.
|
// TrailingSlashConfig defines the config for TrailingSlash middleware.
|
||||||
TrailingSlashConfig struct {
|
type TrailingSlashConfig struct {
|
||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
|
|
||||||
@ -19,14 +18,11 @@ type (
|
|||||||
// Optional, but when provided the request is redirected using this code.
|
// Optional, but when provided the request is redirected using this code.
|
||||||
RedirectCode int `yaml:"redirect_code"`
|
RedirectCode int `yaml:"redirect_code"`
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// DefaultTrailingSlashConfig is the default TrailingSlash middleware config.
|
// DefaultTrailingSlashConfig is the default TrailingSlash middleware config.
|
||||||
DefaultTrailingSlashConfig = TrailingSlashConfig{
|
var DefaultTrailingSlashConfig = TrailingSlashConfig{
|
||||||
Skipper: DefaultSkipper,
|
Skipper: DefaultSkipper,
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// AddTrailingSlash returns a root level (before router) middleware which adds a
|
// AddTrailingSlash returns a root level (before router) middleware which adds a
|
||||||
// trailing slash to the request `URL#Path`.
|
// trailing slash to the request `URL#Path`.
|
||||||
|
@ -17,9 +17,8 @@ import (
|
|||||||
"github.com/labstack/gommon/bytes"
|
"github.com/labstack/gommon/bytes"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// StaticConfig defines the config for Static middleware.
|
// StaticConfig defines the config for Static middleware.
|
||||||
StaticConfig struct {
|
type StaticConfig struct {
|
||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
|
|
||||||
@ -50,7 +49,6 @@ type (
|
|||||||
// Optional. Defaults to http.Dir(config.Root)
|
// Optional. Defaults to http.Dir(config.Root)
|
||||||
Filesystem http.FileSystem `yaml:"-"`
|
Filesystem http.FileSystem `yaml:"-"`
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
const html = `
|
const html = `
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
@ -124,13 +122,11 @@ const html = `
|
|||||||
</html>
|
</html>
|
||||||
`
|
`
|
||||||
|
|
||||||
var (
|
|
||||||
// DefaultStaticConfig is the default Static middleware config.
|
// DefaultStaticConfig is the default Static middleware config.
|
||||||
DefaultStaticConfig = StaticConfig{
|
var DefaultStaticConfig = StaticConfig{
|
||||||
Skipper: DefaultSkipper,
|
Skipper: DefaultSkipper,
|
||||||
Index: "index.html",
|
Index: "index.html",
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// Static returns a Static middleware to serves static content from the provided
|
// Static returns a Static middleware to serves static content from the provided
|
||||||
// root directory.
|
// root directory.
|
||||||
|
@ -80,14 +80,12 @@ type TimeoutConfig struct {
|
|||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
// DefaultTimeoutConfig is the default Timeout middleware config.
|
// DefaultTimeoutConfig is the default Timeout middleware config.
|
||||||
DefaultTimeoutConfig = TimeoutConfig{
|
var DefaultTimeoutConfig = TimeoutConfig{
|
||||||
Skipper: DefaultSkipper,
|
Skipper: DefaultSkipper,
|
||||||
Timeout: 0,
|
Timeout: 0,
|
||||||
ErrorMessage: "",
|
ErrorMessage: "",
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// Timeout returns a middleware which returns error (503 Service Unavailable error) to client immediately when handler
|
// Timeout returns a middleware which returns error (503 Service Unavailable error) to client immediately when handler
|
||||||
// call runs for longer than its time limit. NB: timeout does not stop handler execution.
|
// call runs for longer than its time limit. NB: timeout does not stop handler execution.
|
||||||
|
@ -10,11 +10,10 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// Response wraps an http.ResponseWriter and implements its interface to be used
|
// Response wraps an http.ResponseWriter and implements its interface to be used
|
||||||
// by an HTTP handler to construct an HTTP response.
|
// by an HTTP handler to construct an HTTP response.
|
||||||
// See: https://golang.org/pkg/net/http/#ResponseWriter
|
// See: https://golang.org/pkg/net/http/#ResponseWriter
|
||||||
Response struct {
|
type Response struct {
|
||||||
echo *Echo
|
echo *Echo
|
||||||
beforeFuncs []func()
|
beforeFuncs []func()
|
||||||
afterFuncs []func()
|
afterFuncs []func()
|
||||||
@ -23,7 +22,6 @@ type (
|
|||||||
Size int64
|
Size int64
|
||||||
Committed bool
|
Committed bool
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// NewResponse creates a new instance of Response.
|
// NewResponse creates a new instance of Response.
|
||||||
func NewResponse(w http.ResponseWriter, e *Echo) (r *Response) {
|
func NewResponse(w http.ResponseWriter, e *Echo) (r *Response) {
|
||||||
|
18
router.go
18
router.go
@ -9,15 +9,15 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
// Router is the registry of all registered routes for an `Echo` instance for
|
// Router is the registry of all registered routes for an `Echo` instance for
|
||||||
// request matching and URL path parameter parsing.
|
// request matching and URL path parameter parsing.
|
||||||
Router struct {
|
type Router struct {
|
||||||
tree *node
|
tree *node
|
||||||
routes map[string]*Route
|
routes map[string]*Route
|
||||||
echo *Echo
|
echo *Echo
|
||||||
}
|
}
|
||||||
node struct {
|
|
||||||
|
type node struct {
|
||||||
kind kind
|
kind kind
|
||||||
label byte
|
label byte
|
||||||
prefix string
|
prefix string
|
||||||
@ -36,14 +36,17 @@ type (
|
|||||||
// notFoundHandler is handler registered with RouteNotFound method and is executed for 404 cases
|
// notFoundHandler is handler registered with RouteNotFound method and is executed for 404 cases
|
||||||
notFoundHandler *routeMethod
|
notFoundHandler *routeMethod
|
||||||
}
|
}
|
||||||
kind uint8
|
|
||||||
children []*node
|
type kind uint8
|
||||||
routeMethod struct {
|
type children []*node
|
||||||
|
|
||||||
|
type routeMethod struct {
|
||||||
ppath string
|
ppath string
|
||||||
pnames []string
|
pnames []string
|
||||||
handler HandlerFunc
|
handler HandlerFunc
|
||||||
}
|
}
|
||||||
routeMethods struct {
|
|
||||||
|
type routeMethods struct {
|
||||||
connect *routeMethod
|
connect *routeMethod
|
||||||
delete *routeMethod
|
delete *routeMethod
|
||||||
get *routeMethod
|
get *routeMethod
|
||||||
@ -58,7 +61,6 @@ type (
|
|||||||
anyOther map[string]*routeMethod
|
anyOther map[string]*routeMethod
|
||||||
allowHeader string
|
allowHeader string
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
staticKind kind = iota
|
staticKind kind = iota
|
||||||
|
Loading…
Reference in New Issue
Block a user