4
0
mirror of https://github.com/cwinfo/matterbridge.git synced 2025-07-04 05:27:44 +00:00

Update dependencies / vendor (#1146)

This commit is contained in:
Wim
2020-05-24 00:06:21 +02:00
committed by GitHub
parent ba0bfe70a8
commit 393f9e998b
438 changed files with 35015 additions and 92744 deletions

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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
}

View File

@ -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
)

View File

@ -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=

137
vendor/github.com/labstack/echo/v4/ip.go generated vendored Normal file
View File

@ -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])
}
}

View File

@ -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,

View File

@ -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) == "" {

View File

@ -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
}

View File

@ -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 {
pvalues[len(cn.pnames)-1] = search
break
}
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
// 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
}
}
return // Not found
// 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
}
}
pvalues[len(cn.pnames)-1] = search
break
return // Not found
}
ctx.handler = cn.findHandler(method)