package handlers import ( "errors" "net/http" ) // MaxFormBytes bounds the request body accepted on the HTML form POST // routes (POST / and POST /generate). The forms carry a handful of short // fields, so 1 MiB is generous while making the bound explicit rather than // resting on ParseForm's incidental 10 MB cap. const MaxFormBytes = 1 << 20 // 1 MiB // LimitBody returns middleware that caps the request body on POST requests // at maxBytes and rejects an oversized body with 413 Request Entity Too // Large. // // It parses the form here, before the CSRF middleware reads the token from // it. The CSRF middleware reads the token with PostFormValue, which // swallows a parse error, so if the body were only capped there an // oversized body would read as a missing token and be refused as 403. By // parsing under the cap first, an oversized body is refused as 413. A // successful parse is cached on the request, so the CSRF check and the // handler reuse it rather than reading the body again. func (s *Handlers) LimitBody(maxBytes int64) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method == http.MethodPost { r.Body = http.MaxBytesReader(w, r.Body, maxBytes) err := r.ParseForm() var tooLarge *http.MaxBytesError if errors.As(err, &tooLarge) { http.Error(w, "Request body too large", http.StatusRequestEntityTooLarge) return } } next.ServeHTTP(w, r) }) } }