Skip to content

Add configurable Axum buffered JSON body limits - #407

Draft
ChristianPavilonis wants to merge 2 commits into
issue-392-396-production-hosting-specfrom
issue-393-buffered-body-limit-spec
Draft

ChristianPavilonis wants to merge 2 commits into
issue-392-396-production-hosting-specfrom
issue-393-buffered-body-limit-spec

Conversation

@ChristianPavilonis

@ChristianPavilonis ChristianPavilonis commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Bound framework-managed Axum JSON buffering to a configurable 2 MiB default, exactly 2,097,152 bytes, with typed HTTP 413 on overflow. Keep taken streams, forwarding, manual collection, and other providers' defaults unchanged.
  • Preserve the original ceiling, JSON ingress classification, and cached provenance through request reconstruction, independent of mutable headers and extensions.
  • Reuse admission, lazy conversion, the existing collector/cache/poison state, and response lifecycle. Add strict startup validation and real HTTP/1 boundary tests.

Stacked on #406, which is based on #275. This implementation was explicitly authorized on the current hosting base at 3ab2209, without waiting for accepted #275 integration. No parent code was merged or rebased. Keep this PR draft until the later prerequisite rebase/re-audit and remaining acceptance work are complete.

Changes

Crate / File Change
Core body.rs, lib.rs Opaque policy/cache carrier, non-exhaustive public Body, exhaustive BodyContent raw handoff, and external API fixtures
Core context, extractors, errors Effective native/caller caps, typed PayloadTooLarge, sticky initial errors, and stateless cached rechecks
Core outbound and response preparation Strip ingress metadata at transport boundaries while preserving logical content and byte allocations
All four adapters' outbound/response consumers Migrate transport branching to exhaustive BodyContent without changing provider policies
Axum run options and development server Validated positive limit, fallible builders, strict decimal environment parsing, and safe OS-string development capture
Axum request/service Carry the selected limit through existing startup and attach immutable policy lazily after admission
Core, direct-service, and native HTTP/1 tests Reconstruction, cancellation/drop-once, deadline tie 408, usable Content-Length/chunked 413, overrides above 8 MiB, unrestricted taken streams, startup failures, and router-only defaults
Guides, changelog, spec and plan Configuration, approved breaking API migration, verification evidence, and remaining gaps

Breaking API: Body adds Managed and becomes #[non_exhaustive]. Downstream exhaustive raw-Body matches must migrate to accessors or Body::into_content and exhaustive BodyContent, or add a raw-Body wildcard.

Closes

Closes #393.

Part of #391. This PR remains draft until accepted-prerequisite integration and the remaining acceptance work below are complete.

Test plan

  • cargo test --workspace --all-targets
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo fmt --all -- --check
  • cargo check --workspace --all-targets --features "fastly cloudflare spin"
  • SDK-target cargo check --all-targets for Fastly, Spin, and Cloudflare, plus core WASM check
  • All 56 native/WASM adapter feature-matrix combinations
  • cargo test -p edgezero-core --all-targets, 724 unit and 2 integration tests
  • cargo test -p edgezero-core --doc, 2 regular and 4 compile-fail tests; 13 existing examples ignored
  • cargo test -p edgezero-adapter-axum --all-targets --all-features, 192 unit, 13 contract, 16 subprocess tests
  • Qualified tests::json_body_limit_wire_content_length_and_chunked executed separately and reported ok
  • Docs install, formatting, lint, build, outbound-contract guard, and internal Markdown/link/shell checks
  • git diff --check
  • Provider runtime suites, not implied by successful WASM compilation
  • Accepted feat: implement portable outbound HTTP and request lifecycle contracts #275 integration/re-audit and affected acceptance reruns
  • Excluded app-demo workspace and manual CLI serve, no entrypoint/generator source changes in this PR

Final Rust commands checked one 25-file source fingerprint before and after execution. The plan records commands, counts, elapsed times, and local log paths. Local /tmp artifacts are not durable CI evidence.

Remaining gaps include dedicated above-8-MiB reconstruction, actual router app-state replacement dispatch, and router-only override wire cases. Media variants were tested at the configured 64-byte boundary rather than repeated for every default-size framing. The router-only test awaits outer cancellation, not an explicit inner blocking-worker join.

Fastly all-feature native tests could not link provider host ABI imports; portable Fastly tests passed 94. The standalone Viceroy version differs from the pinned version, and wasmtime/wasm-bindgen-test-runner were unavailable, so no provider-runtime certification is claimed. One inherited storage subprocess selected-greeting assertion failed transiently during development, then passed individually and in subsequent full suites. It is unresolved, not classified as a reproduced baseline failure. Final native/workspace runs used no exclusions.

Checklist

  • Changes follow CLAUDE.md conventions
  • No Tokio dependency or blanket Send bound added to portable core
  • Route parameters use {id} syntax
  • HTTP types imported from edgezero_core
  • Existing registry/store wiring retained
  • New behavior has focused tests and independent read-only verification
  • Public source breaks documented
  • No secrets or credentials committed

@ChristianPavilonis ChristianPavilonis self-assigned this Oct 6, 2026
@ChristianPavilonis
ChristianPavilonis added this pull request to stack #408 October 6, 2026 21:02

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Axum: enforce configurable buffered request-body limits

1 participant