Repository: labstack/echo
Pull request #1181 (2018-08-20 08:15:06)

 Add error variable for too many request


Patch:
diff --git a/.travis.yml b/.travis.yml
index 05e53b1..7de4f96 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,6 +2,7 @@ language: go
 go:
   - 1.9.x
   - 1.10.x
+  - 1.11.x
   - tip
 install:
   - make dependency
diff --git a/Gopkg.lock b/Gopkg.lock
index f3c3b8d..a25473a 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -2,74 +2,113 @@
 
 
 [[projects]]
+  digest = "1:56c130d885a4aacae1dd9c7b71cfe39912c7ebc1ff7d2b46083c8812996dc43b"
   name = "github.com/davecgh/go-spew"
   packages = ["spew"]
+  pruneopts = ""
   revision = "346938d642f2ec3594ed81d874461961cd0faa76"
   version = "v1.1.0"
 
 [[projects]]
+  digest = "1:6098222470fe0172157ce9bbef5d2200df4edde17ee649c5d6e48330e4afa4c6"
   name = "github.com/dgrijalva/jwt-go"
   packages = ["."]
+  pruneopts = ""
   revision = "06ea1031745cb8b3dab3f6a236daf2b0aa468b7e"
   version = "v3.2.0"
 
 [[projects]]
+  digest = "1:f0c583bb1189614701bb928f1a73a7f71a3d31b76f1fbbe6619a83d92cbd2def"
   name = "github.com/labstack/gommon"
-  packages = ["bytes","color","log","random"]
-  revision = "6fe1405d73ec4bd4cd8a4ac8e2a2b2bf95d03954"
-  version = "0.2.4"
+  packages = [
+    "bytes",
+    "color",
+    "log",
+    "random",
+  ]
+  pruneopts = ""
+  revision = "2a618302b929cc20862dda3aa6f02f64dbe740dd"
+  version = "v0.2.7"
 
 [[projects]]
+  digest = "1:9ea83adf8e96d6304f394d40436f2eb44c1dc3250d223b74088cc253a6cd0a1c"
   name = "github.com/mattn/go-colorable"
   packages = ["."]
+  pruneopts = ""
   revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072"
   version = "v0.0.9"
 
 [[projects]]
+  digest = "1:78229b46ddb7434f881390029bd1af7661294af31f6802e0e1bedaad4ab0af3c"
   name = "github.com/mattn/go-isatty"
   packages = ["."]
+  pruneopts = ""
   revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39"
   version = "v0.0.3"
 
 [[projects]]
+  digest = "1:256484dbbcd271f9ecebc6795b2df8cad4c458dd0f5fd82a8c2fa0c29f233411"
   name = "github.com/pmezard/go-difflib"
   packages = ["difflib"]
+  pruneopts = ""
   revision = "792786c7400a136282c1664665ae0a8db921c6c2"
   version = "v1.0.0"
 
 [[projects]]
+  digest = "1:a30066593578732a356dc7e5d7f78d69184ca65aeeff5939241a3ab10559bb06"
   name = "github.com/stretchr/testify"
   packages = ["assert"]
+  pruneopts = ""
   revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71"
   version = "v1.2.1"
 
 [[projects]]
   branch = "master"
+  digest = "1:857a9ecd5cb13379ecc8f798f6e6b6b574c98b9355657d91e068275f1120aaf7"
   name = "github.com/valyala/bytebufferpool"
   packages = ["."]
+  pruneopts = ""
   revision = "e746df99fe4a3986f4d4f79e13c1e0117ce9c2f7"
 
 [[projects]]
   branch = "master"
+  digest = "1:bf6f8915c0338e875383cb7fdebd58a4d360a232f461d9a029d7ccb12f90c5d7"
   name = "github.com/valyala/fasttemplate"
   packages = ["."]
+  pruneopts = ""
   revision = "dcecefd839c4193db0d35b88ec65b4c12d360ab0"
 
 [[projects]]
   branch = "master"
+  digest = "1:7fdbf5fb3eb8256d4c01abe969062a77fa5818cd900dc3302a2400c6ed668860"
   name = "golang.org/x/crypto"
-  packages = ["acme","acme/autocert"]
+  packages = [
+    "acme",
+    "acme/autocert",
+  ]
+  pruneopts = ""
   revision = "182114d582623c1caa54f73de9c7224e23a48487"
 
 [[projects]]
   branch = "master"
+  digest = "1:4b4c7ad782ed549fccf044f2d0f6c3b6f76aca593db6649a9b2e6c12bd733f9a"
   name = "golang.org/x/sys"
   packages = ["unix"]
+  pruneopts = ""
   revision = "c28acc882ebcbfbe8ce9f0f14b9ac26ee138dd51"
 
 [solve-meta]
   analyzer-name = "dep"
   analyzer-version = 1
-  inputs-digest = "9c7b45e80fe353405800cf01f429b3a203cfb8d4468a04c64a908e11a98ea764"
+  input-imports = [
+    "github.com/dgrijalva/jwt-go",
+    "github.com/labstack/gommon/bytes",
+    "github.com/labstack/gommon/color",
+    "github.com/labstack/gommon/log",
+    "github.com/labstack/gommon/random",
+    "github.com/stretchr/testify/assert",
+    "github.com/valyala/fasttemplate",
+    "golang.org/x/crypto/acme/autocert",
+  ]
   solver-name = "gps-cdcl"
   solver-version = 1
diff --git a/Gopkg.toml b/Gopkg.toml
index 61de60c..3ebbc7f 100644
--- a/Gopkg.toml
+++ b/Gopkg.toml
@@ -27,7 +27,7 @@
 
 [[constraint]]
   name = "github.com/labstack/gommon"
-  version = "0.2.4"
+  version = "v0.2.7"
 
 [[constraint]]
   name = "github.com/stretchr/testify"
diff --git a/Makefile b/Makefile
index 494667d..68d3a04 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-DEP_VERSION=0.4.1
+DEP_VERSION=0.5.0
 
 dependency:
 	curl -fsSL -o ${GOPATH}/bin/dep https://github.com/golang/dep/releases/download/v${DEP_VERSION}/dep-linux-amd64
diff --git a/bind.go b/bind.go
index 4c37248..23f3a1b 100644
--- a/bind.go
+++ b/bind.go
@@ -47,9 +47,8 @@ func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) {
 				return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Unmarshal type error: expected=%v, got=%v, field=%v, offset=%v", ute.Type, ute.Value, ute.Field, ute.Offset))
 			} else if se, ok := err.(*json.SyntaxError); ok {
 				return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Syntax error: offset=%v, error=%v", se.Offset, se.Error()))
-			} else {
-				return NewHTTPError(http.StatusBadRequest, err.Error())
 			}
+			return NewHTTPError(http.StatusBadRequest, err.Error())
 		}
 	case strings.HasPrefix(ctype, MIMEApplicationXML), strings.HasPrefix(ctype, MIMETextXML):
 		if err = xml.NewDecoder(req.Body).Decode(i); err != nil {
@@ -57,9 +56,8 @@ func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) {
 				return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Unsupported type error: type=%v, error=%v", ute.Type, ute.Error()))
 			} else if se, ok := err.(*xml.SyntaxError); ok {
 				return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Syntax error: line=%v, error=%v", se.Line, se.Error()))
-			} else {
-				return NewHTTPError(http.StatusBadRequest, err.Error())
 			}
+			return NewHTTPError(http.StatusBadRequest, err.Error())
 		}
 	case strings.HasPrefix(ctype, MIMEApplicationForm), strings.HasPrefix(ctype, MIMEMultipartForm):
 		params, err := c.FormParams()
@@ -96,8 +94,7 @@ func (b *DefaultBinder) bindData(ptr interface{}, data map[string][]string, tag
 			inputFieldName = typeField.Name
 			// If tag is nil, we inspect if the field is a struct.
 			if _, ok := bindUnmarshaler(structField); !ok && structFieldKind == reflect.Struct {
-				err := b.bindData(structField.Addr().Interface(), data, tag)
-				if err != nil {
+				if err := b.bindData(structField.Addr().Interface(), data, tag); err != nil {
 					return err
 				}
 				continue
@@ -142,10 +139,9 @@ func (b *DefaultBinder) bindData(ptr interface{}, data map[string][]string, tag
 				}
 			}
 			val.Field(i).Set(slice)
-		} else {
-			if err := setWithProperType(typeField.Type.Kind(), inputValue[0], structField); err != nil {
-				return err
-			}
+		} else if err := setWithProperType(typeField.Type.Kind(), inputValue[0], structField); err != nil {
+			return err
+
 		}
 	}
 	return nil
diff --git a/context.go b/context.go
index cf780c5..9a9d133 100644
--- a/context.go
+++ b/context.go
@@ -256,14 +256,13 @@ func (c *context) Scheme() string {
 }
 
 func (c *context) RealIP() string {
-	ra := c.request.RemoteAddr
 	if ip := c.request.Header.Get(HeaderXForwardedFor); ip != "" {
-		ra = strings.Split(ip, ", ")[0]
-	} else if ip := c.request.Header.Get(HeaderXRealIP); ip != "" {
-		ra = ip
-	} else {
-		ra, _, _ = net.SplitHostPort(ra)
+		return strings.Split(ip, ", ")[0]
+	}
+	if ip := c.request.Header.Get(HeaderXRealIP); ip != "" {
+		return ip
 	}
+	ra, _, _ := net.SplitHostPort(c.request.RemoteAddr)
 	return ra
 }
 
diff --git a/echo.go b/echo.go
index e017816..d325aa4 100644
--- a/echo.go
+++ b/echo.go
@@ -62,7 +62,7 @@ import (
 type (
 	// Echo is the top-level framework instance.
 	Echo struct {
-		stdLogger        *stdLog.Logger
+		StdLogger        *stdLog.Logger
 		colorer          *color.Color
 		premiddleware    []MiddlewareFunc
 		middleware       []MiddlewareFunc
@@ -255,6 +255,7 @@ var (
 	ErrForbidden                   = NewHTTPError(http.StatusForbidden)
 	ErrMethodNotAllowed            = NewHTTPError(http.StatusMethodNotAllowed)
 	ErrStatusRequestEntityTooLarge = NewHTTPError(http.StatusRequestEntityTooLarge)
+	ErrTooManyRequests             = NewHTTPError(http.StatusTooManyRequests)
 	ErrValidatorNotRegistered      = errors.New("validator not registered")
 	ErrRendererNotRegistered       = errors.New("renderer not registered")
 	ErrInvalidRedirectCode         = errors.New("invalid redirect status code")
@@ -289,7 +290,7 @@ func New() (e *Echo) {
 	e.HTTPErrorHandler = e.DefaultHTTPErrorHandler
 	e.Binder = &DefaultBinder{}
 	e.Logger.SetLevel(log.ERROR)
-	e.stdLogger = stdLog.New(e.Logger.Output(), e.Logger.Prefix()+": ", 0)
+	e.StdLogger = stdLog.New(e.Logger.Output(), e.Logger.Prefix()+": ", 0)
 	e.pool.New = func() interface{} {
 		return e.NewContext(nil, nil)
 	}
@@ -557,18 +558,17 @@ func (e *Echo) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	c := e.pool.Get().(*context)
 	c.Reset(r, w)
 
-	m := r.Method
 	h := NotFoundHandler
 
 	if e.premiddleware == nil {
-		e.router.Find(m, getPath(r), c)
+		e.router.Find(r.Method, getPath(r), c)
 		h = c.Handler()
 		for i := len(e.middleware) - 1; i >= 0; i-- {
 			h = e.middleware[i](h)
 		}
 	} else {
 		h = func(c Context) error {
-			e.router.Find(m, getPath(r), c)
+			e.router.Find(r.Method, getPath(r), c)
 			h := c.Handler()
 			for i := len(e.middleware) - 1; i >= 0; i-- {
 				h = e.middleware[i](h)
@@ -635,7 +635,7 @@ func (e *Echo) startTLS(address string) error {
 func (e *Echo) StartServer(s *http.Server) (err error) {
 	// Setup
 	e.colorer.SetOutput(e.Logger.Output())
-	s.ErrorLog = e.stdLogger
+	s.ErrorLog = e.StdLogger
 	s.Handler = e
 	if e.Debug {
 		e.Logger.SetLevel(log.DEBUG)
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..b2b9f18
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,15 @@
+module github.com/labstack/echo
+
+require (
+	github.com/davecgh/go-spew v1.1.0 // indirect
+	github.com/dgrijalva/jwt-go v3.2.0+incompatible
+	github.com/labstack/gommon v0.2.7
+	github.com/mattn/go-colorable v0.0.9 // indirect
+	github.com/mattn/go-isatty v0.0.3 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	github.com/stretchr/testify v1.2.1
+	github.com/valyala/bytebufferpool v0.0.0-20160817181652-e746df99fe4a // indirect
+	github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4
+	golang.org/x/crypto v0.0.0-20180312195533-182114d58262
+	golang.org/x/sys v0.0.0-20180312081825-c28acc882ebc // indirect
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..7d5ffe0
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,22 @@
+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 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.7 h1:2qOPq/twXDrQ6ooBGrn3mrmVOC+biLlatwgIu8lbzRM=
+github.com/labstack/gommon v0.2.7/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.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI=
+github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+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/testify v1.2.1 h1:52QO5WkIUcHGIR7EnGagH88x1bUzqGXTC5/1bDTUQ7U=
+github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/valyala/bytebufferpool v0.0.0-20160817181652-e746df99fe4a h1:AOcehBWpFhYPYw0ioDTppQzgI8pAAahVCiMSKTp9rbo=
+github.com/valyala/bytebufferpool v0.0.0-20160817181652-e746df99fe4a/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-20180312195533-182114d58262 h1:1NLVUmR8SQ7cNNA5Vo7ronpXbR+5A+9IwIC/bLE7D8Y=
+golang.org/x/crypto v0.0.0-20180312195533-182114d58262/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/sys v0.0.0-20180312081825-c28acc882ebc h1:eCzBKjjvhDDXMoH5l7eA+YK1PEtyJ2QLj3f4IArr+zg=
+golang.org/x/sys v0.0.0-20180312081825-c28acc882ebc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=


Test patch:
diff --git a/echo_test.go b/echo_test.go
index 17c64f8..294a412 100644
--- a/echo_test.go
+++ b/echo_test.go
@@ -457,7 +457,7 @@ func request(method, path string, e *Echo) (int, string) {
 }
 
 func TestHTTPError(t *testing.T) {
-	err := NewHTTPError(400, map[string]interface{}{
+	err := NewHTTPError(http.StatusBadRequest, map[string]interface{}{
 		"code": 12,
 	})
 	assert.Equal(t, "code=400, message=map[code:12]", err.Error())
diff --git a/middleware/body_dump_test.go b/middleware/body_dump_test.go
index 188ed4f..8649034 100644
--- a/middleware/body_dump_test.go
+++ b/middleware/body_dump_test.go
@@ -60,12 +60,7 @@ func TestBodyDumpFails(t *testing.T) {
 		return errors.New("some error")
 	}
 
-	requestBody := ""
-	responseBody := ""
-	mw := BodyDump(func(c echo.Context, reqBody, resBody []byte) {
-		requestBody = string(reqBody)
-		responseBody = string(resBody)
-	})
+	mw := BodyDump(func(c echo.Context, reqBody, resBody []byte) {})
 
 	if !assert.Error(t, mw(h)(c)) {
 		t.FailNow()
@@ -84,8 +79,6 @@ func TestBodyDumpFails(t *testing.T) {
 				return true
 			},
 			Handler: func(c echo.Context, reqBody, resBody []byte) {
-				requestBody = string(reqBody)
-				responseBody = string(resBody)
 			},
 		})