summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/labstack/echo
diff options
context:
space:
mode:
authorWim <wim@42.be>2020-05-24 00:06:21 +0200
committerGitHub <noreply@github.com>2020-05-24 00:06:21 +0200
commit393f9e998b1b40aa59d3fb8794c3a73da38c3fb7 (patch)
tree2bc9b6e6abdbdc6d811b155997597bdae62bc7db /vendor/github.com/labstack/echo
parentba0bfe70a8f07164e1341f4b094841acdad5c3a2 (diff)
downloadmatterbridge-msglm-393f9e998b1b40aa59d3fb8794c3a73da38c3fb7.tar.gz
matterbridge-msglm-393f9e998b1b40aa59d3fb8794c3a73da38c3fb7.tar.bz2
matterbridge-msglm-393f9e998b1b40aa59d3fb8794c3a73da38c3fb7.zip
Update dependencies / vendor (#1146)
Diffstat (limited to 'vendor/github.com/labstack/echo')
-rw-r--r--vendor/github.com/labstack/echo/v4/README.md7
-rw-r--r--vendor/github.com/labstack/echo/v4/bind.go42
-rw-r--r--vendor/github.com/labstack/echo/v4/context.go11
-rw-r--r--vendor/github.com/labstack/echo/v4/echo.go41
-rw-r--r--vendor/github.com/labstack/echo/v4/go.mod11
-rw-r--r--vendor/github.com/labstack/echo/v4/go.sum37
-rw-r--r--vendor/github.com/labstack/echo/v4/ip.go137
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/jwt.go8
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/proxy.go4
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/rewrite.go3
-rw-r--r--vendor/github.com/labstack/echo/v4/router.go88
11 files changed, 277 insertions, 112 deletions
diff --git a/vendor/github.com/labstack/echo/v4/README.md b/vendor/github.com/labstack/echo/v4/README.md
index 0da03122..c57d478f 100644
--- a/vendor/github.com/labstack/echo/v4/README.md
+++ b/vendor/github.com/labstack/echo/v4/README.md
@@ -50,6 +50,13 @@ Lower is better!
## [Guide](https://echo.labstack.com/guide)
+### Installation
+
+```go
+// go get github.com/labstack/echo/{version}
+go get github.com/labstack/echo/v4
+```
+
### Example
```go
diff --git a/vendor/github.com/labstack/echo/v4/bind.go b/vendor/github.com/labstack/echo/v4/bind.go
index c8c88bb2..f8914743 100644
--- a/vendor/github.com/labstack/echo/v4/bind.go
+++ b/vendor/github.com/labstack/echo/v4/bind.go
@@ -115,7 +115,7 @@ func (b *DefaultBinder) bindData(ptr interface{}, data map[string][]string, tag
if inputFieldName == "" {
inputFieldName = typeField.Name
// If tag is nil, we inspect if the field is a struct.
- if _, ok := bindUnmarshaler(structField); !ok && structFieldKind == reflect.Struct {
+ if _, ok := structField.Addr().Interface().(BindUnmarshaler); !ok && structFieldKind == reflect.Struct {
if err := b.bindData(structField.Addr().Interface(), data, tag); err != nil {
return err
}
@@ -129,9 +129,8 @@ func (b *DefaultBinder) bindData(ptr interface{}, data map[string][]string, tag
// url params are bound case sensitive which is inconsistent. To
// fix this we must check all of the map values in a
// case-insensitive search.
- inputFieldName = strings.ToLower(inputFieldName)
for k, v := range data {
- if strings.ToLower(k) == inputFieldName {
+ if strings.EqualFold(k, inputFieldName) {
inputValue = v
exists = true
break
@@ -221,40 +220,13 @@ func unmarshalField(valueKind reflect.Kind, val string, field reflect.Value) (bo
}
}
-// bindUnmarshaler attempts to unmarshal a reflect.Value into a BindUnmarshaler
-func bindUnmarshaler(field reflect.Value) (BindUnmarshaler, bool) {
- ptr := reflect.New(field.Type())
- if ptr.CanInterface() {
- iface := ptr.Interface()
- if unmarshaler, ok := iface.(BindUnmarshaler); ok {
- return unmarshaler, ok
- }
- }
- 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
+ fieldIValue := field.Addr().Interface()
+ if unmarshaler, ok := fieldIValue.(BindUnmarshaler); ok {
+ return true, unmarshaler.UnmarshalParam(value)
}
- if unmarshaler, ok := textUnmarshaler(field); ok {
- err := unmarshaler.UnmarshalText([]byte(value))
- field.Set(reflect.ValueOf(unmarshaler).Elem())
- return true, err
+ if unmarshaler, ok := fieldIValue.(encoding.TextUnmarshaler); ok {
+ return true, unmarshaler.UnmarshalText([]byte(value))
}
return false, nil
diff --git a/vendor/github.com/labstack/echo/v4/context.go b/vendor/github.com/labstack/echo/v4/context.go
index 27da5ffe..99ef03bc 100644
--- a/vendor/github.com/labstack/echo/v4/context.go
+++ b/vendor/github.com/labstack/echo/v4/context.go
@@ -43,6 +43,7 @@ type (
// RealIP returns the client's network address based on `X-Forwarded-For`
// or `X-Real-IP` request header.
+ // The behavior can be configured using `Echo#IPExtractor`.
RealIP() string
// Path returns the registered path for the handler.
@@ -270,6 +271,10 @@ func (c *context) Scheme() string {
}
func (c *context) RealIP() string {
+ if c.echo != nil && c.echo.IPExtractor != nil {
+ return c.echo.IPExtractor(c.request)
+ }
+ // Fall back to legacy behavior
if ip := c.request.Header.Get(HeaderXForwardedFor); ip != "" {
return strings.Split(ip, ", ")[0]
}
@@ -305,6 +310,7 @@ func (c *context) ParamNames() []string {
func (c *context) SetParamNames(names ...string) {
c.pnames = names
+ *c.echo.maxParam = len(names)
}
func (c *context) ParamValues() []string {
@@ -352,8 +358,11 @@ func (c *context) FormParams() (url.Values, error) {
func (c *context) FormFile(name string) (*multipart.FileHeader, error) {
f, fh, err := c.request.FormFile(name)
+ if err != nil {
+ return nil, err
+ }
defer f.Close()
- return fh, err
+ return fh, nil
}
func (c *context) MultipartForm() (*multipart.Form, error) {
diff --git a/vendor/github.com/labstack/echo/v4/echo.go b/vendor/github.com/labstack/echo/v4/echo.go
index a6ac0fa8..511eb43f 100644
--- a/vendor/github.com/labstack/echo/v4/echo.go
+++ b/vendor/github.com/labstack/echo/v4/echo.go
@@ -59,6 +59,8 @@ import (
"github.com/labstack/gommon/log"
"golang.org/x/crypto/acme"
"golang.org/x/crypto/acme/autocert"
+ "golang.org/x/net/http2"
+ "golang.org/x/net/http2/h2c"
)
type (
@@ -88,6 +90,7 @@ type (
Validator Validator
Renderer Renderer
Logger Logger
+ IPExtractor IPExtractor
}
// Route contains a handler and information for matching against requests.
@@ -227,7 +230,7 @@ const (
const (
// Version of Echo
- Version = "4.1.13"
+ Version = "4.1.16"
website = "https://echo.labstack.com"
// http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo
banner = `
@@ -723,6 +726,34 @@ func (e *Echo) StartServer(s *http.Server) (err error) {
return s.Serve(e.TLSListener)
}
+// StartH2CServer starts a custom http/2 server with h2c (HTTP/2 Cleartext).
+func (e *Echo) StartH2CServer(address string, h2s *http2.Server) (err error) {
+ // Setup
+ s := e.Server
+ s.Addr = address
+ e.colorer.SetOutput(e.Logger.Output())
+ s.ErrorLog = e.StdLogger
+ s.Handler = h2c.NewHandler(e, h2s)
+ if e.Debug {
+ e.Logger.SetLevel(log.DEBUG)
+ }
+
+ if !e.HideBanner {
+ e.colorer.Printf(banner, e.colorer.Red("v"+Version), e.colorer.Blue(website))
+ }
+
+ if e.Listener == nil {
+ e.Listener, err = newListener(s.Addr)
+ if err != nil {
+ return err
+ }
+ }
+ if !e.HidePort {
+ e.colorer.Printf("⇨ http server started on %s\n", e.colorer.Green(e.Listener.Addr()))
+ }
+ return s.Serve(e.Listener)
+}
+
// Close immediately stops the server.
// It internally calls `http.Server#Close()`.
func (e *Echo) Close() error {
@@ -752,6 +783,9 @@ func NewHTTPError(code int, message ...interface{}) *HTTPError {
// Error makes it compatible with `error` interface.
func (he *HTTPError) Error() string {
+ if he.Internal == nil {
+ return fmt.Sprintf("code=%d, message=%v", he.Code, he.Message)
+ }
return fmt.Sprintf("code=%d, message=%v, internal=%v", he.Code, he.Message, he.Internal)
}
@@ -826,9 +860,10 @@ func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
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
}
+ // Ignore error from setting the KeepAlivePeriod as some systems, such as
+ // OpenBSD, do not support setting TCP_USER_TIMEOUT on IPPROTO_TCP
+ _ = c.(*net.TCPConn).SetKeepAlivePeriod(3 * time.Minute)
return
}
diff --git a/vendor/github.com/labstack/echo/v4/go.mod b/vendor/github.com/labstack/echo/v4/go.mod
index c5db2ae1..b3ac0800 100644
--- a/vendor/github.com/labstack/echo/v4/go.mod
+++ b/vendor/github.com/labstack/echo/v4/go.mod
@@ -1,17 +1,14 @@
module github.com/labstack/echo/v4
-go 1.12
+go 1.14
require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible
- github.com/labstack/echo v3.3.10+incompatible // indirect
github.com/labstack/gommon v0.3.0
- github.com/mattn/go-colorable v0.1.4 // indirect
- github.com/mattn/go-isatty v0.0.11 // indirect
+ github.com/mattn/go-colorable v0.1.6 // indirect
github.com/stretchr/testify v1.4.0
github.com/valyala/fasttemplate v1.1.0
- golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876
- golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 // indirect
- golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8 // indirect
+ golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d
+ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b
golang.org/x/text v0.3.2 // indirect
)
diff --git a/vendor/github.com/labstack/echo/v4/go.sum b/vendor/github.com/labstack/echo/v4/go.sum
index 57c79877..8e7e54ce 100644
--- a/vendor/github.com/labstack/echo/v4/go.sum
+++ b/vendor/github.com/labstack/echo/v4/go.sum
@@ -1,22 +1,19 @@
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/dgrijalva/jwt-go v1.0.2 h1:KPldsxuKGsS2FPWsNeg9ZO18aCrGKujPoWXn2yo+KQM=
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/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg=
-github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
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-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
-github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
+github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
+github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
-github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=
-github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
-github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
-github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
+github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
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=
@@ -29,29 +26,19 @@ github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPU
github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy1Ocw4=
github.com/valyala/fasttemplate v1.1.0/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-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
-golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876 h1:sKJQZMuxjOAR/Uo2LBfU90onWEf1dF4C+0hPJCc9Mpc=
-golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
+golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d h1:1ZiEyfaQIg3Qh0EoqpwAakHVhecoE5wlSg5GjnafJGw=
+golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20191021144547-ec77196f6094 h1:5O4U9trLjNpuhpynaDsqwCk+Tw6seqJz1EbqbnzHrc8=
-golang.org/x/net v0.0.0-20191021144547-ec77196f6094/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
-golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
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-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191024172528-b4ff53e7a1cb h1:ZxSglHghKPYD8WDeRUzRJrUJtDF0PxsTUSxyqr9/5BI=
-golang.org/x/sys v0.0.0-20191024172528-b4ff53e7a1cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8 h1:JA8d3MPx/IToSyXZG/RhwYEtfrKO1Fxrqe8KrkiLXKM=
-golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/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=
diff --git a/vendor/github.com/labstack/echo/v4/ip.go b/vendor/github.com/labstack/echo/v4/ip.go
new file mode 100644
index 00000000..39cb421f
--- /dev/null
+++ b/vendor/github.com/labstack/echo/v4/ip.go
@@ -0,0 +1,137 @@
+package echo
+
+import (
+ "net"
+ "net/http"
+ "strings"
+)
+
+type ipChecker struct {
+ trustLoopback bool
+ trustLinkLocal bool
+ trustPrivateNet bool
+ trustExtraRanges []*net.IPNet
+}
+
+// TrustOption is config for which IP address to trust
+type TrustOption func(*ipChecker)
+
+// TrustLoopback configures if you trust loopback address (default: true).
+func TrustLoopback(v bool) TrustOption {
+ return func(c *ipChecker) {
+ c.trustLoopback = v
+ }
+}
+
+// TrustLinkLocal configures if you trust link-local address (default: true).
+func TrustLinkLocal(v bool) TrustOption {
+ return func(c *ipChecker) {
+ c.trustLinkLocal = v
+ }
+}
+
+// TrustPrivateNet configures if you trust private network address (default: true).
+func TrustPrivateNet(v bool) TrustOption {
+ return func(c *ipChecker) {
+ c.trustPrivateNet = v
+ }
+}
+
+// TrustIPRange add trustable IP ranges using CIDR notation.
+func TrustIPRange(ipRange *net.IPNet) TrustOption {
+ return func(c *ipChecker) {
+ c.trustExtraRanges = append(c.trustExtraRanges, ipRange)
+ }
+}
+
+func newIPChecker(configs []TrustOption) *ipChecker {
+ checker := &ipChecker{trustLoopback: true, trustLinkLocal: true, trustPrivateNet: true}
+ for _, configure := range configs {
+ configure(checker)
+ }
+ return checker
+}
+
+func isPrivateIPRange(ip net.IP) bool {
+ if ip4 := ip.To4(); ip4 != nil {
+ return ip4[0] == 10 ||
+ ip4[0] == 172 && ip4[1]&0xf0 == 16 ||
+ ip4[0] == 192 && ip4[1] == 168
+ }
+ return len(ip) == net.IPv6len && ip[0]&0xfe == 0xfc
+}
+
+func (c *ipChecker) trust(ip net.IP) bool {
+ if c.trustLoopback && ip.IsLoopback() {
+ return true
+ }
+ if c.trustLinkLocal && ip.IsLinkLocalUnicast() {
+ return true
+ }
+ if c.trustPrivateNet && isPrivateIPRange(ip) {
+ return true
+ }
+ for _, trustedRange := range c.trustExtraRanges {
+ if trustedRange.Contains(ip) {
+ return true
+ }
+ }
+ return false
+}
+
+// IPExtractor is a function to extract IP addr from http.Request.
+// Set appropriate one to Echo#IPExtractor.
+// See https://echo.labstack.com/guide/ip-address for more details.
+type IPExtractor func(*http.Request) string
+
+// ExtractIPDirect extracts IP address using actual IP address.
+// Use this if your server faces to internet directory (i.e.: uses no proxy).
+func ExtractIPDirect() IPExtractor {
+ return func(req *http.Request) string {
+ ra, _, _ := net.SplitHostPort(req.RemoteAddr)
+ return ra
+ }
+}
+
+// ExtractIPFromRealIPHeader extracts IP address using x-real-ip header.
+// Use this if you put proxy which uses this header.
+func ExtractIPFromRealIPHeader(options ...TrustOption) IPExtractor {
+ checker := newIPChecker(options)
+ return func(req *http.Request) string {
+ directIP := ExtractIPDirect()(req)
+ realIP := req.Header.Get(HeaderXRealIP)
+ if realIP != "" {
+ if ip := net.ParseIP(directIP); ip != nil && checker.trust(ip) {
+ return realIP
+ }
+ }
+ return directIP
+ }
+}
+
+// ExtractIPFromXFFHeader extracts IP address using x-forwarded-for header.
+// Use this if you put proxy which uses this header.
+// This returns nearest untrustable IP. If all IPs are trustable, returns furthest one (i.e.: XFF[0]).
+func ExtractIPFromXFFHeader(options ...TrustOption) IPExtractor {
+ checker := newIPChecker(options)
+ return func(req *http.Request) string {
+ directIP := ExtractIPDirect()(req)
+ xffs := req.Header[HeaderXForwardedFor]
+ if len(xffs) == 0 {
+ return directIP
+ }
+ ips := append(strings.Split(strings.Join(xffs, ","), ","), directIP)
+ for i := len(ips) - 1; i >= 0; i-- {
+ ip := net.ParseIP(strings.TrimSpace(ips[i]))
+ if ip == nil {
+ // Unable to parse IP; cannot trust entire records
+ return directIP
+ }
+ if !checker.trust(ip) {
+ return ip.String()
+ }
+ }
+ // All of the IPs are trusted; return first element because it is furthest from server (best effort strategy).
+ return strings.TrimSpace(ips[0])
+ }
+}
diff --git a/vendor/github.com/labstack/echo/v4/middleware/jwt.go b/vendor/github.com/labstack/echo/v4/middleware/jwt.go
index 55a98632..3c7c4868 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/jwt.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/jwt.go
@@ -25,7 +25,7 @@ type (
// ErrorHandler defines a function which is executed for an invalid token.
// It may be used to define a custom JWT error.
ErrorHandler JWTErrorHandler
-
+
// ErrorHandlerWithContext is almost identical to ErrorHandler, but it's passed the current context.
ErrorHandlerWithContext JWTErrorHandlerWithContext
@@ -74,7 +74,7 @@ type (
// JWTErrorHandlerWithContext is almost identical to JWTErrorHandler, but it's passed the current context.
JWTErrorHandlerWithContext func(error, echo.Context) error
-
+
jwtExtractor func(echo.Context) (string, error)
)
@@ -183,7 +183,7 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
if config.ErrorHandler != nil {
return config.ErrorHandler(err)
}
-
+
if config.ErrorHandlerWithContext != nil {
return config.ErrorHandlerWithContext(err, c)
}
@@ -210,7 +210,7 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
return config.ErrorHandler(err)
}
if config.ErrorHandlerWithContext != nil {
- return config.ErrorHandlerWithContext(err, c)
+ return config.ErrorHandlerWithContext(err, c)
}
return &echo.HTTPError{
Code: http.StatusUnauthorized,
diff --git a/vendor/github.com/labstack/echo/v4/middleware/proxy.go b/vendor/github.com/labstack/echo/v4/middleware/proxy.go
index ef5602bd..1da370db 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/proxy.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/proxy.go
@@ -231,7 +231,9 @@ func ProxyWithConfig(config ProxyConfig) echo.MiddlewareFunc {
}
// Fix header
- if req.Header.Get(echo.HeaderXRealIP) == "" {
+ // Basically it's not good practice to unconditionally pass incoming x-real-ip header to upstream.
+ // However, for backward compatibility, legacy behavior is preserved unless you configure Echo#IPExtractor.
+ if req.Header.Get(echo.HeaderXRealIP) == "" || c.Echo().IPExtractor != nil {
req.Header.Set(echo.HeaderXRealIP, c.RealIP())
}
if req.Header.Get(echo.HeaderXForwardedProto) == "" {
diff --git a/vendor/github.com/labstack/echo/v4/middleware/rewrite.go b/vendor/github.com/labstack/echo/v4/middleware/rewrite.go
index a64e10bb..d1387af0 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/rewrite.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/rewrite.go
@@ -57,7 +57,8 @@ func RewriteWithConfig(config RewriteConfig) echo.MiddlewareFunc {
// Initialize
for k, v := range config.Rules {
- k = strings.Replace(k, "*", "(.*)", -1)
+ k = regexp.QuoteMeta(k)
+ k = strings.Replace(k, `\*`, "(.*)", -1)
k = k + "$"
config.rulesRegex[regexp.MustCompile(k)] = v
}
diff --git a/vendor/github.com/labstack/echo/v4/router.go b/vendor/github.com/labstack/echo/v4/router.go
index 08145973..15a3398f 100644
--- a/vendor/github.com/labstack/echo/v4/router.go
+++ b/vendor/github.com/labstack/echo/v4/router.go
@@ -347,7 +347,14 @@ func (r *Router) Find(method, path string, c Context) {
if l == pl {
// Continue search
search = search[l:]
- } else {
+ // Finish routing if no remaining search and we are on an leaf node
+ if search == "" && (nn == nil || cn.parent == nil || cn.ppath != "") {
+ break
+ }
+ }
+
+ // Attempt to go back up the tree on no matching prefix or no remaining search
+ if l != pl || search == "" {
if nn == nil { // Issue #1348
return // Not found
}
@@ -360,10 +367,6 @@ func (r *Router) Find(method, path string, c Context) {
}
}
- if search == "" {
- break
- }
-
// Static node
if child = cn.findChild(search[0], skind); child != nil {
// Save next
@@ -376,8 +379,8 @@ func (r *Router) Find(method, path string, c Context) {
continue
}
- // Param node
Param:
+ // Param node
if child = cn.findChildByKind(pkind); child != nil {
// Issue #378
if len(pvalues) == n {
@@ -401,43 +404,58 @@ func (r *Router) Find(method, path string, c Context) {
continue
}
- // Any node
Any:
- if cn = cn.findChildByKind(akind); cn == nil {
- if nn != nil {
- // No next node to go down in routing (issue #954)
- // Find nearest "any" route going up the routing tree
- search = ns
- np := nn.parent
- // Consider param route one level up only
- // if no slash is remaining in search string
- if cn = nn.findChildByKind(pkind); cn != nil && strings.IndexByte(ns, '/') == -1 {
+ // Any node
+ if cn = cn.findChildByKind(akind); cn != nil {
+ // If any node is found, use remaining path for pvalues
+ pvalues[len(cn.pnames)-1] = search
+ break
+ }
+
+ // No node found, continue at stored next node
+ // or find nearest "any" route
+ if nn != nil {
+ // No next node to go down in routing (issue #954)
+ // Find nearest "any" route going up the routing tree
+ search = ns
+ np := nn.parent
+ // Consider param route one level up only
+ if cn = nn.findChildByKind(pkind); cn != nil {
+ pos := strings.IndexByte(ns, '/')
+ if pos == -1 {
+ // If no slash is remaining in search string set param value
pvalues[len(cn.pnames)-1] = search
break
+ } else if pos > 0 {
+ // Otherwise continue route processing with restored next node
+ cn = nn
+ nn = nil
+ ns = ""
+ goto Param
}
- for {
- np = nn.parent
- if cn = nn.findChildByKind(akind); cn != nil {
- break
- }
- if np == nil {
- break // no further parent nodes in tree, abort
- }
- var str strings.Builder
- str.WriteString(nn.prefix)
- str.WriteString(search)
- search = str.String()
- nn = np
- }
- if cn != nil { // use the found "any" route and update path
- pvalues[len(cn.pnames)-1] = search
+ }
+ // No param route found, try to resolve nearest any route
+ for {
+ np = nn.parent
+ if cn = nn.findChildByKind(akind); cn != nil {
break
}
+ if np == nil {
+ break // no further parent nodes in tree, abort
+ }
+ var str strings.Builder
+ str.WriteString(nn.prefix)
+ str.WriteString(search)
+ search = str.String()
+ nn = np
+ }
+ if cn != nil { // use the found "any" route and update path
+ pvalues[len(cn.pnames)-1] = search
+ break
}
- return // Not found
}
- pvalues[len(cn.pnames)-1] = search
- break
+ return // Not found
+
}
ctx.handler = cn.findHandler(method)