Files
simplexcalc/internal/middleware/bodylimit.go
T
clawbot f8ce8cef83 Seed from go-template-repo, renamed to simplexcalc
The template's files at a77fd30, without its history or LICENSE, after
script/rename simplexcalc.

Model: opus-5-5
2026-09-26 21:38:57 +00:00

47 lines
1.5 KiB
Go

package middleware
import (
"net/http"
"strconv"
)
// BodyLimit caps how much of a request body a handler can read.
//
// http.MaxBytesReader is the mechanism, and the reason to use it rather
// than checking Content-Length is that Content-Length is a claim: a
// chunked request does not send one, and a lying one is trivial to
// send. MaxBytesReader counts the bytes that actually arrive and makes
// the read fail past the cap, so the ceiling holds whatever the headers
// said.
//
// It also sets the response's error status itself (413) when the limit
// is hit during a read, so a handler that ignores the read error still
// cannot serve a success off a truncated body.
//
// Content-Length is still checked first, as an early refusal: it costs
// nothing and it lets an oversized upload be rejected before it is
// transferred.
func (m *Middleware) BodyLimit() func(http.Handler) http.Handler {
limit := m.cfg.MaxRequestBody
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.ContentLength > limit {
w.Header().Set("Content-Length", strconv.Itoa(len(tooLargeBody)))
http.Error(w, tooLargeBody, http.StatusRequestEntityTooLarge)
return
}
r.Body = http.MaxBytesReader(w, r.Body, limit)
next.ServeHTTP(w, r)
})
}
}
// tooLargeBody is the response to an oversized request. It names no
// limit: the number is an operational detail and telling a caller
// exactly where the ceiling is only helps them sit under it.
const tooLargeBody = "request body too large"