cicadel

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, Set returns bodylimit.ErrBodyRead and Limit answers 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/accounts no longer caps every route under Browser.Middleware at 8 KiB. The account pages keep their own 8 KiB bound.
  • Handlers served outside a cicadel.Application have no adjustable limit. Set then wraps the body with http.MaxBytesReader, which can only lower an existing limit. Call bodylimit.Apply to install one.

Keep MaxBodyBytes small. Every form and JSON endpoint accepts that much without asking.

Type to search this version.