summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/labstack/echo/v4
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/labstack/echo/v4')
-rw-r--r--vendor/github.com/labstack/echo/v4/.travis.yml1
-rw-r--r--vendor/github.com/labstack/echo/v4/README.md27
-rw-r--r--vendor/github.com/labstack/echo/v4/bind.go21
-rw-r--r--vendor/github.com/labstack/echo/v4/context.go12
-rw-r--r--vendor/github.com/labstack/echo/v4/echo.go151
-rw-r--r--vendor/github.com/labstack/echo/v4/go.mod16
-rw-r--r--vendor/github.com/labstack/echo/v4/go.sum50
-rw-r--r--vendor/github.com/labstack/echo/v4/group.go25
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/compress.go3
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/cors.go4
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/jwt.go33
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/key_auth.go7
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/logger.go8
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/proxy.go2
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/redirect.go10
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/secure.go23
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/slash.go6
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/util.go54
-rw-r--r--vendor/github.com/labstack/echo/v4/response.go5
-rw-r--r--vendor/github.com/labstack/echo/v4/router.go12
20 files changed, 359 insertions, 111 deletions
diff --git a/vendor/github.com/labstack/echo/v4/.travis.yml b/vendor/github.com/labstack/echo/v4/.travis.yml
index 30346d7f..3897356d 100644
--- a/vendor/github.com/labstack/echo/v4/.travis.yml
+++ b/vendor/github.com/labstack/echo/v4/.travis.yml
@@ -1,6 +1,7 @@
language: go
go:
- 1.11.x
+ - 1.12.x
- tip
env:
- GO111MODULE=on
diff --git a/vendor/github.com/labstack/echo/v4/README.md b/vendor/github.com/labstack/echo/v4/README.md
index 1db5e356..0da03122 100644
--- a/vendor/github.com/labstack/echo/v4/README.md
+++ b/vendor/github.com/labstack/echo/v4/README.md
@@ -56,30 +56,29 @@ Lower is better!
package main
import (
- "net/http"
-
- "github.com/labstack/echo/v4"
- "github.com/labstack/echo/v4/middleware"
+ "net/http"
+ "github.com/labstack/echo/v4"
+ "github.com/labstack/echo/v4/middleware"
)
func main() {
- // Echo instance
- e := echo.New()
+ // 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"))
}
// Handler
func hello(c echo.Context) error {
- return c.String(http.StatusOK, "Hello, World!")
+ return c.String(http.StatusOK, "Hello, World!")
}
```
diff --git a/vendor/github.com/labstack/echo/v4/bind.go b/vendor/github.com/labstack/echo/v4/bind.go
index cb65ed2d..07d8034c 100644
--- a/vendor/github.com/labstack/echo/v4/bind.go
+++ b/vendor/github.com/labstack/echo/v4/bind.go
@@ -1,6 +1,7 @@
package echo
import (
+ "encoding"
"encoding/json"
"encoding/xml"
"errors"
@@ -21,6 +22,8 @@ type (
DefaultBinder struct{}
// BindUnmarshaler is the interface used to wrap the UnmarshalParam method.
+ // Types that don't implement this, but do implement encoding.TextUnmarshaler
+ // will use that interface instead.
BindUnmarshaler interface {
// UnmarshalParam decodes and assigns a value from an form or query param.
UnmarshalParam(param string) error
@@ -211,12 +214,30 @@ func bindUnmarshaler(field reflect.Value) (BindUnmarshaler, bool) {
return nil, false
}
+// textUnmarshaler attempts to unmarshal a reflect.Value into a TextUnmarshaler
+func textUnmarshaler(field reflect.Value) (encoding.TextUnmarshaler, bool) {
+ ptr := reflect.New(field.Type())
+ if ptr.CanInterface() {
+ iface := ptr.Interface()
+ if unmarshaler, ok := iface.(encoding.TextUnmarshaler); ok {
+ return unmarshaler, ok
+ }
+ }
+ return nil, false
+}
+
func unmarshalFieldNonPtr(value string, field reflect.Value) (bool, error) {
if unmarshaler, ok := bindUnmarshaler(field); ok {
err := unmarshaler.UnmarshalParam(value)
field.Set(reflect.ValueOf(unmarshaler).Elem())
return true, err
}
+ if unmarshaler, ok := textUnmarshaler(field); ok {
+ err := unmarshaler.UnmarshalText([]byte(value))
+ field.Set(reflect.ValueOf(unmarshaler).Elem())
+ return true, err
+ }
+
return false, nil
}
diff --git a/vendor/github.com/labstack/echo/v4/context.go b/vendor/github.com/labstack/echo/v4/context.go
index d4722700..065f5815 100644
--- a/vendor/github.com/labstack/echo/v4/context.go
+++ b/vendor/github.com/labstack/echo/v4/context.go
@@ -13,6 +13,7 @@ import (
"os"
"path/filepath"
"strings"
+ "sync"
)
type (
@@ -198,6 +199,7 @@ type (
handler HandlerFunc
store Map
echo *Echo
+ lock sync.RWMutex
}
)
@@ -232,7 +234,7 @@ func (c *context) IsTLS() bool {
func (c *context) IsWebSocket() bool {
upgrade := c.request.Header.Get(HeaderUpgrade)
- return upgrade == "websocket" || upgrade == "Websocket"
+ return strings.ToLower(upgrade) == "websocket"
}
func (c *context) Scheme() string {
@@ -360,10 +362,15 @@ func (c *context) Cookies() []*http.Cookie {
}
func (c *context) Get(key string) interface{} {
+ c.lock.RLock()
+ defer c.lock.RUnlock()
return c.store[key]
}
func (c *context) Set(key string, val interface{}) {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
if c.store == nil {
c.store = make(Map)
}
@@ -430,7 +437,7 @@ func (c *context) json(code int, i interface{}, indent string) error {
enc.SetIndent("", indent)
}
c.writeContentType(MIMEApplicationJSONCharsetUTF8)
- c.response.WriteHeader(code)
+ c.response.Status = code
return enc.Encode(i)
}
@@ -597,4 +604,3 @@ func (c *context) Reset(r *http.Request, w http.ResponseWriter) {
// NOTE: Don't reset because it has to have length c.echo.maxParam at all times
// c.pvalues = nil
}
-
diff --git a/vendor/github.com/labstack/echo/v4/echo.go b/vendor/github.com/labstack/echo/v4/echo.go
index 0fe6880f..56b2cf8c 100644
--- a/vendor/github.com/labstack/echo/v4/echo.go
+++ b/vendor/github.com/labstack/echo/v4/echo.go
@@ -43,6 +43,7 @@ import (
"errors"
"fmt"
"io"
+ "io/ioutil"
stdLog "log"
"net"
"net/http"
@@ -56,18 +57,21 @@ import (
"github.com/labstack/gommon/color"
"github.com/labstack/gommon/log"
+ "golang.org/x/crypto/acme"
"golang.org/x/crypto/acme/autocert"
)
type (
// Echo is the top-level framework instance.
Echo struct {
+ common
StdLogger *stdLog.Logger
colorer *color.Color
premiddleware []MiddlewareFunc
middleware []MiddlewareFunc
maxParam *int
router *Router
+ routers map[string]*Router
notFoundHandler HandlerFunc
pool sync.Pool
Server *http.Server
@@ -122,10 +126,8 @@ type (
// Map defines a generic map of type `map[string]interface{}`.
Map map[string]interface{}
- // i is the interface for Echo and Group.
- i interface {
- GET(string, HandlerFunc, ...MiddlewareFunc) *Route
- }
+ // Common struct for Echo & Group.
+ common struct{}
)
// HTTP methods
@@ -168,6 +170,8 @@ const (
charsetUTF8 = "charset=UTF-8"
// PROPFIND Method can be used on collection and property resources.
PROPFIND = "PROPFIND"
+ // REPORT Method can be used to get information about a resource, see rfc 3253
+ REPORT = "REPORT"
)
// Headers
@@ -211,17 +215,18 @@ const (
HeaderAccessControlMaxAge = "Access-Control-Max-Age"
// Security
- HeaderStrictTransportSecurity = "Strict-Transport-Security"
- HeaderXContentTypeOptions = "X-Content-Type-Options"
- HeaderXXSSProtection = "X-XSS-Protection"
- HeaderXFrameOptions = "X-Frame-Options"
- HeaderContentSecurityPolicy = "Content-Security-Policy"
- HeaderXCSRFToken = "X-CSRF-Token"
+ HeaderStrictTransportSecurity = "Strict-Transport-Security"
+ HeaderXContentTypeOptions = "X-Content-Type-Options"
+ HeaderXXSSProtection = "X-XSS-Protection"
+ HeaderXFrameOptions = "X-Frame-Options"
+ HeaderContentSecurityPolicy = "Content-Security-Policy"
+ HeaderContentSecurityPolicyReportOnly = "Content-Security-Policy-Report-Only"
+ HeaderXCSRFToken = "X-CSRF-Token"
)
const (
// Version of Echo
- Version = "4.0.0"
+ Version = "4.1.5"
website = "https://echo.labstack.com"
// http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo
banner = `
@@ -248,6 +253,7 @@ var (
PROPFIND,
http.MethodPut,
http.MethodTrace,
+ REPORT,
}
)
@@ -269,6 +275,7 @@ var (
ErrRendererNotRegistered = errors.New("renderer not registered")
ErrInvalidRedirectCode = errors.New("invalid redirect status code")
ErrCookieNotFound = errors.New("cookie not found")
+ ErrInvalidCertOrKeyType = errors.New("invalid cert or key type, must be string or []byte")
)
// Error handlers
@@ -304,6 +311,7 @@ func New() (e *Echo) {
return e.NewContext(nil, nil)
}
e.router = NewRouter(e)
+ e.routers = map[string]*Router{}
return
}
@@ -319,11 +327,16 @@ func (e *Echo) NewContext(r *http.Request, w http.ResponseWriter) Context {
}
}
-// Router returns router.
+// Router returns the default router.
func (e *Echo) Router() *Router {
return e.router
}
+// Routers returns the map of host => router.
+func (e *Echo) Routers() map[string]*Router {
+ return e.routers
+}
+
// DefaultHTTPErrorHandler is the default HTTP error handler. It sends a JSON response
// with status code.
func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) {
@@ -450,10 +463,10 @@ func (e *Echo) Static(prefix, root string) *Route {
if root == "" {
root = "." // For security we want to restrict to CWD.
}
- return static(e, prefix, root)
+ return e.static(prefix, root, e.GET)
}
-func static(i i, prefix, root string) *Route {
+func (common) static(prefix, root string, get func(string, HandlerFunc, ...MiddlewareFunc) *Route) *Route {
h := func(c Context) error {
p, err := url.PathUnescape(c.Param("*"))
if err != nil {
@@ -462,26 +475,28 @@ func static(i i, prefix, root string) *Route {
name := filepath.Join(root, path.Clean("/"+p)) // "/"+ for security
return c.File(name)
}
- i.GET(prefix, h)
if prefix == "/" {
- return i.GET(prefix+"*", h)
+ return get(prefix+"*", h)
}
+ return get(prefix+"/*", h)
+}
- return i.GET(prefix+"/*", h)
+func (common) file(path, file string, get func(string, HandlerFunc, ...MiddlewareFunc) *Route,
+ m ...MiddlewareFunc) *Route {
+ return get(path, func(c Context) error {
+ return c.File(file)
+ }, m...)
}
// File registers a new route with path to serve a static file with optional route-level middleware.
func (e *Echo) File(path, file string, m ...MiddlewareFunc) *Route {
- return e.GET(path, func(c Context) error {
- return c.File(file)
- }, m...)
+ return e.file(path, file, e.GET, m...)
}
-// Add registers a new route for an HTTP method and path with matching handler
-// in the router with optional route-level middleware.
-func (e *Echo) Add(method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route {
+func (e *Echo) add(host, method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route {
name := handlerName(handler)
- e.router.Add(method, path, func(c Context) error {
+ router := e.findRouter(host)
+ router.Add(method, path, func(c Context) error {
h := handler
// Chain middleware
for i := len(middleware) - 1; i >= 0; i-- {
@@ -498,6 +513,20 @@ func (e *Echo) Add(method, path string, handler HandlerFunc, middleware ...Middl
return r
}
+// Add registers a new route for an HTTP method and path with matching handler
+// in the router with optional route-level middleware.
+func (e *Echo) Add(method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route {
+ return e.add("", method, path, handler, middleware...)
+}
+
+// Host creates a new router group for the provided host and optional host-level middleware.
+func (e *Echo) Host(name string, m ...MiddlewareFunc) (g *Group) {
+ e.routers[name] = NewRouter(e)
+ g = &Group{host: name, echo: e}
+ g.Use(m...)
+ return
+}
+
// Group creates a new router group with prefix and optional group-level middleware.
func (e *Echo) Group(prefix string, m ...MiddlewareFunc) (g *Group) {
g = &Group{prefix: prefix, echo: e}
@@ -570,23 +599,17 @@ func (e *Echo) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h := NotFoundHandler
if e.premiddleware == nil {
- e.router.Find(r.Method, getPath(r), c)
+ e.findRouter(r.Host).Find(r.Method, getPath(r), c)
h = c.Handler()
- for i := len(e.middleware) - 1; i >= 0; i-- {
- h = e.middleware[i](h)
- }
+ h = applyMiddleware(h, e.middleware...)
} else {
h = func(c Context) error {
- e.router.Find(r.Method, getPath(r), c)
+ e.findRouter(r.Host).Find(r.Method, getPath(r), c)
h := c.Handler()
- for i := len(e.middleware) - 1; i >= 0; i-- {
- h = e.middleware[i](h)
- }
+ h = applyMiddleware(h, e.middleware...)
return h(c)
}
- for i := len(e.premiddleware) - 1; i >= 0; i-- {
- h = e.premiddleware[i](h)
- }
+ h = applyMiddleware(h, e.premiddleware...)
}
// Execute chain
@@ -605,25 +628,46 @@ func (e *Echo) Start(address string) error {
}
// StartTLS starts an HTTPS server.
-func (e *Echo) StartTLS(address string, certFile, keyFile string) (err error) {
- if certFile == "" || keyFile == "" {
- return errors.New("invalid tls configuration")
+// If `certFile` or `keyFile` is `string` the values are treated as file paths.
+// If `certFile` or `keyFile` is `[]byte` the values are treated as the certificate or key as-is.
+func (e *Echo) StartTLS(address string, certFile, keyFile interface{}) (err error) {
+ var cert []byte
+ if cert, err = filepathOrContent(certFile); err != nil {
+ return
+ }
+
+ var key []byte
+ if key, err = filepathOrContent(keyFile); err != nil {
+ return
}
+
s := e.TLSServer
s.TLSConfig = new(tls.Config)
s.TLSConfig.Certificates = make([]tls.Certificate, 1)
- s.TLSConfig.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
- if err != nil {
+ if s.TLSConfig.Certificates[0], err = tls.X509KeyPair(cert, key); err != nil {
return
}
+
return e.startTLS(address)
}
+func filepathOrContent(fileOrContent interface{}) (content []byte, err error) {
+ switch v := fileOrContent.(type) {
+ case string:
+ return ioutil.ReadFile(v)
+ case []byte:
+ return v, nil
+ default:
+ return nil, ErrInvalidCertOrKeyType
+ }
+}
+
// StartAutoTLS starts an HTTPS server using certificates automatically installed from https://letsencrypt.org.
func (e *Echo) StartAutoTLS(address string) error {
s := e.TLSServer
s.TLSConfig = new(tls.Config)
s.TLSConfig.GetCertificate = e.AutoTLSManager.GetCertificate
+ s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, acme.ALPNProto)
return e.startTLS(address)
}
@@ -742,6 +786,15 @@ func getPath(r *http.Request) string {
return path
}
+func (e *Echo) findRouter(host string) *Router {
+ if len(e.routers) > 0 {
+ if r, ok := e.routers[host]; ok {
+ return r
+ }
+ }
+ return e.router
+}
+
func handlerName(h HandlerFunc) string {
t := reflect.ValueOf(h).Type()
if t.Kind() == reflect.Func {
@@ -764,13 +817,14 @@ type tcpKeepAliveListener struct {
}
func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
- tc, err := ln.AcceptTCP()
- if err != nil {
+ if c, err = ln.AcceptTCP(); err != nil {
+ return
+ } else if err = c.(*net.TCPConn).SetKeepAlive(true); err != nil {
+ return
+ } else if err = c.(*net.TCPConn).SetKeepAlivePeriod(3 * time.Minute); err != nil {
return
}
- tc.SetKeepAlive(true)
- tc.SetKeepAlivePeriod(3 * time.Minute)
- return tc, nil
+ return
}
func newListener(address string) (*tcpKeepAliveListener, error) {
@@ -780,3 +834,10 @@ func newListener(address string) (*tcpKeepAliveListener, error) {
}
return &tcpKeepAliveListener{l.(*net.TCPListener)}, nil
}
+
+func applyMiddleware(h HandlerFunc, middleware ...MiddlewareFunc) HandlerFunc {
+ for i := len(middleware) - 1; i >= 0; i-- {
+ h = middleware[i](h)
+ }
+ return h
+}
diff --git a/vendor/github.com/labstack/echo/v4/go.mod b/vendor/github.com/labstack/echo/v4/go.mod
index 2853cba5..d76b9843 100644
--- a/vendor/github.com/labstack/echo/v4/go.mod
+++ b/vendor/github.com/labstack/echo/v4/go.mod
@@ -1,13 +1,15 @@
module github.com/labstack/echo/v4
+go 1.12
+
require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible
- github.com/labstack/gommon v0.2.8
- github.com/mattn/go-colorable v0.0.9 // indirect
- github.com/mattn/go-isatty v0.0.4 // indirect
+ github.com/labstack/gommon v0.2.9
github.com/stretchr/testify v1.3.0
- github.com/valyala/bytebufferpool v1.0.0 // indirect
- github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4
- golang.org/x/crypto v0.0.0-20190130090550-b01c7a725664
- golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc // indirect
+ github.com/valyala/fasttemplate v1.0.1
+ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5
+ golang.org/x/net v0.0.0-20190607181551-461777fb6f67 // indirect
+ golang.org/x/sys v0.0.0-20190609082536-301114b31cce // indirect
+ golang.org/x/text v0.3.2 // indirect
+ golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3 // indirect
)
diff --git a/vendor/github.com/labstack/echo/v4/go.sum b/vendor/github.com/labstack/echo/v4/go.sum
index e6981931..48c5b8f1 100644
--- a/vendor/github.com/labstack/echo/v4/go.sum
+++ b/vendor/github.com/labstack/echo/v4/go.sum
@@ -1,23 +1,53 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/labstack/gommon v0.2.8 h1:JvRqmeZcfrHC5u6uVleB4NxxNbzx6gpbJiQknDbKQu0=
github.com/labstack/gommon v0.2.8/go.mod h1:/tj9csK2iPSBvn+3NLM9e52usepMtrd5ilFYA+wQNJ4=
-github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
-github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
-github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
-github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/labstack/gommon v0.2.9 h1:heVeuAYtevIQVYkGj6A41dtfT91LrvFG220lavpWhrU=
+github.com/labstack/gommon v0.2.9/go.mod h1:E8ZTmW9vw5az5/ZyHWCp0Lw4OH2ecsaBP1C/NKavGG4=
+github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
+github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
+github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
+github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
+github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
+github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
+github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
-github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4 h1:gKMu1Bf6QINDnvyZuTaACm9ofY+PRh+5vFz4oxBZeF8=
-github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4/go.mod h1:50wTf68f99/Zt14pr046Tgt3Lp2vLyFZKzbFXTOabXw=
-golang.org/x/crypto v0.0.0-20190130090550-b01c7a725664 h1:YbZJ76lQ1BqNhVe7dKTSB67wDrc2VPRR75IyGyyPDX8=
-golang.org/x/crypto v0.0.0-20190130090550-b01c7a725664/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc h1:WiYx1rIFmx8c0mXAFtv5D/mHyKe1+jmuP7PViuwqwuQ=
-golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
+github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/LemDnOc1GiZL5FCVlORJ5zo=
+golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
+golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190607181551-461777fb6f67 h1:rJJxsykSlULwd2P2+pg/rtnwN2FrWp4IuCxOSyS0V00=
+golang.org/x/net v0.0.0-20190607181551-461777fb6f67/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2 h1:T5DasATyLQfmbTpfEXx/IOL9vfjzW6up+ZDkmHvIf2s=
+golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190609082536-301114b31cce/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
diff --git a/vendor/github.com/labstack/echo/v4/group.go b/vendor/github.com/labstack/echo/v4/group.go
index 3e3732b6..5d958253 100644
--- a/vendor/github.com/labstack/echo/v4/group.go
+++ b/vendor/github.com/labstack/echo/v4/group.go
@@ -2,7 +2,6 @@ package echo
import (
"net/http"
- "path"
)
type (
@@ -10,6 +9,8 @@ type (
// routes that share a common middleware or functionality that should be separate
// from the parent echo instance while still inheriting from it.
Group struct {
+ common
+ host string
prefix string
middleware []MiddlewareFunc
echo *Echo
@@ -19,13 +20,13 @@ type (
// Use implements `Echo#Use()` for sub-routes within the Group.
func (g *Group) Use(middleware ...MiddlewareFunc) {
g.middleware = append(g.middleware, middleware...)
+ if len(g.middleware) == 0 {
+ return
+ }
// Allow all requests to reach the group as they might get dropped if router
// doesn't find a match, making none of the group middleware process.
- for _, p := range []string{"", "/*"} {
- g.echo.Any(path.Clean(g.prefix+p), func(c Context) error {
- return NotFoundHandler(c)
- }, g.middleware...)
- }
+ g.Any("", NotFoundHandler)
+ g.Any("/*", NotFoundHandler)
}
// CONNECT implements `Echo#CONNECT()` for sub-routes within the Group.
@@ -92,21 +93,23 @@ func (g *Group) Match(methods []string, path string, handler HandlerFunc, middle
}
// Group creates a new sub-group with prefix and optional sub-group-level middleware.
-func (g *Group) Group(prefix string, middleware ...MiddlewareFunc) *Group {
+func (g *Group) Group(prefix string, middleware ...MiddlewareFunc) (sg *Group) {
m := make([]MiddlewareFunc, 0, len(g.middleware)+len(middleware))
m = append(m, g.middleware...)
m = append(m, middleware...)
- return g.echo.Group(g.prefix+prefix, m...)
+ sg = g.echo.Group(g.prefix+prefix, m...)
+ sg.host = g.host
+ return
}
// Static implements `Echo#Static()` for sub-routes within the Group.
func (g *Group) Static(prefix, root string) {
- static(g, prefix, root)
+ g.static(prefix, root, g.GET)
}
// File implements `Echo#File()` for sub-routes within the Group.
func (g *Group) File(path, file string) {
- g.echo.File(g.prefix+path, file)
+ g.file(g.prefix+path, file, g.GET)
}
// Add implements `Echo#Add()` for sub-routes within the Group.
@@ -117,5 +120,5 @@ func (g *Group) Add(method, path string, handler HandlerFunc, middleware ...Midd
m := make([]MiddlewareFunc, 0, len(g.middleware)+len(middleware))
m = append(m, g.middleware...)
m = append(m, middleware...)
- return g.echo.Add(method, g.prefix+path, handler, m...)
+ return g.echo.add(g.host, method, g.prefix+path, handler, m...)
}
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
+}
diff --git a/vendor/github.com/labstack/echo/v4/response.go b/vendor/github.com/labstack/echo/v4/response.go
index eb2d988d..ca7405c5 100644
--- a/vendor/github.com/labstack/echo/v4/response.go
+++ b/vendor/github.com/labstack/echo/v4/response.go
@@ -67,7 +67,10 @@ func (r *Response) WriteHeader(code int) {
// Write writes the data to the connection as part of an HTTP reply.
func (r *Response) Write(b []byte) (n int, err error) {
if !r.Committed {
- r.WriteHeader(http.StatusOK)
+ if r.Status == 0 {
+ r.Status = http.StatusOK
+ }
+ r.WriteHeader(r.Status)
}
n, err = r.Writer.Write(b)
r.Size += int64(n)
diff --git a/vendor/github.com/labstack/echo/v4/router.go b/vendor/github.com/labstack/echo/v4/router.go
index 73f0b68b..8d3a0180 100644
--- a/vendor/github.com/labstack/echo/v4/router.go
+++ b/vendor/github.com/labstack/echo/v4/router.go
@@ -33,6 +33,7 @@ type (
propfind HandlerFunc
put HandlerFunc
trace HandlerFunc
+ report HandlerFunc
}
)
@@ -57,7 +58,7 @@ func NewRouter(e *Echo) *Router {
func (r *Router) Add(method, path string, h HandlerFunc) {
// Validate path
if path == "" {
- panic("echo: path cannot be empty")
+ path = "/"
}
if path[0] != '/' {
path = "/" + path
@@ -79,14 +80,13 @@ func (r *Router) Add(method, path string, h HandlerFunc) {
if i == l {
r.insert(method, path[:i], h, pkind, ppath, pnames)
- return
+ } else {
+ r.insert(method, path[:i], nil, pkind, "", nil)
}
- r.insert(method, path[:i], nil, pkind, "", nil)
} else if path[i] == '*' {
r.insert(method, path[:i], nil, skind, "", nil)
pnames = append(pnames, "*")
r.insert(method, path[:i+1], h, akind, ppath, pnames)
- return
}
}
@@ -248,6 +248,8 @@ func (n *node) addHandler(method string, h HandlerFunc) {
n.methodHandler.put = h
case http.MethodTrace:
n.methodHandler.trace = h
+ case REPORT:
+ n.methodHandler.report = h
}
}
@@ -273,6 +275,8 @@ func (n *node) findHandler(method string) HandlerFunc {
return n.methodHandler.put
case http.MethodTrace:
return n.methodHandler.trace
+ case REPORT:
+ return n.methodHandler.report
default:
return nil
}