From 3a183cb218c6812964a70d2e75884ad7071d9c0c Mon Sep 17 00:00:00 2001 From: Wim Date: Tue, 6 Jun 2017 00:01:05 +0200 Subject: Update vendor --- .../labstack/echo/middleware/basic_auth.go | 28 +++- .../labstack/echo/middleware/compress.go | 4 +- vendor/github.com/labstack/echo/middleware/jwt.go | 2 +- .../labstack/echo/middleware/key_auth.go | 7 +- .../github.com/labstack/echo/middleware/logger.go | 15 +- .../labstack/echo/middleware/middleware.go | 2 +- .../github.com/labstack/echo/middleware/proxy.go | 160 +++++++++++++++++++++ .../labstack/echo/middleware/request_id.go | 64 +++++++++ .../github.com/labstack/echo/middleware/static.go | 39 +++-- 9 files changed, 301 insertions(+), 20 deletions(-) create mode 100644 vendor/github.com/labstack/echo/middleware/proxy.go create mode 100644 vendor/github.com/labstack/echo/middleware/request_id.go (limited to 'vendor/github.com/labstack/echo/middleware') diff --git a/vendor/github.com/labstack/echo/middleware/basic_auth.go b/vendor/github.com/labstack/echo/middleware/basic_auth.go index e98a87e3..c1f34c8f 100644 --- a/vendor/github.com/labstack/echo/middleware/basic_auth.go +++ b/vendor/github.com/labstack/echo/middleware/basic_auth.go @@ -2,6 +2,7 @@ package middleware import ( "encoding/base64" + "strconv" "github.com/labstack/echo" ) @@ -15,20 +16,26 @@ type ( // Validator is a function to validate BasicAuth credentials. // Required. Validator BasicAuthValidator + + // Realm is a string to define realm attribute of BasicAuth. + // Default value "Restricted". + Realm string } // BasicAuthValidator defines a function to validate BasicAuth credentials. - BasicAuthValidator func(string, string, echo.Context) bool + BasicAuthValidator func(string, string, echo.Context) (bool, error) ) const ( - basic = "Basic" + basic = "Basic" + defaultRealm = "Restricted" ) var ( // DefaultBasicAuthConfig is the default BasicAuth middleware config. DefaultBasicAuthConfig = BasicAuthConfig{ Skipper: DefaultSkipper, + Realm: defaultRealm, } ) @@ -52,6 +59,9 @@ func BasicAuthWithConfig(config BasicAuthConfig) echo.MiddlewareFunc { if config.Skipper == nil { config.Skipper = DefaultBasicAuthConfig.Skipper } + if config.Realm == "" { + config.Realm = defaultRealm + } return func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { @@ -71,15 +81,25 @@ func BasicAuthWithConfig(config BasicAuthConfig) echo.MiddlewareFunc { for i := 0; i < len(cred); i++ { if cred[i] == ':' { // Verify credentials - if config.Validator(cred[:i], cred[i+1:], c) { + valid, err := config.Validator(cred[:i], cred[i+1:], c) + if err != nil { + return err + } else if valid { return next(c) } } } } + realm := "" + if config.Realm == defaultRealm { + realm = defaultRealm + } else { + realm = strconv.Quote(config.Realm) + } + // Need to return `401` for browsers to pop-up login box. - c.Response().Header().Set(echo.HeaderWWWAuthenticate, basic+" realm=Restricted") + c.Response().Header().Set(echo.HeaderWWWAuthenticate, basic+" realm="+realm) return echo.ErrUnauthorized } } diff --git a/vendor/github.com/labstack/echo/middleware/compress.go b/vendor/github.com/labstack/echo/middleware/compress.go index eee67b37..cffadbd1 100644 --- a/vendor/github.com/labstack/echo/middleware/compress.go +++ b/vendor/github.com/labstack/echo/middleware/compress.go @@ -108,8 +108,8 @@ func (w *gzipResponseWriter) Write(b []byte) (int, error) { return w.Writer.Write(b) } -func (w *gzipResponseWriter) Flush() error { - return w.Writer.(*gzip.Writer).Flush() +func (w *gzipResponseWriter) Flush() { + w.Writer.(*gzip.Writer).Flush() } func (w *gzipResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { diff --git a/vendor/github.com/labstack/echo/middleware/jwt.go b/vendor/github.com/labstack/echo/middleware/jwt.go index b2658739..5d2072e7 100644 --- a/vendor/github.com/labstack/echo/middleware/jwt.go +++ b/vendor/github.com/labstack/echo/middleware/jwt.go @@ -91,7 +91,7 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc { config.Skipper = DefaultJWTConfig.Skipper } if config.SigningKey == nil { - panic("jwt middleware requires signing key") + panic("echo: jwt middleware requires signing key") } if config.SigningMethod == "" { config.SigningMethod = DefaultJWTConfig.SigningMethod diff --git a/vendor/github.com/labstack/echo/middleware/key_auth.go b/vendor/github.com/labstack/echo/middleware/key_auth.go index 4d4cb940..5ef87e3d 100644 --- a/vendor/github.com/labstack/echo/middleware/key_auth.go +++ b/vendor/github.com/labstack/echo/middleware/key_auth.go @@ -32,7 +32,7 @@ type ( } // KeyAuthValidator defines a function to validate KeyAuth credentials. - KeyAuthValidator func(string, echo.Context) bool + KeyAuthValidator func(string, echo.Context) (bool, error) keyExtractor func(echo.Context) (string, error) ) @@ -94,7 +94,10 @@ func KeyAuthWithConfig(config KeyAuthConfig) echo.MiddlewareFunc { if err != nil { return echo.NewHTTPError(http.StatusBadRequest, err.Error()) } - if config.Validator(key, c) { + valid, err := config.Validator(key, c) + if err != nil { + return err + } else if valid { return next(c) } diff --git a/vendor/github.com/labstack/echo/middleware/logger.go b/vendor/github.com/labstack/echo/middleware/logger.go index e26b5496..b9c54468 100644 --- a/vendor/github.com/labstack/echo/middleware/logger.go +++ b/vendor/github.com/labstack/echo/middleware/logger.go @@ -26,7 +26,7 @@ type ( // - time_unix_nano // - time_rfc3339 // - time_rfc3339_nano - // - id (Request ID - Not implemented) + // - id (Request ID) // - remote_ip // - uri // - host @@ -62,7 +62,7 @@ var ( // DefaultLoggerConfig is the default Logger middleware config. DefaultLoggerConfig = LoggerConfig{ Skipper: DefaultSkipper, - Format: `{"time":"${time_rfc3339_nano}","remote_ip":"${remote_ip}","host":"${host}",` + + Format: `{"time":"${time_rfc3339_nano}","id":"${id}","remote_ip":"${remote_ip}","host":"${host}",` + `"method":"${method}","uri":"${uri}","status":${status}, "latency":${latency},` + `"latency_human":"${latency_human}","bytes_in":${bytes_in},` + `"bytes_out":${bytes_out}}` + "\n", @@ -126,6 +126,12 @@ func LoggerWithConfig(config LoggerConfig) echo.MiddlewareFunc { return buf.WriteString(time.Now().Format(time.RFC3339)) case "time_rfc3339_nano": return buf.WriteString(time.Now().Format(time.RFC3339Nano)) + case "id": + id := req.Header.Get(echo.HeaderXRequestID) + if id == "" { + id = res.Header().Get(echo.HeaderXRequestID) + } + return buf.WriteString(id) case "remote_ip": return buf.WriteString(c.RealIP()) case "host": @@ -177,6 +183,11 @@ func LoggerWithConfig(config LoggerConfig) echo.MiddlewareFunc { return buf.Write([]byte(c.QueryParam(tag[6:]))) case strings.HasPrefix(tag, "form:"): return buf.Write([]byte(c.FormValue(tag[5:]))) + case strings.HasPrefix(tag, "cookie:"): + cookie, err := c.Cookie(tag[7:]) + if err == nil { + return buf.Write([]byte(cookie.Value)) + } } } return 0, nil diff --git a/vendor/github.com/labstack/echo/middleware/middleware.go b/vendor/github.com/labstack/echo/middleware/middleware.go index 7edccc1d..efcbab91 100644 --- a/vendor/github.com/labstack/echo/middleware/middleware.go +++ b/vendor/github.com/labstack/echo/middleware/middleware.go @@ -9,6 +9,6 @@ type ( ) // DefaultSkipper returns false which processes the middleware. -func DefaultSkipper(c echo.Context) bool { +func DefaultSkipper(echo.Context) bool { return false } diff --git a/vendor/github.com/labstack/echo/middleware/proxy.go b/vendor/github.com/labstack/echo/middleware/proxy.go new file mode 100644 index 00000000..7eb24abf --- /dev/null +++ b/vendor/github.com/labstack/echo/middleware/proxy.go @@ -0,0 +1,160 @@ +package middleware + +import ( + "errors" + "fmt" + "io" + "math/rand" + "net" + "net/http" + "net/http/httputil" + "net/url" + "sync/atomic" + "time" + + "github.com/labstack/echo" +) + +// TODO: Handle TLS proxy + +type ( + // ProxyConfig defines the config for Proxy middleware. + ProxyConfig struct { + // Skipper defines a function to skip middleware. + Skipper Skipper + + // Balancer defines a load balancing technique. + // Required. + // Possible values: + // - RandomBalancer + // - RoundRobinBalancer + Balancer ProxyBalancer + } + + // ProxyTarget defines the upstream target. + ProxyTarget struct { + URL *url.URL + } + + // RandomBalancer implements a random load balancing technique. + RandomBalancer struct { + Targets []*ProxyTarget + random *rand.Rand + } + + // RoundRobinBalancer implements a round-robin load balancing technique. + RoundRobinBalancer struct { + Targets []*ProxyTarget + i uint32 + } + + // ProxyBalancer defines an interface to implement a load balancing technique. + ProxyBalancer interface { + Next() *ProxyTarget + } +) + +func proxyHTTP(t *ProxyTarget) http.Handler { + return httputil.NewSingleHostReverseProxy(t.URL) +} + +func proxyRaw(t *ProxyTarget, c echo.Context) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + h, ok := w.(http.Hijacker) + if !ok { + c.Error(errors.New("proxy raw, not a hijacker")) + return + } + in, _, err := h.Hijack() + if err != nil { + c.Error(fmt.Errorf("proxy raw, hijack error=%v, url=%s", r.URL, err)) + return + } + defer in.Close() + + out, err := net.Dial("tcp", t.URL.Host) + if err != nil { + he := echo.NewHTTPError(http.StatusBadGateway, fmt.Sprintf("proxy raw, dial error=%v, url=%s", r.URL, err)) + c.Error(he) + return + } + defer out.Close() + + err = r.Write(out) + if err != nil { + he := echo.NewHTTPError(http.StatusBadGateway, fmt.Sprintf("proxy raw, request copy error=%v, url=%s", r.URL, err)) + c.Error(he) + return + } + + errc := make(chan error, 2) + cp := func(dst io.Writer, src io.Reader) { + _, err := io.Copy(dst, src) + errc <- err + } + + go cp(out, in) + go cp(in, out) + err = <-errc + if err != nil && err != io.EOF { + c.Logger().Errorf("proxy raw, error=%v, url=%s", r.URL, err) + } + }) +} + +// Next randomly returns an upstream target. +func (r *RandomBalancer) Next() *ProxyTarget { + if r.random == nil { + r.random = rand.New(rand.NewSource(int64(time.Now().Nanosecond()))) + } + return r.Targets[r.random.Intn(len(r.Targets))] +} + +// Next returns an upstream target using round-robin technique. +func (r *RoundRobinBalancer) Next() *ProxyTarget { + r.i = r.i % uint32(len(r.Targets)) + t := r.Targets[r.i] + atomic.AddUint32(&r.i, 1) + return t +} + +// Proxy returns an HTTP/WebSocket reverse proxy middleware. +func Proxy(config ProxyConfig) echo.MiddlewareFunc { + // Defaults + if config.Skipper == nil { + config.Skipper = DefaultLoggerConfig.Skipper + } + if config.Balancer == nil { + panic("echo: proxy middleware requires balancer") + } + + return func(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) (err error) { + req := c.Request() + res := c.Response() + tgt := config.Balancer.Next() + + // Fix header + if req.Header.Get(echo.HeaderXRealIP) == "" { + req.Header.Set(echo.HeaderXRealIP, c.RealIP()) + } + if req.Header.Get(echo.HeaderXForwardedProto) == "" { + req.Header.Set(echo.HeaderXForwardedProto, c.Scheme()) + } + if c.IsWebSocket() && req.Header.Get(echo.HeaderXForwardedFor) == "" { // For HTTP, it is automatically set by Go HTTP reverse proxy. + req.Header.Set(echo.HeaderXForwardedFor, c.RealIP()) + } + + // Proxy + switch { + case c.IsWebSocket(): + proxyRaw(tgt, c).ServeHTTP(res, req) + case req.Header.Get(echo.HeaderAccept) == "text/event-stream": + default: + proxyHTTP(tgt).ServeHTTP(res, req) + } + + return + } + } +} diff --git a/vendor/github.com/labstack/echo/middleware/request_id.go b/vendor/github.com/labstack/echo/middleware/request_id.go new file mode 100644 index 00000000..f376c296 --- /dev/null +++ b/vendor/github.com/labstack/echo/middleware/request_id.go @@ -0,0 +1,64 @@ +package middleware + +import ( + "github.com/labstack/echo" + "github.com/labstack/gommon/random" +) + +type ( + // RequestIDConfig defines the config for RequestID middleware. + RequestIDConfig struct { + // Skipper defines a function to skip middleware. + Skipper Skipper + + // Generator defines a function to generate an ID. + // Optional. Default value random.String(32). + Generator func() string + } +) + +var ( + // DefaultRequestIDConfig is the default RequestID middleware config. + DefaultRequestIDConfig = RequestIDConfig{ + Skipper: DefaultSkipper, + Generator: generator, + } +) + +// RequestID returns a X-Request-ID middleware. +func RequestID() echo.MiddlewareFunc { + return RequestIDWithConfig(DefaultRequestIDConfig) +} + +// RequestIDWithConfig returns a X-Request-ID middleware with config. +func RequestIDWithConfig(config RequestIDConfig) echo.MiddlewareFunc { + // Defaults + if config.Skipper == nil { + config.Skipper = DefaultRequestIDConfig.Skipper + } + if config.Generator == nil { + config.Generator = generator + } + + return func(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + if config.Skipper(c) { + return next(c) + } + + req := c.Request() + res := c.Response() + rid := req.Header.Get(echo.HeaderXRequestID) + if rid == "" { + rid = config.Generator() + } + res.Header().Set(echo.HeaderXRequestID, rid) + + return next(c) + } + } +} + +func generator() string { + return random.String(32) +} diff --git a/vendor/github.com/labstack/echo/middleware/static.go b/vendor/github.com/labstack/echo/middleware/static.go index 793c1445..e715c1c4 100644 --- a/vendor/github.com/labstack/echo/middleware/static.go +++ b/vendor/github.com/labstack/echo/middleware/static.go @@ -3,7 +3,9 @@ package middleware import ( "fmt" "os" + "path" "path/filepath" + "strings" "github.com/labstack/echo" ) @@ -53,6 +55,9 @@ func Static(root string) echo.MiddlewareFunc { // See `Static()`. func StaticWithConfig(config StaticConfig) echo.MiddlewareFunc { // Defaults + if config.Root == "" { + config.Root = "." // For security we want to restrict to CWD. + } if config.Skipper == nil { config.Skipper = DefaultStaticConfig.Skipper } @@ -62,26 +67,44 @@ func StaticWithConfig(config StaticConfig) echo.MiddlewareFunc { return func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { - p := c.Param("*") - name := filepath.Join(config.Root, p) - fi, err := os.Stat(name) + if config.Skipper(c) { + return next(c) + } + p := c.Request().URL.Path + if strings.HasSuffix(c.Path(), "*") { // When serving from a group, e.g. `/static*`. + p = c.Param("*") + } + name := filepath.Join(config.Root, path.Clean("/"+p)) // "/"+ for security + + fi, err := os.Stat(name) if err != nil { if os.IsNotExist(err) { - if config.HTML5 { + if config.HTML5 && path.Ext(p) == "" { return c.File(filepath.Join(config.Root, config.Index)) } - return echo.ErrNotFound + return next(c) } return err } if fi.IsDir() { - if config.Browse { - return listDir(name, c.Response()) + index := filepath.Join(name, config.Index) + fi, err = os.Stat(index) + + if err != nil { + if config.Browse { + return listDir(name, c.Response()) + } + if os.IsNotExist(err) { + return next(c) + } + return err } - return c.File(filepath.Join(name, config.Index)) + + return c.File(index) } + return c.File(name) } } -- cgit v1.2.3