Limit request bodies
Every request body is capped at settings.MaxBodyBytes (1 MiB by default,
CICADEL_MAX_BODY_BYTES). Raise the cap for one route, such as an upload, and
keep the small default everywhere else.
#Upload routes raise their own limit
forms/upload uses the upload’s Config.MaxBytes as the request’s limit. No
other change is needed:
Go
upload.Middleware(func(*http.Request) (upload.Config, error) {
return upload.Config{
MaxBytes: 12 << 20, // a 10 MB file plus the form around it
Fields: []upload.Field{{Name: "slip", MaxBytes: 10 << 20}},
}, nil
})Each field keeps its own Field.MaxBytes.
#Other routes: bodylimit.Limit
Wrap a route handler, or add the middleware to App.Middleware for every route
of an app:
Go
urls.Route{
Method: "POST",
Path: "/imports",
Name: "imports:create",
Handler: bodylimit.Limit(50 << 20)(http.HandlerFunc(createImport)),
}Limit can raise or lower the default. Inside a handler, call
bodylimit.Set(w, r, n) instead.
#Rules
- A limit can change only before the body is first read. After that,
Setreturnsbodylimit.ErrBodyReadandLimitanswers 500, because the route’s limit could not be applied. - Reading past the limit fails with
*http.MaxBytesError, and the server closes the connection after the response. Answer with 413 or a form error. - CSRF middleware parses URL-encoded forms, so its reads count against the route’s limit. Multipart bodies are not read by CSRF.
contrib/accountsno longer caps every route underBrowser.Middlewareat 8 KiB. The account pages keep their own 8 KiB bound.- Handlers served outside a
cicadel.Applicationhave no adjustable limit.Setthen wraps the body withhttp.MaxBytesReader, which can only lower an existing limit. Callbodylimit.Applyto install one.
Keep MaxBodyBytes small. Every form and JSON endpoint accepts that much
without asking.