fix(multipart): respect MaxBodyBytes limit - #1094
Conversation
`(huma.Operation).MaxBodyBytes` was only enforced for normal request bodies via the `readBody` path, but multipart requests take a separate path throug `readForm` / `(huma.Context).GetMultipartForm()` and did not consult `op.MaxBodyBytes`. This change makes the `MaxBodyBytes` value be respected in all paths.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1094 +/- ##
==========================================
- Coverage 93.20% 93.04% -0.16%
==========================================
Files 23 23
Lines 4988 5003 +15
==========================================
+ Hits 4649 4655 +6
- Misses 272 278 +6
- Partials 67 70 +3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR extends request body size limiting so that huma.Operation.MaxBodyBytes is enforced for multipart requests (which previously bypassed the readBody path), and adds test coverage to prevent regressions.
Changes:
- Pass
op.MaxBodyBytesinto the multipart parsing path (readForm) so multipart uploads are subject to the same limit. - Implement multipart parsing via a limited reader when
MaxBodyBytes > 0to detect oversize bodies. - Add a unit test ensuring oversized multipart requests return HTTP 413 and do not invoke the handler.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| huma.go | Routes multipart parsing through a new readForm(ctx, maxBytes) implementation to enforce MaxBodyBytes. |
| huma_test.go | Adds a test verifying multipart requests exceeding MaxBodyBytes return 413 and do not call the handler. |
Suppressed comments (2)
huma.go:1029
- When
readFormreturns aStatusError(e.g. 413 for MaxBodyBytes), this path appends it tores.Errorsand later wraps it withWriteErr(..., "validation failed", ...), so clients get a 413 with an unrelated top-leveldetailmessage. Consider short-circuiting and writingStatusErrorresponses directly here (similar to the handler error path).
This issue also appears on line 2075 of the same file.
if err != nil {
res.Errors = append(res.Errors, err)
} else {
huma.go:2077
- On multipart parse errors (
ReadFormreturning a non-nilform+err), the current code returns the form without cleaning up any temporary files created during parsing, and the caller ignoresformon error. This can leak temp files on malformed/aborted uploads.
if err != nil {
return form, &ErrorDetail{Location: "body", Message: "cannot read multipart form: " + err.Error()}
}
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
(huma.Operation).MaxBodyByteswas only enforced for normal request bodies via thereadBodypath, but multipart requests take a separate path througreadForm/(huma.Context).GetMultipartForm()and did not consultop.MaxBodyBytes.This change makes the
MaxBodyBytesvalue be respected in all paths.