summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/labstack/echo
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/labstack/echo')
-rw-r--r--vendor/github.com/labstack/echo/v4/CHANGELOG.md37
-rw-r--r--vendor/github.com/labstack/echo/v4/Makefile6
-rw-r--r--vendor/github.com/labstack/echo/v4/context.go13
-rw-r--r--vendor/github.com/labstack/echo/v4/echo.go146
-rw-r--r--vendor/github.com/labstack/echo/v4/echo_fs.go18
-rw-r--r--vendor/github.com/labstack/echo/v4/ip.go7
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/body_dump.go5
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/compress.go5
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/csrf.go2
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/extractor.go20
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/jwt.go6
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/logger.go14
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/proxy.go17
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/rate_limiter.go11
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/request_logger.go102
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/slash.go2
-rw-r--r--vendor/github.com/labstack/echo/v4/router.go46
17 files changed, 318 insertions, 139 deletions
diff --git a/vendor/github.com/labstack/echo/v4/CHANGELOG.md b/vendor/github.com/labstack/echo/v4/CHANGELOG.md
index 8b71fb8e..c1c3c107 100644
--- a/vendor/github.com/labstack/echo/v4/CHANGELOG.md
+++ b/vendor/github.com/labstack/echo/v4/CHANGELOG.md
@@ -1,5 +1,42 @@
# Changelog
+## v4.10.0 - 2022-12-27
+
+**Security**
+
+* We are deprecating JWT middleware in this repository. Please use https://github.com/labstack/echo-jwt instead.
+
+ JWT middleware is moved to separate repository to allow us to bump/upgrade version of JWT implementation (`github.com/golang-jwt/jwt`) we are using
+which we can not do in Echo core because this would break backwards compatibility guarantees we try to maintain.
+
+* This minor version bumps minimum Go version to 1.17 (from 1.16) due `golang.org/x/` packages we depend on. There are
+ several vulnerabilities fixed in these libraries.
+
+ Echo still tries to support last 4 Go versions but there are occasions we can not guarantee this promise.
+
+
+**Enhancements**
+
+* Bump x/text to 0.3.8 [#2305](https://github.com/labstack/echo/pull/2305)
+* Bump dependencies and add notes about Go releases we support [#2336](https://github.com/labstack/echo/pull/2336)
+* Add helper interface for ProxyBalancer interface [#2316](https://github.com/labstack/echo/pull/2316)
+* Expose `middleware.CreateExtractors` function so we can use it from echo-contrib repository [#2338](https://github.com/labstack/echo/pull/2338)
+* Refactor func(Context) error to HandlerFunc [#2315](https://github.com/labstack/echo/pull/2315)
+* Improve function comments [#2329](https://github.com/labstack/echo/pull/2329)
+* Add new method HTTPError.WithInternal [#2340](https://github.com/labstack/echo/pull/2340)
+* Replace io/ioutil package usages [#2342](https://github.com/labstack/echo/pull/2342)
+* Add staticcheck to CI flow [#2343](https://github.com/labstack/echo/pull/2343)
+* Replace relative path determination from proprietary to std [#2345](https://github.com/labstack/echo/pull/2345)
+* Remove square brackets from ipv6 addresses in XFF (X-Forwarded-For header) [#2182](https://github.com/labstack/echo/pull/2182)
+* Add testcases for some BodyLimit middleware configuration options [#2350](https://github.com/labstack/echo/pull/2350)
+* Additional configuration options for RequestLogger and Logger middleware [#2341](https://github.com/labstack/echo/pull/2341)
+* Add route to request log [#2162](https://github.com/labstack/echo/pull/2162)
+* GitHub Workflows security hardening [#2358](https://github.com/labstack/echo/pull/2358)
+* Add govulncheck to CI and bump dependencies [#2362](https://github.com/labstack/echo/pull/2362)
+* Fix rate limiter docs [#2366](https://github.com/labstack/echo/pull/2366)
+* Refactor how `e.Routes()` work and introduce `e.OnAddRouteHandler` callback [#2337](https://github.com/labstack/echo/pull/2337)
+
+
## v4.9.1 - 2022-10-12
**Fixes**
diff --git a/vendor/github.com/labstack/echo/v4/Makefile b/vendor/github.com/labstack/echo/v4/Makefile
index a6c4aaa9..6aff6a89 100644
--- a/vendor/github.com/labstack/echo/v4/Makefile
+++ b/vendor/github.com/labstack/echo/v4/Makefile
@@ -10,8 +10,10 @@ check: lint vet race ## Check project
init:
@go install golang.org/x/lint/golint@latest
+ @go install honnef.co/go/tools/cmd/staticcheck@latest
lint: ## Lint the files
+ @staticcheck ${PKG_LIST}
@golint -set_exit_status ${PKG_LIST}
vet: ## Vet the files
@@ -29,6 +31,6 @@ benchmark: ## Run benchmarks
help: ## Display this help screen
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
-goversion ?= "1.16"
-test_version: ## Run tests inside Docker with given version (defaults to 1.15 oldest supported). Example: make test_version goversion=1.16
+goversion ?= "1.17"
+test_version: ## Run tests inside Docker with given version (defaults to 1.17 oldest supported). Example: make test_version goversion=1.17
@docker run --rm -it -v $(shell pwd):/project golang:$(goversion) /bin/sh -c "cd /project && make init check"
diff --git a/vendor/github.com/labstack/echo/v4/context.go b/vendor/github.com/labstack/echo/v4/context.go
index 5567100b..b3a7ce8d 100644
--- a/vendor/github.com/labstack/echo/v4/context.go
+++ b/vendor/github.com/labstack/echo/v4/context.go
@@ -169,7 +169,11 @@ type (
// Redirect redirects the request to a provided URL with status code.
Redirect(code int, url string) error
- // Error invokes the registered HTTP error handler. Generally used by middleware.
+ // Error invokes the registered global HTTP error handler. Generally used by middleware.
+ // A side-effect of calling global error handler is that now Response has been committed (sent to the client) and
+ // middlewares up in chain can not change Response status code or Response body anymore.
+ //
+ // Avoid using this method in handlers as no middleware will be able to effectively handle errors after that.
Error(err error)
// Handler returns the matched handler by router.
@@ -282,11 +286,16 @@ func (c *context) RealIP() string {
if ip := c.request.Header.Get(HeaderXForwardedFor); ip != "" {
i := strings.IndexAny(ip, ",")
if i > 0 {
- return strings.TrimSpace(ip[:i])
+ xffip := strings.TrimSpace(ip[:i])
+ xffip = strings.TrimPrefix(xffip, "[")
+ xffip = strings.TrimSuffix(xffip, "]")
+ return xffip
}
return ip
}
if ip := c.request.Header.Get(HeaderXRealIP); ip != "" {
+ ip = strings.TrimPrefix(ip, "[")
+ ip = strings.TrimSuffix(ip, "]")
return ip
}
ra, _, _ := net.SplitHostPort(c.request.RemoteAddr)
diff --git a/vendor/github.com/labstack/echo/v4/echo.go b/vendor/github.com/labstack/echo/v4/echo.go
index 5ae8a142..f6d89b96 100644
--- a/vendor/github.com/labstack/echo/v4/echo.go
+++ b/vendor/github.com/labstack/echo/v4/echo.go
@@ -3,50 +3,49 @@ Package echo implements high performance, minimalist Go web framework.
Example:
- package main
+ package main
- import (
- "net/http"
+ import (
+ "net/http"
- "github.com/labstack/echo/v4"
- "github.com/labstack/echo/v4/middleware"
- )
+ "github.com/labstack/echo/v4"
+ "github.com/labstack/echo/v4/middleware"
+ )
- // Handler
- func hello(c echo.Context) error {
- return c.String(http.StatusOK, "Hello, World!")
- }
+ // Handler
+ func hello(c echo.Context) error {
+ return c.String(http.StatusOK, "Hello, World!")
+ }
- func main() {
- // Echo instance
- e := echo.New()
+ func main() {
+ // Echo instance
+ e := echo.New()
- // Middleware
- e.Use(middleware.Logger())
- e.Use(middleware.Recover())
+ // Middleware
+ e.Use(middleware.Logger())
+ e.Use(middleware.Recover())
- // Routes
- e.GET("/", hello)
+ // Routes
+ e.GET("/", hello)
- // Start server
- e.Logger.Fatal(e.Start(":1323"))
- }
+ // Start server
+ e.Logger.Fatal(e.Start(":1323"))
+ }
Learn more at https://echo.labstack.com
*/
package echo
import (
- "bytes"
stdContext "context"
"crypto/tls"
"errors"
"fmt"
"io"
- "io/ioutil"
stdLog "log"
"net"
"net/http"
+ "os"
"reflect"
"runtime"
"sync"
@@ -62,20 +61,28 @@ import (
type (
// Echo is the top-level framework instance.
+ //
+ // 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.
+ // Adding new routes after the server has been started is also not safe!
Echo struct {
filesystem
common
// startupMutex is mutex to lock Echo instance access during server configuration and startup. Useful for to get
// listener address info (on which interface/port was listener binded) without having data races.
- startupMutex sync.RWMutex
+ startupMutex sync.RWMutex
+ colorer *color.Color
+
+ // premiddleware are middlewares that are run before routing is done. In case a pre-middleware returns
+ // an error the router is not executed and the request will end up in the global error handler.
+ premiddleware []MiddlewareFunc
+ middleware []MiddlewareFunc
+ maxParam *int
+ router *Router
+ routers map[string]*Router
+ pool sync.Pool
+
StdLogger *stdLog.Logger
- colorer *color.Color
- premiddleware []MiddlewareFunc
- middleware []MiddlewareFunc
- maxParam *int
- router *Router
- routers map[string]*Router
- pool sync.Pool
Server *http.Server
TLSServer *http.Server
Listener net.Listener
@@ -93,6 +100,9 @@ type (
Logger Logger
IPExtractor IPExtractor
ListenerNetwork string
+
+ // OnAddRouteHandler is called when Echo adds new route to specific host router.
+ OnAddRouteHandler func(host string, route Route, handler HandlerFunc, middleware []MiddlewareFunc)
}
// Route contains a handler and information for matching against requests.
@@ -116,7 +126,7 @@ type (
HandlerFunc func(c Context) error
// HTTPErrorHandler is a centralized HTTP error handler.
- HTTPErrorHandler func(error, Context)
+ HTTPErrorHandler func(err error, c Context)
// Validator is the interface that wraps the Validate function.
Validator interface {
@@ -248,7 +258,7 @@ const (
const (
// Version of Echo
- Version = "4.9.0"
+ Version = "4.10.0"
website = "https://echo.labstack.com"
// http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo
banner = `
@@ -527,21 +537,20 @@ func (e *Echo) File(path, file string, m ...MiddlewareFunc) *Route {
return e.file(path, file, e.GET, m...)
}
-func (e *Echo) add(host, method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route {
- name := handlerName(handler)
+func (e *Echo) add(host, method, path string, handler HandlerFunc, middlewares ...MiddlewareFunc) *Route {
router := e.findRouter(host)
- // FIXME: when handler+middleware are both nil ... make it behave like handler removal
- router.Add(method, path, func(c Context) error {
- h := applyMiddleware(handler, middleware...)
+ //FIXME: when handler+middleware are both nil ... make it behave like handler removal
+ name := handlerName(handler)
+ route := router.add(method, path, name, func(c Context) error {
+ h := applyMiddleware(handler, middlewares...)
return h(c)
})
- r := &Route{
- Method: method,
- Path: path,
- Name: name,
+
+ if e.OnAddRouteHandler != nil {
+ e.OnAddRouteHandler(host, *route, handler, middlewares)
}
- e.router.routes[method+path] = r
- return r
+
+ return route
}
// Add registers a new route for an HTTP method and path with matching handler
@@ -565,7 +574,7 @@ func (e *Echo) Group(prefix string, m ...MiddlewareFunc) (g *Group) {
return
}
-// URI generates a URI from handler.
+// URI generates an URI from handler.
func (e *Echo) URI(handler HandlerFunc, params ...interface{}) string {
name := handlerName(handler)
return e.Reverse(name, params...)
@@ -578,35 +587,13 @@ func (e *Echo) URL(h HandlerFunc, params ...interface{}) string {
// Reverse generates an URL from route name and provided parameters.
func (e *Echo) Reverse(name string, params ...interface{}) string {
- uri := new(bytes.Buffer)
- ln := len(params)
- n := 0
- for _, r := range e.router.routes {
- if r.Name == name {
- for i, l := 0, len(r.Path); i < l; i++ {
- if (r.Path[i] == ':' || r.Path[i] == '*') && n < ln {
- for ; i < l && r.Path[i] != '/'; i++ {
- }
- uri.WriteString(fmt.Sprintf("%v", params[n]))
- n++
- }
- if i < l {
- uri.WriteByte(r.Path[i])
- }
- }
- break
- }
- }
- return uri.String()
+ return e.router.Reverse(name, params...)
}
-// Routes returns the registered routes.
+// Routes returns the registered routes for default router.
+// In case when Echo serves multiple hosts/domains use `e.Routers()["domain2.site"].Routes()` to get specific host routes.
func (e *Echo) Routes() []*Route {
- routes := make([]*Route, 0, len(e.router.routes))
- for _, v := range e.router.routes {
- routes = append(routes, v)
- }
- return routes
+ return e.router.Routes()
}
// AcquireContext returns an empty `Context` instance from the pool.
@@ -626,7 +613,7 @@ func (e *Echo) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Acquire context
c := e.pool.Get().(*context)
c.Reset(r, w)
- var h func(Context) error
+ var h HandlerFunc
if e.premiddleware == nil {
e.findRouter(r.Host).Find(r.Method, GetPath(r), c)
@@ -700,7 +687,7 @@ func (e *Echo) StartTLS(address string, certFile, keyFile interface{}) (err erro
func filepathOrContent(fileOrContent interface{}) (content []byte, err error) {
switch v := fileOrContent.(type) {
case string:
- return ioutil.ReadFile(v)
+ return os.ReadFile(v)
case []byte:
return v, nil
default:
@@ -884,6 +871,15 @@ func (he *HTTPError) SetInternal(err error) *HTTPError {
return he
}
+// WithInternal returns clone of HTTPError with err set to HTTPError.Internal field
+func (he *HTTPError) WithInternal(err error) *HTTPError {
+ return &HTTPError{
+ Code: he.Code,
+ Message: he.Message,
+ Internal: err,
+ }
+}
+
// Unwrap satisfies the Go 1.13 error wrapper interface.
func (he *HTTPError) Unwrap() error {
return he.Internal
@@ -913,8 +909,8 @@ func WrapMiddleware(m func(http.Handler) http.Handler) MiddlewareFunc {
// GetPath returns RawPath, if it's empty returns Path from URL
// Difference between RawPath and Path is:
-// * Path is where request path is stored. Value is stored in decoded form: /%47%6f%2f becomes /Go/.
-// * RawPath is an optional field which only gets set if the default encoding is different from Path.
+// - Path is where request path is stored. Value is stored in decoded form: /%47%6f%2f becomes /Go/.
+// - RawPath is an optional field which only gets set if the default encoding is different from Path.
func GetPath(r *http.Request) string {
path := r.URL.RawPath
if path == "" {
diff --git a/vendor/github.com/labstack/echo/v4/echo_fs.go b/vendor/github.com/labstack/echo/v4/echo_fs.go
index b8526da9..9f83a035 100644
--- a/vendor/github.com/labstack/echo/v4/echo_fs.go
+++ b/vendor/github.com/labstack/echo/v4/echo_fs.go
@@ -7,7 +7,6 @@ import (
"net/url"
"os"
"path/filepath"
- "runtime"
"strings"
)
@@ -125,7 +124,7 @@ func subFS(currentFs fs.FS, root string) (fs.FS, error) {
// we need to make exception for `defaultFS` instances as it interprets root prefix differently from fs.FS.
// fs.Fs.Open does not like relative paths ("./", "../") and absolute paths at all but prior echo.Filesystem we
// were able to use paths like `./myfile.log`, `/etc/hosts` and these would work fine with `os.Open` but not with fs.Fs
- if isRelativePath(root) {
+ if !filepath.IsAbs(root) {
root = filepath.Join(dFS.prefix, root)
}
return &defaultFS{
@@ -136,21 +135,6 @@ func subFS(currentFs fs.FS, root string) (fs.FS, error) {
return fs.Sub(currentFs, root)
}
-func isRelativePath(path string) bool {
- if path == "" {
- return true
- }
- if path[0] == '/' {
- return false
- }
- if runtime.GOOS == "windows" && strings.IndexByte(path, ':') != -1 {
- // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN#file_and_directory_names
- // https://docs.microsoft.com/en-us/dotnet/standard/io/file-path-formats
- return false
- }
- return true
-}
-
// MustSubFS creates sub FS from current filesystem or panic on failure.
// Panic happens when `fsRoot` contains invalid path according to `fs.ValidPath` rules.
//
diff --git a/vendor/github.com/labstack/echo/v4/ip.go b/vendor/github.com/labstack/echo/v4/ip.go
index 46d464cf..1bcd756a 100644
--- a/vendor/github.com/labstack/echo/v4/ip.go
+++ b/vendor/github.com/labstack/echo/v4/ip.go
@@ -227,6 +227,8 @@ func ExtractIPFromRealIPHeader(options ...TrustOption) IPExtractor {
return func(req *http.Request) string {
realIP := req.Header.Get(HeaderXRealIP)
if realIP != "" {
+ realIP = strings.TrimPrefix(realIP, "[")
+ realIP = strings.TrimSuffix(realIP, "]")
if ip := net.ParseIP(realIP); ip != nil && checker.trust(ip) {
return realIP
}
@@ -248,7 +250,10 @@ func ExtractIPFromXFFHeader(options ...TrustOption) IPExtractor {
}
ips := append(strings.Split(strings.Join(xffs, ","), ","), directIP)
for i := len(ips) - 1; i >= 0; i-- {
- ip := net.ParseIP(strings.TrimSpace(ips[i]))
+ ips[i] = strings.TrimSpace(ips[i])
+ ips[i] = strings.TrimPrefix(ips[i], "[")
+ ips[i] = strings.TrimSuffix(ips[i], "]")
+ ip := net.ParseIP(ips[i])
if ip == nil {
// Unable to parse IP; cannot trust entire records
return directIP
diff --git a/vendor/github.com/labstack/echo/v4/middleware/body_dump.go b/vendor/github.com/labstack/echo/v4/middleware/body_dump.go
index ebd0d0ab..fa7891b1 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/body_dump.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/body_dump.go
@@ -4,7 +4,6 @@ import (
"bufio"
"bytes"
"io"
- "io/ioutil"
"net"
"net/http"
@@ -68,9 +67,9 @@ func BodyDumpWithConfig(config BodyDumpConfig) echo.MiddlewareFunc {
// Request
reqBody := []byte{}
if c.Request().Body != nil { // Read
- reqBody, _ = ioutil.ReadAll(c.Request().Body)
+ reqBody, _ = io.ReadAll(c.Request().Body)
}
- c.Request().Body = ioutil.NopCloser(bytes.NewBuffer(reqBody)) // Reset
+ c.Request().Body = io.NopCloser(bytes.NewBuffer(reqBody)) // Reset
// Response
resBody := new(bytes.Buffer)
diff --git a/vendor/github.com/labstack/echo/v4/middleware/compress.go b/vendor/github.com/labstack/echo/v4/middleware/compress.go
index ac6672e9..9e5f6106 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/compress.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/compress.go
@@ -4,7 +4,6 @@ import (
"bufio"
"compress/gzip"
"io"
- "io/ioutil"
"net"
"net/http"
"strings"
@@ -89,7 +88,7 @@ func GzipWithConfig(config GzipConfig) echo.MiddlewareFunc {
// nothing is written to body or error is returned.
// See issue #424, #407.
res.Writer = rw
- w.Reset(ioutil.Discard)
+ w.Reset(io.Discard)
}
w.Close()
pool.Put(w)
@@ -135,7 +134,7 @@ func (w *gzipResponseWriter) Push(target string, opts *http.PushOptions) error {
func gzipCompressPool(config GzipConfig) sync.Pool {
return sync.Pool{
New: func() interface{} {
- w, err := gzip.NewWriterLevel(ioutil.Discard, config.Level)
+ w, err := gzip.NewWriterLevel(io.Discard, config.Level)
if err != nil {
return err
}
diff --git a/vendor/github.com/labstack/echo/v4/middleware/csrf.go b/vendor/github.com/labstack/echo/v4/middleware/csrf.go
index ea90fdba..8661c9f8 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/csrf.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/csrf.go
@@ -119,7 +119,7 @@ func CSRFWithConfig(config CSRFConfig) echo.MiddlewareFunc {
config.CookieSecure = true
}
- extractors, err := createExtractors(config.TokenLookup, "")
+ extractors, err := CreateExtractors(config.TokenLookup)
if err != nil {
panic(err)
}
diff --git a/vendor/github.com/labstack/echo/v4/middleware/extractor.go b/vendor/github.com/labstack/echo/v4/middleware/extractor.go
index afdfd819..5d9cee6d 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/extractor.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/extractor.go
@@ -24,6 +24,26 @@ var errFormExtractorValueMissing = errors.New("missing value in the form")
// ValuesExtractor defines a function for extracting values (keys/tokens) from the given context.
type ValuesExtractor func(c echo.Context) ([]string, error)
+// CreateExtractors creates ValuesExtractors from given lookups.
+// Lookups is a string in the form of "<source>:<name>" or "<source>:<name>,<source>:<name>" that is used
+// to extract key from the request.
+// Possible values:
+// - "header:<name>" or "header:<name>:<cut-prefix>"
+// `<cut-prefix>` is argument value to cut/trim prefix of the extracted value. This is useful if header
+// value has static prefix like `Authorization: <auth-scheme> <authorisation-parameters>` where part that we
+// want to cut is `<auth-scheme> ` note the space at the end.
+// In case of basic authentication `Authorization: Basic <credentials>` prefix we want to remove is `Basic `.
+// - "query:<name>"
+// - "param:<name>"
+// - "form:<name>"
+// - "cookie:<name>"
+//
+// Multiple sources example:
+// - "header:Authorization,header:X-Api-Key"
+func CreateExtractors(lookups string) ([]ValuesExtractor, error) {
+ return createExtractors(lookups, "")
+}
+
func createExtractors(lookups string, authScheme string) ([]ValuesExtractor, error) {
if lookups == "" {
return nil, nil
diff --git a/vendor/github.com/labstack/echo/v4/middleware/jwt.go b/vendor/github.com/labstack/echo/v4/middleware/jwt.go
index bec5167e..bd628264 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/jwt.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/jwt.go
@@ -154,6 +154,8 @@ var (
//
// See: https://jwt.io/introduction
// See `JWTConfig.TokenLookup`
+//
+// Deprecated: Please use https://github.com/labstack/echo-jwt instead
func JWT(key interface{}) echo.MiddlewareFunc {
c := DefaultJWTConfig
c.SigningKey = key
@@ -162,6 +164,8 @@ func JWT(key interface{}) echo.MiddlewareFunc {
// JWTWithConfig returns a JWT auth middleware with config.
// See: `JWT()`.
+//
+// Deprecated: Please use https://github.com/labstack/echo-jwt instead
func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
// Defaults
if config.Skipper == nil {
@@ -262,7 +266,7 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
}
func (config *JWTConfig) defaultParseToken(auth string, c echo.Context) (interface{}, error) {
- token := new(jwt.Token)
+ var token *jwt.Token
var err error
// Issue #647, #656
if _, ok := config.Claims.(jwt.MapClaims); ok {
diff --git a/vendor/github.com/labstack/echo/v4/middleware/logger.go b/vendor/github.com/labstack/echo/v4/middleware/logger.go
index a21df8f3..7958d873 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/logger.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/logger.go
@@ -35,6 +35,7 @@ type (
// - host
// - method
// - path
+ // - route
// - protocol
// - referer
// - user_agent
@@ -47,6 +48,7 @@ type (
// - header:<NAME>
// - query:<NAME>
// - form:<NAME>
+ // - custom (see CustomTagFunc field)
//
// Example "${remote_ip} ${status}"
//
@@ -56,6 +58,11 @@ type (
// Optional. Default value DefaultLoggerConfig.CustomTimeFormat.
CustomTimeFormat string `yaml:"custom_time_format"`
+ // CustomTagFunc is function called for `${custom}` tag to output user implemented text by writing it to buf.
+ // Make sure that outputted text creates valid JSON string with other logged tags.
+ // Optional.
+ CustomTagFunc func(c echo.Context, buf *bytes.Buffer) (int, error)
+
// Output is a writer where logs in JSON format are written.
// Optional. Default value os.Stdout.
Output io.Writer
@@ -126,6 +133,11 @@ func LoggerWithConfig(config LoggerConfig) echo.MiddlewareFunc {
if _, err = config.template.ExecuteFunc(buf, func(w io.Writer, tag string) (int, error) {
switch tag {
+ case "custom":
+ if config.CustomTagFunc == nil {
+ return 0, nil
+ }
+ return config.CustomTagFunc(c, buf)
case "time_unix":
return buf.WriteString(strconv.FormatInt(time.Now().Unix(), 10))
case "time_unix_milli":
@@ -162,6 +174,8 @@ func LoggerWithConfig(config LoggerConfig) echo.MiddlewareFunc {
p = "/"
}
return buf.WriteString(p)
+ case "route":
+ return buf.WriteString(c.Path())
case "protocol":
return buf.WriteString(req.Proto)
case "referer":
diff --git a/vendor/github.com/labstack/echo/v4/middleware/proxy.go b/vendor/github.com/labstack/echo/v4/middleware/proxy.go
index 6cfd6731..d2cd2aa6 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/proxy.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/proxy.go
@@ -72,6 +72,11 @@ type (
Next(echo.Context) *ProxyTarget
}
+ // TargetProvider defines an interface that gives the opportunity for balancer to return custom errors when selecting target.
+ TargetProvider interface {
+ NextTarget(echo.Context) (*ProxyTarget, error)
+ }
+
commonBalancer struct {
targets []*ProxyTarget
mutex sync.RWMutex
@@ -223,6 +228,7 @@ func ProxyWithConfig(config ProxyConfig) echo.MiddlewareFunc {
}
}
+ provider, isTargetProvider := config.Balancer.(TargetProvider)
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) (err error) {
if config.Skipper(c) {
@@ -231,7 +237,16 @@ func ProxyWithConfig(config ProxyConfig) echo.MiddlewareFunc {
req := c.Request()
res := c.Response()
- tgt := config.Balancer.Next(c)
+
+ var tgt *ProxyTarget
+ if isTargetProvider {
+ tgt, err = provider.NextTarget(c)
+ if err != nil {
+ return err
+ }
+ } else {
+ tgt = config.Balancer.Next(c)
+ }
c.Set(config.ContextKey, tgt)
if err := rewriteURL(config.RegexRewrite, req); err != nil {
diff --git a/vendor/github.com/labstack/echo/v4/middleware/rate_limiter.go b/vendor/github.com/labstack/echo/v4/middleware/rate_limiter.go
index be2b348d..f7fae83c 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/rate_limiter.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/rate_limiter.go
@@ -155,7 +155,7 @@ type (
RateLimiterMemoryStore struct {
visitors map[string]*Visitor
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.
burst int
expiresIn time.Duration
@@ -170,15 +170,16 @@ type (
/*
NewRateLimiterMemoryStore returns an instance of RateLimiterMemoryStore with
-the provided rate (as req/s). The provided rate less than 1 will be treated as zero.
+the provided rate (as req/s).
for more info check out Limiter docs - https://pkg.go.dev/golang.org/x/time/rate#Limit.
Burst and ExpiresIn will be set to default values.
+Note that if the provided rate is a float number and Burst is zero, Burst will be treated as the rounded down value of the rate.
+
Example (with 20 requests/sec):
limiterStore := middleware.NewRateLimiterMemoryStore(20)
-
*/
func NewRateLimiterMemoryStore(rate rate.Limit) (store *RateLimiterMemoryStore) {
return NewRateLimiterMemoryStoreWithConfig(RateLimiterMemoryStoreConfig{
@@ -188,7 +189,7 @@ func NewRateLimiterMemoryStore(rate rate.Limit) (store *RateLimiterMemoryStore)
/*
NewRateLimiterMemoryStoreWithConfig returns an instance of RateLimiterMemoryStore
-with the provided configuration. Rate must be provided. Burst will be set to the value of
+with the provided configuration. Rate must be provided. Burst will be set to the rounded down value of
the configured rate if not provided or set to 0.
The build-in memory store is usually capable for modest loads. For higher loads other
@@ -225,7 +226,7 @@ func NewRateLimiterMemoryStoreWithConfig(config RateLimiterMemoryStoreConfig) (s
// RateLimiterMemoryStoreConfig represents configuration for RateLimiterMemoryStore
type RateLimiterMemoryStoreConfig struct {
Rate rate.Limit // Rate of requests allowed to pass as req/s. For more info check out Limiter docs - https://pkg.go.dev/golang.org/x/time/rate#Limit.
- Burst int // Burst additionally allows a number of requests to pass when rate limit is reached
+ Burst int // Burst is maximum number of requests to pass at the same moment. It additionally allows a number of requests to pass when rate limit is reached.
ExpiresIn time.Duration // ExpiresIn is the duration after that a rate limiter is cleaned up
}
diff --git a/vendor/github.com/labstack/echo/v4/middleware/request_logger.go b/vendor/github.com/labstack/echo/v4/middleware/request_logger.go
index 7a4d9822..b9e36925 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/request_logger.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/request_logger.go
@@ -10,10 +10,16 @@ import (
// Example for `fmt.Printf`
// e.Use(middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{
-// LogStatus: true,
-// LogURI: true,
+// LogStatus: true,
+// LogURI: true,
+// LogError: true,
+// HandleError: true, // forwards error to the global error handler, so it can decide appropriate status code
// LogValuesFunc: func(c echo.Context, v middleware.RequestLoggerValues) error {
-// fmt.Printf("REQUEST: uri: %v, status: %v\n", v.URI, v.Status)
+// if v.Error == nil {
+// fmt.Printf("REQUEST: uri: %v, status: %v\n", v.URI, v.Status)
+// } else {
+// fmt.Printf("REQUEST_ERROR: uri: %v, status: %v, err: %v\n", v.URI, v.Status, v.Error)
+// }
// return nil
// },
// }))
@@ -21,14 +27,23 @@ import (
// Example for Zerolog (https://github.com/rs/zerolog)
// logger := zerolog.New(os.Stdout)
// e.Use(middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{
-// LogURI: true,
-// LogStatus: true,
+// LogURI: true,
+// LogStatus: true,
+// LogError: true,
+// HandleError: true, // forwards error to the global error handler, so it can decide appropriate status code
// LogValuesFunc: func(c echo.Context, v middleware.RequestLoggerValues) error {
-// logger.Info().
-// Str("URI", v.URI).
-// Int("status", v.Status).
-// Msg("request")
-//
+// if v.Error == nil {
+// logger.Info().
+// Str("URI", v.URI).
+// Int("status", v.Status).
+// Msg("request")
+// } else {
+// logger.Error().
+// Err(v.Error).
+// Str("URI", v.URI).
+// Int("status", v.Status).
+// Msg("request error")
+// }
// return nil
// },
// }))
@@ -36,29 +51,47 @@ import (
// Example for Zap (https://github.com/uber-go/zap)
// logger, _ := zap.NewProduction()
// e.Use(middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{
-// LogURI: true,
-// LogStatus: true,
+// LogURI: true,
+// LogStatus: true,
+// LogError: true,
+// HandleError: true, // forwards error to the global error handler, so it can decide appropriate status code
// LogValuesFunc: func(c echo.Context, v middleware.RequestLoggerValues) error {
-// logger.Info("request",
-// zap.String("URI", v.URI),
-// zap.Int("status", v.Status),
-// )
-//
+// if v.Error == nil {
+// logger.Info("request",
+// zap.String("URI", v.URI),
+// zap.Int("status", v.Status),
+// )
+// } else {
+// logger.Error("request error",
+// zap.String("URI", v.URI),
+// zap.Int("status", v.Status),
+// zap.Error(v.Error),
+// )
+// }
// return nil
// },
// }))
//
// Example for Logrus (https://github.com/sirupsen/logrus)
-// log := logrus.New()
+// log := logrus.New()
// e.Use(middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{
-// LogURI: true,
-// LogStatus: true,
-// LogValuesFunc: func(c echo.Context, values middleware.RequestLoggerValues) error {
-// log.WithFields(logrus.Fields{
-// "URI": values.URI,
-// "status": values.Status,
-// }).Info("request")
-//
+// LogURI: true,
+// LogStatus: true,
+// LogError: true,
+// HandleError: true, // forwards error to the global error handler, so it can decide appropriate status code
+// LogValuesFunc: func(c echo.Context, v middleware.RequestLoggerValues) error {
+// if v.Error == nil {
+// log.WithFields(logrus.Fields{
+// "URI": v.URI,
+// "status": v.Status,
+// }).Info("request")
+// } else {
+// log.WithFields(logrus.Fields{
+// "URI": v.URI,
+// "status": v.Status,
+// "error": v.Error,
+// }).Error("request error")
+// }
// return nil
// },
// }))
@@ -74,6 +107,13 @@ type RequestLoggerConfig struct {
// Mandatory.
LogValuesFunc func(c echo.Context, v RequestLoggerValues) error
+ // HandleError instructs logger to call global error handler when next middleware/handler returns an error.
+ // This is useful when you have custom error handler that can decide to use different status codes.
+ //
+ // A side-effect of calling global error handler is that now Response has been committed and sent to the client
+ // and middlewares up in chain can not change Response status code or response body.
+ HandleError bool
+
// LogLatency instructs logger to record duration it took to execute rest of the handler chain (next(c) call).
LogLatency bool
// LogProtocol instructs logger to extract request protocol (i.e. `HTTP/1.1` or `HTTP/2`)
@@ -217,6 +257,9 @@ func (config RequestLoggerConfig) ToMiddleware() (echo.MiddlewareFunc, error) {
config.BeforeNextFunc(c)
}
err := next(c)
+ if config.HandleError {
+ c.Error(err)
+ }
v := RequestLoggerValues{
StartTime: start,
@@ -264,7 +307,9 @@ func (config RequestLoggerConfig) ToMiddleware() (echo.MiddlewareFunc, error) {
}
if config.LogStatus {
v.Status = res.Status
- if err != nil {
+ if err != nil && !config.HandleError {
+ // this block should not be executed in case of HandleError=true as the global error handler will decide
+ // the status code. In that case status code could be different from what err contains.
var httpErr *echo.HTTPError
if errors.As(err, &httpErr) {
v.Status = httpErr.Code
@@ -310,6 +355,9 @@ func (config RequestLoggerConfig) ToMiddleware() (echo.MiddlewareFunc, error) {
return errOnLog
}
+ // in case of HandleError=true we are returning the error that we already have handled with global error handler
+ // this is deliberate as this error could be useful for upstream middlewares and default global error handler
+ // will ignore that error when it bubbles up in middleware chain.
return err
}
}, nil
diff --git a/vendor/github.com/labstack/echo/v4/middleware/slash.go b/vendor/github.com/labstack/echo/v4/middleware/slash.go
index 4188675b..a3bf807e 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/slash.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/slash.go
@@ -33,7 +33,7 @@ func AddTrailingSlash() echo.MiddlewareFunc {
return AddTrailingSlashWithConfig(DefaultTrailingSlashConfig)
}
-// AddTrailingSlashWithConfig returns a AddTrailingSlash middleware with config.
+// AddTrailingSlashWithConfig returns an AddTrailingSlash middleware with config.
// See `AddTrailingSlash()`.
func AddTrailingSlashWithConfig(config TrailingSlashConfig) echo.MiddlewareFunc {
// Defaults
diff --git a/vendor/github.com/labstack/echo/v4/router.go b/vendor/github.com/labstack/echo/v4/router.go
index 23c5bd3b..86a986a2 100644
--- a/vendor/github.com/labstack/echo/v4/router.go
+++ b/vendor/github.com/labstack/echo/v4/router.go
@@ -2,6 +2,7 @@ package echo
import (
"bytes"
+ "fmt"
"net/http"
)
@@ -141,6 +142,51 @@ func NewRouter(e *Echo) *Router {
}
}
+// Routes returns the registered routes.
+func (r *Router) Routes() []*Route {
+ routes := make([]*Route, 0, len(r.routes))
+ for _, v := range r.routes {
+ routes = append(routes, v)
+ }
+ return routes
+}
+
+// Reverse generates an URL from route name and provided parameters.
+func (r *Router) Reverse(name string, params ...interface{}) string {
+ uri := new(bytes.Buffer)
+ ln := len(params)
+ n := 0
+ for _, route := range r.routes {
+ if route.Name == name {
+ for i, l := 0, len(route.Path); i < l; i++ {
+ if (route.Path[i] == ':' || route.Path[i] == '*') && n < ln {
+ for ; i < l && route.Path[i] != '/'; i++ {
+ }
+ uri.WriteString(fmt.Sprintf("%v", params[n]))
+ n++
+ }
+ if i < l {
+ uri.WriteByte(route.Path[i])
+ }
+ }
+ break
+ }
+ }
+ return uri.String()
+}
+
+func (r *Router) add(method, path, name string, h HandlerFunc) *Route {
+ r.Add(method, path, h)
+
+ route := &Route{
+ Method: method,
+ Path: path,
+ Name: name,
+ }
+ r.routes[method+path] = route
+ return route
+}
+
// Add registers a new route for method and path with matching handler.
func (r *Router) Add(method, path string, h HandlerFunc) {
// Validate path