diff --git a/error.go b/error.go
index e5e9fd47..f268f723 100644
--- a/error.go
+++ b/error.go
@@ -28,7 +28,7 @@ import (
)
const (
- errorTypeHandler = iota
+ errorTypeHandler = iota
errorTypeController
)
@@ -359,6 +359,20 @@ func gatewayTimeout(rw http.ResponseWriter, r *http.Request) {
)
}
+// show 413 Payload Too Large
+func payloadTooLarge(rw http.ResponseWriter, r *http.Request) {
+ responseError(rw, r,
+ 413,
+ `
The page you have requested is unavailable.
+
Perhaps you are here because:
+
+
The request entity is larger than limits defined by server.
+
Please change the request entity and try again.
+
+ `,
+ )
+}
+
func responseError(rw http.ResponseWriter, r *http.Request, errCode int, errContent string) {
t, _ := template.New("beegoerrortemp").Parse(errtpl)
data := M{
diff --git a/hooks.go b/hooks.go
index b8671d35..49c42d5a 100644
--- a/hooks.go
+++ b/hooks.go
@@ -34,6 +34,7 @@ func registerDefaultErrorHandler() error {
"504": gatewayTimeout,
"417": invalidxsrf,
"422": missingxsrf,
+ "413": payloadTooLarge,
}
for e, h := range m {
if _, ok := ErrorMaps[e]; !ok {
diff --git a/router.go b/router.go
index b19a199d..a993a1af 100644
--- a/router.go
+++ b/router.go
@@ -742,6 +742,12 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
if r.Method != http.MethodGet && r.Method != http.MethodHead {
if BConfig.CopyRequestBody && !context.Input.IsUpload() {
+ // connection will close if the incoming data are larger (RFC 7231, 6.5.11)
+ if r.ContentLength > BConfig.MaxMemory {
+ logs.Error(errors.New("payload too large"))
+ exception("413", context)
+ goto Admin
+ }
context.Input.CopyBody(BConfig.MaxMemory)
}
context.Input.ParseFormOrMulitForm(BConfig.MaxMemory)
diff --git a/router_test.go b/router_test.go
index 2797b33a..8ec7927a 100644
--- a/router_test.go
+++ b/router_test.go
@@ -15,6 +15,7 @@
package beego
import (
+ "bytes"
"net/http"
"net/http/httptest"
"strings"
@@ -71,7 +72,6 @@ func (tc *TestController) GetEmptyBody() {
tc.Ctx.Output.Body(res)
}
-
type JSONController struct {
Controller
}
@@ -656,17 +656,14 @@ func beegoBeforeRouter1(ctx *context.Context) {
ctx.WriteString("|BeforeRouter1")
}
-
func beegoBeforeExec1(ctx *context.Context) {
ctx.WriteString("|BeforeExec1")
}
-
func beegoAfterExec1(ctx *context.Context) {
ctx.WriteString("|AfterExec1")
}
-
func beegoFinishRouter1(ctx *context.Context) {
ctx.WriteString("|FinishRouter1")
}
@@ -709,3 +706,27 @@ func TestYAMLPrepare(t *testing.T) {
t.Errorf(w.Body.String())
}
}
+
+func TestRouterEntityTooLargeCopyBody(t *testing.T) {
+ _MaxMemory := BConfig.MaxMemory
+ _CopyRequestBody := BConfig.CopyRequestBody
+ BConfig.CopyRequestBody = true
+ BConfig.MaxMemory = 20
+
+ b := bytes.NewBuffer([]byte("barbarbarbarbarbarbarbarbarbar"))
+ r, _ := http.NewRequest("POST", "/user/123", b)
+ w := httptest.NewRecorder()
+
+ handler := NewControllerRegister()
+ handler.Post("/user/:id", func(ctx *context.Context) {
+ ctx.Output.Body([]byte(ctx.Input.Param(":id")))
+ })
+ handler.ServeHTTP(w, r)
+
+ BConfig.CopyRequestBody = _CopyRequestBody
+ BConfig.MaxMemory = _MaxMemory
+
+ if w.Code != http.StatusRequestEntityTooLarge {
+ t.Errorf("TestRouterRequestEntityTooLarge can't run")
+ }
+}