summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/labstack/echo/middleware
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/labstack/echo/middleware')
-rw-r--r--vendor/github.com/labstack/echo/middleware/basic_auth.go28
-rw-r--r--vendor/github.com/labstack/echo/middleware/compress.go4
-rw-r--r--vendor/github.com/labstack/echo/middleware/jwt.go2
-rw-r--r--vendor/github.com/labstack/echo/middleware/key_auth.go7
-rw-r--r--vendor/github.com/labstack/echo/middleware/logger.go15
-rw-r--r--vendor/github.com/labstack/echo/middleware/middleware.go2
-rw-r--r--vendor/github.com/labstack/echo/middleware/proxy.go160
-rw-r--r--vendor/github.com/labstack/echo/middleware/request_id.go64
-rw-r--r--vendor/github.com/labstack/echo/middleware/static.go39
9 files changed, 301 insertions, 20 deletions
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)
}
}