summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/labstack/echo/v4/middleware
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/labstack/echo/v4/middleware')
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/csrf.go2
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/csrf_samesite.go12
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/csrf_samesite_1.12.go12
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/jwt.go108
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/key_auth.go13
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/proxy.go37
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/proxy_1_11.go47
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/proxy_1_11_n.go14
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/static.go80
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/timeout.go11
10 files changed, 188 insertions, 148 deletions
diff --git a/vendor/github.com/labstack/echo/v4/middleware/csrf.go b/vendor/github.com/labstack/echo/v4/middleware/csrf.go
index 60f809a0..7804997d 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/csrf.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/csrf.go
@@ -110,7 +110,7 @@ func CSRFWithConfig(config CSRFConfig) echo.MiddlewareFunc {
if config.CookieMaxAge == 0 {
config.CookieMaxAge = DefaultCSRFConfig.CookieMaxAge
}
- if config.CookieSameSite == SameSiteNoneMode {
+ if config.CookieSameSite == http.SameSiteNoneMode {
config.CookieSecure = true
}
diff --git a/vendor/github.com/labstack/echo/v4/middleware/csrf_samesite.go b/vendor/github.com/labstack/echo/v4/middleware/csrf_samesite.go
deleted file mode 100644
index 9a27dc43..00000000
--- a/vendor/github.com/labstack/echo/v4/middleware/csrf_samesite.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// +build go1.13
-
-package middleware
-
-import (
- "net/http"
-)
-
-const (
- // SameSiteNoneMode required to be redefined for Go 1.12 support (see #1524)
- SameSiteNoneMode http.SameSite = http.SameSiteNoneMode
-)
diff --git a/vendor/github.com/labstack/echo/v4/middleware/csrf_samesite_1.12.go b/vendor/github.com/labstack/echo/v4/middleware/csrf_samesite_1.12.go
deleted file mode 100644
index 22076dd6..00000000
--- a/vendor/github.com/labstack/echo/v4/middleware/csrf_samesite_1.12.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// +build !go1.13
-
-package middleware
-
-import (
- "net/http"
-)
-
-const (
- // SameSiteNoneMode required to be redefined for Go 1.12 support (see #1524)
- SameSiteNoneMode http.SameSite = 4
-)
diff --git a/vendor/github.com/labstack/echo/v4/middleware/jwt.go b/vendor/github.com/labstack/echo/v4/middleware/jwt.go
index da00ea56..cd35b621 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/jwt.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/jwt.go
@@ -29,15 +29,19 @@ type (
// ErrorHandlerWithContext is almost identical to ErrorHandler, but it's passed the current context.
ErrorHandlerWithContext JWTErrorHandlerWithContext
- // Signing key to validate token. Used as fallback if SigningKeys has length 0.
- // Required. This or SigningKeys.
+ // Signing key to validate token.
+ // This is one of the three options to provide a token validation key.
+ // The order of precedence is a user-defined KeyFunc, SigningKeys and SigningKey.
+ // Required if neither user-defined KeyFunc nor SigningKeys is provided.
SigningKey interface{}
// Map of signing keys to validate token with kid field usage.
- // Required. This or SigningKey.
+ // This is one of the three options to provide a token validation key.
+ // The order of precedence is a user-defined KeyFunc, SigningKeys and SigningKey.
+ // Required if neither user-defined KeyFunc nor SigningKey is provided.
SigningKeys map[string]interface{}
- // Signing method, used to check token signing method.
+ // Signing method used to check the token's signing algorithm.
// Optional. Default value HS256.
SigningMethod string
@@ -64,7 +68,16 @@ type (
// Optional. Default value "Bearer".
AuthScheme string
- keyFunc jwt.Keyfunc
+ // KeyFunc defines a user-defined function that supplies the public key for a token validation.
+ // The function shall take care of verifying the signing algorithm and selecting the proper key.
+ // A user-defined KeyFunc can be useful if tokens are issued by an external party.
+ //
+ // When a user-defined KeyFunc is provided, SigningKey, SigningKeys, and SigningMethod are ignored.
+ // This is one of the three options to provide a token validation key.
+ // The order of precedence is a user-defined KeyFunc, SigningKeys and SigningKey.
+ // Required if neither SigningKeys nor SigningKey is provided.
+ // Default to an internal implementation verifying the signing algorithm and selecting the proper key.
+ KeyFunc jwt.Keyfunc
}
// JWTSuccessHandler defines a function which is executed for a valid token.
@@ -99,6 +112,7 @@ var (
TokenLookup: "header:" + echo.HeaderAuthorization,
AuthScheme: "Bearer",
Claims: jwt.MapClaims{},
+ KeyFunc: nil,
}
)
@@ -123,7 +137,7 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
if config.Skipper == nil {
config.Skipper = DefaultJWTConfig.Skipper
}
- if config.SigningKey == nil && len(config.SigningKeys) == 0 {
+ if config.SigningKey == nil && len(config.SigningKeys) == 0 && config.KeyFunc == nil {
panic("echo: jwt middleware requires signing key")
}
if config.SigningMethod == "" {
@@ -141,35 +155,29 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
if config.AuthScheme == "" {
config.AuthScheme = DefaultJWTConfig.AuthScheme
}
- config.keyFunc = func(t *jwt.Token) (interface{}, error) {
- // Check the signing method
- if t.Method.Alg() != config.SigningMethod {
- return nil, fmt.Errorf("unexpected jwt signing method=%v", t.Header["alg"])
- }
- if len(config.SigningKeys) > 0 {
- if kid, ok := t.Header["kid"].(string); ok {
- if key, ok := config.SigningKeys[kid]; ok {
- return key, nil
- }
- }
- return nil, fmt.Errorf("unexpected jwt key id=%v", t.Header["kid"])
- }
-
- return config.SigningKey, nil
+ if config.KeyFunc == nil {
+ config.KeyFunc = config.defaultKeyFunc
}
// Initialize
- parts := strings.Split(config.TokenLookup, ":")
- extractor := jwtFromHeader(parts[1], config.AuthScheme)
- switch parts[0] {
- case "query":
- extractor = jwtFromQuery(parts[1])
- case "param":
- extractor = jwtFromParam(parts[1])
- case "cookie":
- extractor = jwtFromCookie(parts[1])
- case "form":
- extractor = jwtFromForm(parts[1])
+ // Split sources
+ sources := strings.Split(config.TokenLookup, ",")
+ var extractors []jwtExtractor
+ for _, source := range sources {
+ parts := strings.Split(source, ":")
+
+ switch parts[0] {
+ case "query":
+ extractors = append(extractors, jwtFromQuery(parts[1]))
+ case "param":
+ extractors = append(extractors, jwtFromParam(parts[1]))
+ case "cookie":
+ extractors = append(extractors, jwtFromCookie(parts[1]))
+ case "form":
+ extractors = append(extractors, jwtFromForm(parts[1]))
+ case "header":
+ extractors = append(extractors, jwtFromHeader(parts[1], config.AuthScheme))
+ }
}
return func(next echo.HandlerFunc) echo.HandlerFunc {
@@ -181,8 +189,17 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
if config.BeforeFunc != nil {
config.BeforeFunc(c)
}
-
- auth, err := extractor(c)
+ var auth string
+ var err error
+ for _, extractor := range extractors {
+ // Extract token from extractor, if it's not fail break the loop and
+ // set auth
+ auth, err = extractor(c)
+ if err == nil {
+ break
+ }
+ }
+ // If none of extractor has a token, handle error
if err != nil {
if config.ErrorHandler != nil {
return config.ErrorHandler(err)
@@ -193,14 +210,15 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
}
return err
}
+
token := new(jwt.Token)
// Issue #647, #656
if _, ok := config.Claims.(jwt.MapClaims); ok {
- token, err = jwt.Parse(auth, config.keyFunc)
+ token, err = jwt.Parse(auth, config.KeyFunc)
} else {
t := reflect.ValueOf(config.Claims).Type().Elem()
claims := reflect.New(t).Interface().(jwt.Claims)
- token, err = jwt.ParseWithClaims(auth, claims, config.keyFunc)
+ token, err = jwt.ParseWithClaims(auth, claims, config.KeyFunc)
}
if err == nil && token.Valid {
// Store user information from token into context.
@@ -225,6 +243,24 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
}
}
+// defaultKeyFunc returns a signing key of the given token.
+func (config *JWTConfig) defaultKeyFunc(t *jwt.Token) (interface{}, error) {
+ // Check the signing method
+ if t.Method.Alg() != config.SigningMethod {
+ return nil, fmt.Errorf("unexpected jwt signing method=%v", t.Header["alg"])
+ }
+ if len(config.SigningKeys) > 0 {
+ if kid, ok := t.Header["kid"].(string); ok {
+ if key, ok := config.SigningKeys[kid]; ok {
+ return key, nil
+ }
+ }
+ return nil, fmt.Errorf("unexpected jwt key id=%v", t.Header["kid"])
+ }
+
+ return config.SigningKey, nil
+}
+
// jwtFromHeader returns a `jwtExtractor` that extracts token from the request header.
func jwtFromHeader(header string, authScheme string) jwtExtractor {
return func(c echo.Context) (string, error) {
diff --git a/vendor/github.com/labstack/echo/v4/middleware/key_auth.go b/vendor/github.com/labstack/echo/v4/middleware/key_auth.go
index 94cfd142..fd169aa2 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/key_auth.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/key_auth.go
@@ -30,12 +30,19 @@ type (
// Validator is a function to validate key.
// Required.
Validator KeyAuthValidator
+
+ // ErrorHandler defines a function which is executed for an invalid key.
+ // It may be used to define a custom error.
+ ErrorHandler KeyAuthErrorHandler
}
// KeyAuthValidator defines a function to validate KeyAuth credentials.
KeyAuthValidator func(string, echo.Context) (bool, error)
keyExtractor func(echo.Context) (string, error)
+
+ // KeyAuthErrorHandler defines a function which is executed for an invalid key.
+ KeyAuthErrorHandler func(error, echo.Context) error
)
var (
@@ -95,10 +102,16 @@ func KeyAuthWithConfig(config KeyAuthConfig) echo.MiddlewareFunc {
// Extract and verify key
key, err := extractor(c)
if err != nil {
+ if config.ErrorHandler != nil {
+ return config.ErrorHandler(err, c)
+ }
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
}
valid, err := config.Validator(key, c)
if err != nil {
+ if config.ErrorHandler != nil {
+ return config.ErrorHandler(err, c)
+ }
return &echo.HTTPError{
Code: http.StatusUnauthorized,
Message: "invalid key",
diff --git a/vendor/github.com/labstack/echo/v4/middleware/proxy.go b/vendor/github.com/labstack/echo/v4/middleware/proxy.go
index 6f01f3a7..6cfd6731 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/proxy.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/proxy.go
@@ -1,13 +1,16 @@
package middleware
import (
+ "context"
"fmt"
"io"
"math/rand"
"net"
"net/http"
+ "net/http/httputil"
"net/url"
"regexp"
+ "strings"
"sync"
"sync/atomic"
"time"
@@ -264,3 +267,37 @@ func ProxyWithConfig(config ProxyConfig) echo.MiddlewareFunc {
}
}
}
+
+// StatusCodeContextCanceled is a custom HTTP status code for situations
+// where a client unexpectedly closed the connection to the server.
+// As there is no standard error code for "client closed connection", but
+// various well-known HTTP clients and server implement this HTTP code we use
+// 499 too instead of the more problematic 5xx, which does not allow to detect this situation
+const StatusCodeContextCanceled = 499
+
+func proxyHTTP(tgt *ProxyTarget, c echo.Context, config ProxyConfig) http.Handler {
+ proxy := httputil.NewSingleHostReverseProxy(tgt.URL)
+ proxy.ErrorHandler = func(resp http.ResponseWriter, req *http.Request, err error) {
+ desc := tgt.URL.String()
+ if tgt.Name != "" {
+ desc = fmt.Sprintf("%s(%s)", tgt.Name, tgt.URL.String())
+ }
+ // If the client canceled the request (usually by closing the connection), we can report a
+ // client error (4xx) instead of a server error (5xx) to correctly identify the situation.
+ // The Go standard library (at of late 2020) wraps the exported, standard
+ // context.Canceled error with unexported garbage value requiring a substring check, see
+ // https://github.com/golang/go/blob/6965b01ea248cabb70c3749fd218b36089a21efb/src/net/net.go#L416-L430
+ if err == context.Canceled || strings.Contains(err.Error(), "operation was canceled") {
+ httpError := echo.NewHTTPError(StatusCodeContextCanceled, fmt.Sprintf("client closed connection: %v", err))
+ httpError.Internal = err
+ c.Set("_error", httpError)
+ } else {
+ httpError := echo.NewHTTPError(http.StatusBadGateway, fmt.Sprintf("remote %s unreachable, could not forward: %v", desc, err))
+ httpError.Internal = err
+ c.Set("_error", httpError)
+ }
+ }
+ proxy.Transport = config.Transport
+ proxy.ModifyResponse = config.ModifyResponse
+ return proxy
+}
diff --git a/vendor/github.com/labstack/echo/v4/middleware/proxy_1_11.go b/vendor/github.com/labstack/echo/v4/middleware/proxy_1_11.go
deleted file mode 100644
index 17d142d8..00000000
--- a/vendor/github.com/labstack/echo/v4/middleware/proxy_1_11.go
+++ /dev/null
@@ -1,47 +0,0 @@
-// +build go1.11
-
-package middleware
-
-import (
- "context"
- "fmt"
- "net/http"
- "net/http/httputil"
- "strings"
-
- "github.com/labstack/echo/v4"
-)
-
-// StatusCodeContextCanceled is a custom HTTP status code for situations
-// where a client unexpectedly closed the connection to the server.
-// As there is no standard error code for "client closed connection", but
-// various well-known HTTP clients and server implement this HTTP code we use
-// 499 too instead of the more problematic 5xx, which does not allow to detect this situation
-const StatusCodeContextCanceled = 499
-
-func proxyHTTP(tgt *ProxyTarget, c echo.Context, config ProxyConfig) http.Handler {
- proxy := httputil.NewSingleHostReverseProxy(tgt.URL)
- proxy.ErrorHandler = func(resp http.ResponseWriter, req *http.Request, err error) {
- desc := tgt.URL.String()
- if tgt.Name != "" {
- desc = fmt.Sprintf("%s(%s)", tgt.Name, tgt.URL.String())
- }
- // If the client canceled the request (usually by closing the connection), we can report a
- // client error (4xx) instead of a server error (5xx) to correctly identify the situation.
- // The Go standard library (at of late 2020) wraps the exported, standard
- // context.Canceled error with unexported garbage value requiring a substring check, see
- // https://github.com/golang/go/blob/6965b01ea248cabb70c3749fd218b36089a21efb/src/net/net.go#L416-L430
- if err == context.Canceled || strings.Contains(err.Error(), "operation was canceled") {
- httpError := echo.NewHTTPError(StatusCodeContextCanceled, fmt.Sprintf("client closed connection: %v", err))
- httpError.Internal = err
- c.Set("_error", httpError)
- } else {
- httpError := echo.NewHTTPError(http.StatusBadGateway, fmt.Sprintf("remote %s unreachable, could not forward: %v", desc, err))
- httpError.Internal = err
- c.Set("_error", httpError)
- }
- }
- proxy.Transport = config.Transport
- proxy.ModifyResponse = config.ModifyResponse
- return proxy
-}
diff --git a/vendor/github.com/labstack/echo/v4/middleware/proxy_1_11_n.go b/vendor/github.com/labstack/echo/v4/middleware/proxy_1_11_n.go
deleted file mode 100644
index 9a78929f..00000000
--- a/vendor/github.com/labstack/echo/v4/middleware/proxy_1_11_n.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// +build !go1.11
-
-package middleware
-
-import (
- "net/http"
- "net/http/httputil"
-
- "github.com/labstack/echo/v4"
-)
-
-func proxyHTTP(t *ProxyTarget, c echo.Context, config ProxyConfig) http.Handler {
- return httputil.NewSingleHostReverseProxy(t.URL)
-}
diff --git a/vendor/github.com/labstack/echo/v4/middleware/static.go b/vendor/github.com/labstack/echo/v4/middleware/static.go
index ae79cb5f..0106f7ce 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/static.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/static.go
@@ -42,6 +42,10 @@ type (
// the filesystem path is not doubled
// Optional. Default value false.
IgnoreBase bool `yaml:"ignoreBase"`
+
+ // Filesystem provides access to the static content.
+ // Optional. Defaults to http.Dir(config.Root)
+ Filesystem http.FileSystem `yaml:"-"`
}
)
@@ -146,6 +150,10 @@ func StaticWithConfig(config StaticConfig) echo.MiddlewareFunc {
if config.Index == "" {
config.Index = DefaultStaticConfig.Index
}
+ if config.Filesystem == nil {
+ config.Filesystem = http.Dir(config.Root)
+ config.Root = "."
+ }
// Index template
t, err := template.New("index").Parse(html)
@@ -178,49 +186,73 @@ func StaticWithConfig(config StaticConfig) echo.MiddlewareFunc {
}
}
- fi, err := os.Stat(name)
+ file, err := openFile(config.Filesystem, name)
if err != nil {
- if os.IsNotExist(err) {
- if err = next(c); err != nil {
- if he, ok := err.(*echo.HTTPError); ok {
- if config.HTML5 && he.Code == http.StatusNotFound {
- return c.File(filepath.Join(config.Root, config.Index))
- }
- }
- return
- }
+ if !os.IsNotExist(err) {
+ return err
+ }
+
+ if err = next(c); err == nil {
+ return err
+ }
+
+ he, ok := err.(*echo.HTTPError)
+ if !(ok && config.HTML5 && he.Code == http.StatusNotFound) {
+ return err
+ }
+
+ file, err = openFile(config.Filesystem, filepath.Join(config.Root, config.Index))
+ if err != nil {
+ return err
}
- return
}
- if fi.IsDir() {
- index := filepath.Join(name, config.Index)
- fi, err = os.Stat(index)
+ defer file.Close()
+
+ info, err := file.Stat()
+ if err != nil {
+ return err
+ }
+ if info.IsDir() {
+ index, err := openFile(config.Filesystem, filepath.Join(name, config.Index))
if err != nil {
if config.Browse {
- return listDir(t, name, c.Response())
+ return listDir(t, name, file, c.Response())
}
+
if os.IsNotExist(err) {
return next(c)
}
- return
}
- return c.File(index)
+ defer index.Close()
+
+ info, err = index.Stat()
+ if err != nil {
+ return err
+ }
+
+ return serveFile(c, index, info)
}
- return c.File(name)
+ return serveFile(c, file, info)
}
}
}
-func listDir(t *template.Template, name string, res *echo.Response) (err error) {
- file, err := os.Open(name)
- if err != nil {
- return
- }
- files, err := file.Readdir(-1)
+func openFile(fs http.FileSystem, name string) (http.File, error) {
+ pathWithSlashes := filepath.ToSlash(name)
+ return fs.Open(pathWithSlashes)
+}
+
+func serveFile(c echo.Context, file http.File, info os.FileInfo) error {
+ http.ServeContent(c.Response(), c.Request(), info.Name(), info.ModTime(), file)
+ return nil
+}
+
+func listDir(t *template.Template, name string, dir http.File, res *echo.Response) (err error) {
+ files, err := dir.Readdir(-1)
if err != nil {
return
}
diff --git a/vendor/github.com/labstack/echo/v4/middleware/timeout.go b/vendor/github.com/labstack/echo/v4/middleware/timeout.go
index 5d23ff45..fb8ae421 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/timeout.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/timeout.go
@@ -1,5 +1,3 @@
-// +build go1.13
-
package middleware
import (
@@ -94,6 +92,15 @@ func (t echoHandlerFuncWrapper) ServeHTTP(rw http.ResponseWriter, r *http.Reques
originalWriter := t.ctx.Response().Writer
t.ctx.Response().Writer = rw
+ // in case of panic we restore original writer and call panic again
+ // so it could be handled with global middleware Recover()
+ defer func() {
+ if err := recover(); err != nil {
+ t.ctx.Response().Writer = originalWriter
+ panic(err)
+ }
+ }()
+
err := t.handler(t.ctx)
if ctxErr := r.Context().Err(); ctxErr == context.DeadlineExceeded {
if err != nil && t.errHandler != nil {