diff options
Diffstat (limited to 'vendor/github.com/labstack/echo/v4/middleware')
10 files changed, 134 insertions, 16 deletions
diff --git a/vendor/github.com/labstack/echo/v4/middleware/compress.go b/vendor/github.com/labstack/echo/v4/middleware/compress.go index 19052064..89da16ef 100644 --- a/vendor/github.com/labstack/echo/v4/middleware/compress.go +++ b/vendor/github.com/labstack/echo/v4/middleware/compress.go @@ -111,6 +111,9 @@ func (w *gzipResponseWriter) Write(b []byte) (int, error) { func (w *gzipResponseWriter) Flush() { w.Writer.(*gzip.Writer).Flush() + if flusher, ok := w.ResponseWriter.(http.Flusher); ok { + flusher.Flush() + } } func (w *gzipResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { diff --git a/vendor/github.com/labstack/echo/v4/middleware/cors.go b/vendor/github.com/labstack/echo/v4/middleware/cors.go index c61c7125..5dfe31f9 100644 --- a/vendor/github.com/labstack/echo/v4/middleware/cors.go +++ b/vendor/github.com/labstack/echo/v4/middleware/cors.go @@ -102,6 +102,10 @@ func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc { allowOrigin = o break } + if matchSubdomain(origin, o) { + allowOrigin = origin + break + } } // Simple request diff --git a/vendor/github.com/labstack/echo/v4/middleware/jwt.go b/vendor/github.com/labstack/echo/v4/middleware/jwt.go index 861d3142..d4420246 100644 --- a/vendor/github.com/labstack/echo/v4/middleware/jwt.go +++ b/vendor/github.com/labstack/echo/v4/middleware/jwt.go @@ -26,10 +26,14 @@ type ( // It may be used to define a custom JWT error. ErrorHandler JWTErrorHandler - // Signing key to validate token. - // Required. + // Signing key to validate token. Used as fallback if SigningKeys has length 0. + // Required. This or SigningKeys. SigningKey interface{} + // Map of signing keys to validate token with kid field usage. + // Required. This or SigningKey. + SigningKeys map[string]interface{} + // Signing method, used to check token signing method. // Optional. Default value HS256. SigningMethod string @@ -48,6 +52,7 @@ type ( // Possible values: // - "header:<name>" // - "query:<name>" + // - "param:<name>" // - "cookie:<name>" TokenLookup string @@ -110,7 +115,7 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc { if config.Skipper == nil { config.Skipper = DefaultJWTConfig.Skipper } - if config.SigningKey == nil { + if config.SigningKey == nil && len(config.SigningKeys) == 0 { panic("echo: jwt middleware requires signing key") } if config.SigningMethod == "" { @@ -133,6 +138,15 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc { 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 } @@ -142,6 +156,8 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc { switch parts[0] { case "query": extractor = jwtFromQuery(parts[1]) + case "param": + extractor = jwtFromParam(parts[1]) case "cookie": extractor = jwtFromCookie(parts[1]) } @@ -215,6 +231,17 @@ func jwtFromQuery(param string) jwtExtractor { } } +// jwtFromParam returns a `jwtExtractor` that extracts token from the url param string. +func jwtFromParam(param string) jwtExtractor { + return func(c echo.Context) (string, error) { + token := c.Param(param) + if token == "" { + return "", ErrJWTMissing + } + return token, nil + } +} + // jwtFromCookie returns a `jwtExtractor` that extracts token from the named cookie. func jwtFromCookie(name 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 fe01e23e..94cfd142 100644 --- a/vendor/github.com/labstack/echo/v4/middleware/key_auth.go +++ b/vendor/github.com/labstack/echo/v4/middleware/key_auth.go @@ -99,11 +99,14 @@ func KeyAuthWithConfig(config KeyAuthConfig) echo.MiddlewareFunc { } valid, err := config.Validator(key, c) if err != nil { - return err + return &echo.HTTPError{ + Code: http.StatusUnauthorized, + Message: "invalid key", + Internal: err, + } } else if valid { return next(c) } - return echo.ErrUnauthorized } } diff --git a/vendor/github.com/labstack/echo/v4/middleware/logger.go b/vendor/github.com/labstack/echo/v4/middleware/logger.go index b2e48347..6fd59efb 100644 --- a/vendor/github.com/labstack/echo/v4/middleware/logger.go +++ b/vendor/github.com/labstack/echo/v4/middleware/logger.go @@ -2,6 +2,7 @@ package middleware import ( "bytes" + "encoding/json" "io" "os" "strconv" @@ -20,7 +21,7 @@ type ( // Skipper defines a function to skip middleware. Skipper Skipper - // Tags to constructed the logger format. + // Tags to construct the logger format. // // - time_unix // - time_unix_nano @@ -175,7 +176,10 @@ func LoggerWithConfig(config LoggerConfig) echo.MiddlewareFunc { return buf.WriteString(s) case "error": if err != nil { - return buf.WriteString(err.Error()) + // Error may contain invalid JSON e.g. `"` + b, _ := json.Marshal(err.Error()) + b = b[1 : len(b)-1] + return buf.Write(b) } case "latency": l := stop.Sub(start) diff --git a/vendor/github.com/labstack/echo/v4/middleware/proxy.go b/vendor/github.com/labstack/echo/v4/middleware/proxy.go index 9d67f445..532346d5 100644 --- a/vendor/github.com/labstack/echo/v4/middleware/proxy.go +++ b/vendor/github.com/labstack/echo/v4/middleware/proxy.go @@ -200,7 +200,7 @@ func Proxy(balancer ProxyBalancer) echo.MiddlewareFunc { func ProxyWithConfig(config ProxyConfig) echo.MiddlewareFunc { // Defaults if config.Skipper == nil { - config.Skipper = DefaultLoggerConfig.Skipper + config.Skipper = DefaultProxyConfig.Skipper } if config.Balancer == nil { panic("echo: proxy middleware requires balancer") diff --git a/vendor/github.com/labstack/echo/v4/middleware/redirect.go b/vendor/github.com/labstack/echo/v4/middleware/redirect.go index 30a2e403..813e5b85 100644 --- a/vendor/github.com/labstack/echo/v4/middleware/redirect.go +++ b/vendor/github.com/labstack/echo/v4/middleware/redirect.go @@ -21,7 +21,7 @@ type RedirectConfig struct { // 2) return the appropriate redirect url. type redirectLogic func(scheme, host, uri string) (ok bool, url string) -const www = "www" +const www = "www." // DefaultRedirectConfig is the default Redirect middleware config. var DefaultRedirectConfig = RedirectConfig{ @@ -60,7 +60,7 @@ func HTTPSWWWRedirect() echo.MiddlewareFunc { // See `HTTPSWWWRedirect()`. func HTTPSWWWRedirectWithConfig(config RedirectConfig) echo.MiddlewareFunc { return redirect(config, func(scheme, host, uri string) (ok bool, url string) { - if ok = scheme != "https" && host[:3] != www; ok { + if ok = scheme != "https" && host[:4] != www; ok { url = "https://www." + host + uri } return @@ -80,7 +80,7 @@ func HTTPSNonWWWRedirect() echo.MiddlewareFunc { func HTTPSNonWWWRedirectWithConfig(config RedirectConfig) echo.MiddlewareFunc { return redirect(config, func(scheme, host, uri string) (ok bool, url string) { if ok = scheme != "https"; ok { - if host[:3] == www { + if host[:4] == www { host = host[4:] } url = "https://" + host + uri @@ -101,7 +101,7 @@ func WWWRedirect() echo.MiddlewareFunc { // See `WWWRedirect()`. func WWWRedirectWithConfig(config RedirectConfig) echo.MiddlewareFunc { return redirect(config, func(scheme, host, uri string) (ok bool, url string) { - if ok = host[:3] != www; ok { + if ok = host[:4] != www; ok { url = scheme + "://www." + host + uri } return @@ -120,7 +120,7 @@ func NonWWWRedirect() echo.MiddlewareFunc { // See `NonWWWRedirect()`. func NonWWWRedirectWithConfig(config RedirectConfig) echo.MiddlewareFunc { return redirect(config, func(scheme, host, uri string) (ok bool, url string) { - if ok = host[:3] == www; ok { + if ok = host[:4] == www; ok { url = scheme + "://" + host[4:] + uri } return diff --git a/vendor/github.com/labstack/echo/v4/middleware/secure.go b/vendor/github.com/labstack/echo/v4/middleware/secure.go index 8839c879..77a1487f 100644 --- a/vendor/github.com/labstack/echo/v4/middleware/secure.go +++ b/vendor/github.com/labstack/echo/v4/middleware/secure.go @@ -53,6 +53,19 @@ type ( // trusted web page context. // Optional. Default value "". ContentSecurityPolicy string `yaml:"content_security_policy"` + + // CSPReportOnly would use the `Content-Security-Policy-Report-Only` header instead + // of the `Content-Security-Policy` header. This allows iterative updates of the + // content security policy by only reporting the violations that would + // have occurred instead of blocking the resource. + // Optional. Default value false. + CSPReportOnly bool `yaml:"csp_report_only"` + + // HSTSPreloadEnabled will add the preload tag in the `Strict Transport Security` + // header, which enables the domain to be included in the HSTS preload list + // maintained by Chrome (and used by Firefox and Safari): https://hstspreload.org/ + // Optional. Default value false. + HSTSPreloadEnabled bool `yaml:"hsts_preload_enabled"` } ) @@ -63,6 +76,7 @@ var ( XSSProtection: "1; mode=block", ContentTypeNosniff: "nosniff", XFrameOptions: "SAMEORIGIN", + HSTSPreloadEnabled: false, } ) @@ -105,10 +119,17 @@ func SecureWithConfig(config SecureConfig) echo.MiddlewareFunc { if !config.HSTSExcludeSubdomains { subdomains = "; includeSubdomains" } + if config.HSTSPreloadEnabled { + subdomains = fmt.Sprintf("%s; preload", subdomains) + } res.Header().Set(echo.HeaderStrictTransportSecurity, fmt.Sprintf("max-age=%d%s", config.HSTSMaxAge, subdomains)) } if config.ContentSecurityPolicy != "" { - res.Header().Set(echo.HeaderContentSecurityPolicy, config.ContentSecurityPolicy) + if config.CSPReportOnly { + res.Header().Set(echo.HeaderContentSecurityPolicyReportOnly, config.ContentSecurityPolicy) + } else { + res.Header().Set(echo.HeaderContentSecurityPolicy, config.ContentSecurityPolicy) + } } return next(c) } diff --git a/vendor/github.com/labstack/echo/v4/middleware/slash.go b/vendor/github.com/labstack/echo/v4/middleware/slash.go index 61d6e30b..0492b334 100644 --- a/vendor/github.com/labstack/echo/v4/middleware/slash.go +++ b/vendor/github.com/labstack/echo/v4/middleware/slash.go @@ -1,6 +1,8 @@ package middleware import ( + "strings" + "github.com/labstack/echo/v4" ) @@ -49,7 +51,7 @@ func AddTrailingSlashWithConfig(config TrailingSlashConfig) echo.MiddlewareFunc url := req.URL path := url.Path qs := c.QueryString() - if path != "/" && path[len(path)-1] != '/' { + if !strings.HasSuffix(path, "/") { path += "/" uri := path if qs != "" { @@ -97,7 +99,7 @@ func RemoveTrailingSlashWithConfig(config TrailingSlashConfig) echo.MiddlewareFu path := url.Path qs := c.QueryString() l := len(path) - 1 - if l >= 0 && path != "/" && path[l] == '/' { + if l > 0 && strings.HasSuffix(path, "/") { path = path[:l] uri := path if qs != "" { diff --git a/vendor/github.com/labstack/echo/v4/middleware/util.go b/vendor/github.com/labstack/echo/v4/middleware/util.go new file mode 100644 index 00000000..ab951a0e --- /dev/null +++ b/vendor/github.com/labstack/echo/v4/middleware/util.go @@ -0,0 +1,54 @@ +package middleware + +import ( + "strings" +) + +func matchScheme(domain, pattern string) bool { + didx := strings.Index(domain, ":") + pidx := strings.Index(pattern, ":") + return didx != -1 && pidx != -1 && domain[:didx] == pattern[:pidx] +} + +// matchSubdomain compares authority with wildcard +func matchSubdomain(domain, pattern string) bool { + if !matchScheme(domain, pattern) { + return false + } + didx := strings.Index(domain, "://") + pidx := strings.Index(pattern, "://") + if didx == -1 || pidx == -1 { + return false + } + domAuth := domain[didx+3:] + // to avoid long loop by invalid long domain + if len(domAuth) > 253 { + return false + } + patAuth := pattern[pidx+3:] + + domComp := strings.Split(domAuth, ".") + patComp := strings.Split(patAuth, ".") + for i := len(domComp)/2 - 1; i >= 0; i-- { + opp := len(domComp) - 1 - i + domComp[i], domComp[opp] = domComp[opp], domComp[i] + } + for i := len(patComp)/2 - 1; i >= 0; i-- { + opp := len(patComp) - 1 - i + patComp[i], patComp[opp] = patComp[opp], patComp[i] + } + + for i, v := range domComp { + if len(patComp) <= i { + return false + } + p := patComp[i] + if p == "*" { + return true + } + if p != v { + return false + } + } + return false +} |