diff --git a/README.md b/README.md index 07357be4..d16a8682 100644 --- a/README.md +++ b/README.md @@ -277,6 +277,8 @@ References issue [#774](https://github.com/gin-gonic/gin/issues/774) and detail ```go func main() { router := gin.Default() + // Set a lower memory limit for multipart forms (default is 32 MiB) + // router.MaxMultipartMemory = 8 << 20 // 8 MiB router.POST("/upload", func(c *gin.Context) { // single file file, _ := c.FormFile("file") @@ -306,6 +308,8 @@ See the detail [example code](examples/upload-file/multiple). ```go func main() { router := gin.Default() + // Set a lower memory limit for multipart forms (default is 32 MiB) + // router.MaxMultipartMemory = 8 << 20 // 8 MiB router.POST("/upload", func(c *gin.Context) { // Multipart form form, _ := c.MultipartForm() diff --git a/context.go b/context.go index d7b6c61d..74995e68 100644 --- a/context.go +++ b/context.go @@ -34,8 +34,7 @@ const ( ) const ( - defaultMemory = 32 << 20 // 32 MB - abortIndex int8 = math.MaxInt8 / 2 + abortIndex int8 = math.MaxInt8 / 2 ) // Context is the most important part of gin. It allows us to pass variables between middleware, @@ -407,7 +406,7 @@ func (c *Context) PostFormArray(key string) []string { func (c *Context) GetPostFormArray(key string) ([]string, bool) { req := c.Request req.ParseForm() - req.ParseMultipartForm(defaultMemory) + req.ParseMultipartForm(c.engine.MaxMultipartMemory) if values := req.PostForm[key]; len(values) > 0 { return values, true } @@ -427,7 +426,7 @@ func (c *Context) FormFile(name string) (*multipart.FileHeader, error) { // MultipartForm is the parsed multipart form, including file uploads. func (c *Context) MultipartForm() (*multipart.Form, error) { - err := c.Request.ParseMultipartForm(defaultMemory) + err := c.Request.ParseMultipartForm(c.engine.MaxMultipartMemory) return c.Request.MultipartForm, err } diff --git a/examples/upload-file/multiple/main.go b/examples/upload-file/multiple/main.go index 4bb4cdcb..a55325ed 100644 --- a/examples/upload-file/multiple/main.go +++ b/examples/upload-file/multiple/main.go @@ -9,6 +9,8 @@ import ( func main() { router := gin.Default() + // Set a lower memory limit for multipart forms (default is 32 MiB) + router.MaxMultipartMemory = 8 << 20 // 8 MiB router.Static("/", "./public") router.POST("/upload", func(c *gin.Context) { name := c.PostForm("name") diff --git a/examples/upload-file/single/main.go b/examples/upload-file/single/main.go index 372a2994..5d438651 100644 --- a/examples/upload-file/single/main.go +++ b/examples/upload-file/single/main.go @@ -9,6 +9,8 @@ import ( func main() { router := gin.Default() + // Set a lower memory limit for multipart forms (default is 32 MiB) + router.MaxMultipartMemory = 8 << 20 // 8 MiB router.Static("/", "./public") router.POST("/upload", func(c *gin.Context) { name := c.PostForm("name") diff --git a/gin.go b/gin.go index ee39c9aa..24c4dd8d 100644 --- a/gin.go +++ b/gin.go @@ -15,7 +15,10 @@ import ( ) // Version is Framework's version. -const Version = "v1.2" +const ( + Version = "v1.2" + defaultMultipartMemory = 32 << 20 // 32 MB +) var default404Body = []byte("404 page not found") var default405Body = []byte("405 method not allowed") @@ -92,6 +95,10 @@ type Engine struct { // If UseRawPath is false (by default), the UnescapePathValues effectively is true, // as url.Path gonna be used, which is already unescaped. UnescapePathValues bool + + // Value of 'maxMemory' param that is given to http.Request's ParseMultipartForm + // method call. + MaxMultipartMemory int64 } var _ IRouter = &Engine{} @@ -120,6 +127,7 @@ func New() *Engine { AppEngine: defaultAppEngine, UseRawPath: false, UnescapePathValues: true, + MaxMultipartMemory: defaultMultipartMemory, trees: make(methodTrees, 0, 9), delims: render.Delims{Left: "{{", Right: "}}"}, secureJsonPrefix: "while(1);",