Thanks to visit codestin.com
Credit goes to github.com

Skip to content

caddyhttp: surface 413 for oversized request body placeholders - #7969

Open
hktitof wants to merge 1 commit into
caddyserver:masterfrom
hktitof:fix/request-body-placeholder-max-size
Open

caddyhttp: surface 413 for oversized request body placeholders#7969
hktitof wants to merge 1 commit into
caddyserver:masterfrom
hktitof:fix/request-body-placeholder-max-size

Conversation

@hktitof

@hktitof hktitof commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Summary

fixes #7691

when a request body goes over the request_body max_size limit, the request_body handler turns the http.MaxBytesError into a caddyhttp handler error with status 413, but the {http.request.body} and {http.request.body_base64} placeholders read with io.Copy and ignored the error, so they returned the truncated prefix as if it was the whole body. the docs say a read past max_size returns 413, and a silently truncated body is a bad failure mode in templates and vars_regexp where code makes decisions from that value (i am following the narrower follow-up that was prescribed when #7692 was closed)

so now the placeholder path surfaces that 413 handler error instead, and the template placeholder func plus the vars matchers propagate only that status-carrying error, so the oversized request fails with 413 in both consumption sites. every other placeholder and every other error path stays unchanged

Testing

  • go test ./modules/caddyhttp/... -count=1 (14 packages ok)
  • go test -race ./modules/caddyhttp/ ./modules/caddyhttp/templates/
  • go test ./caddytest/integration/ -run TestRequestBodyPlaceholder (2/2 pass)
  • go vet ./modules/caddyhttp/...
  • golangci-lint run modules/caddyhttp/... (0 issues)
  • gofmt clean

the two new integration tests fail before this change (they got 200 instead of 413) and pass after

Assistance Disclosure

this change was written with the help of AI coding agents (GLM in my local harness), i reviewed and tested every line before submitting, and the implementation follows the maintainer-prescribed scope from the issue thread

@CLAassistant

CLAassistant commented Aug 30, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

steadytao

This comment was marked as outdated.

@steadytao
steadytao enabled auto-merge (squash) September 2, 2026 21:28
@steadytao
steadytao disabled auto-merge September 2, 2026 21:30

@steadytao steadytao left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is narrower than #7692 because it only propagates HandlerError but the behaviour is still generic across every placeholder and variable value of that type. The requested follow-up was meant to scope control flow specifically to {http.request.body} and {http.request.body_base64} hitting request_body max_size.

Please use a request-body-specific marker or state and have the consumers recognise only that condition. Existing or future unrelated HandlerError values must retain their current behaviour. Add negative regressions proving an unrelated HandlerError in templates, vars and vars_regexp does not start controlling request handling.

@steadytao steadytao added the bug 🐞 Something isn't working label Sep 2, 2026
@steadytao steadytao added this to the v2.11.5 milestone Sep 2, 2026
when a request exceeds the request_body max_size limit, the request_body handler wraps the http.MaxBytesError into a caddyhttp.HandlerError carrying status 413, but the {http.request.body} and {http.request.body_base64} placeholders ran io.Copy with the error ignored, so they silently returned the truncated prefix as though it were the complete body. docs promise a 413 for reads past max_size, and silently truncating is a bad failure mode in templates and vars_regexp where the body value drives decisions. see caddyserver#7691 and the narrow follow-up prescribed when caddyserver#7692 was closed

reading the body now returns a dedicated RequestBodyLimitError marker instead of a generic HandlerError, and only when the read failure is actually the max_size limit. the consumers (template placeholder function, vars and vars_regexp matchers) recognize exactly that marker and wrap it in a status carrying handler error so the oversized request fails with 413, while every unrelated error value keeps its old behavior: templates still render it as text and the vars matchers still match on its error text. the surfaced error is stripped of its generated id and stack trace so a placeholder stringified into a response body cannot leak the call stack

negative regressions prove an unrelated HandlerError in templates, vars and vars_regexp does not start controlling request handling, plus integration tests for the template and vars_regexp 413 paths

ai assisted (GLM agent) under Abdel's direction and local verification

Signed-off-by: Abdel <[email protected]>
@hktitof
hktitof force-pushed the fix/request-body-placeholder-max-size branch from add471a to 23bc340 Compare September 2, 2026 21:59

@steadytao steadytao left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Cheers.

@steadytao
steadytao requested a review from mholt September 2, 2026 22:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug 🐞 Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Placeholder http.request.body truncates at max_size bytes, rather than producing a 413 error

3 participants