fix: bound buffered-op body size and fail closed on classifier over-match#102
Merged
Conversation
…atch Review follow-ups on the cross-request body-I/O change: - handle_request now runs the header-only check_upload_size before the eager pre-read of buffered ops, restoring the pre-read size rejection. Without it an oversized batch DeleteObjects was fully materialized before being rejected, and the multipart-control ops had no size bound at all. - The Forward arm fails closed with a 500 instead of panicking via expect() if op_needs_buffered_body ever over-matches an op that dispatches to Forward (the body would already be taken by the pre-read). Mirrors the under-match path. - Comment accuracy: the FixedLengthStream PUT branch streams but is not zero-copy (chunks cross the transform boundary), and the dropped pipe promise surfaces failures via the awaited outbound fetch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
🚀 Latest commit deployed to https://multistore-proxy-pr-102.development-seed.workers.dev
|
Dedupes the error_response + maybe_inject_server_timing + return idiom that the buffered-op size guard, the body-read failure, and the body-already-consumed guard each repeated. No behavior change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-ups to #100 (merged as
60b4278), from a code review of that change. Two small correctness fixes plus comment accuracy.1. Bound the buffered-op body before the eager pre-read
#100 moved the body read for buffered ops (multipart control + batch delete) to the top of
handle_request, ahead ofresolve— but that's also ahead ofdispatch_operation'scheck_upload_size. So an oversized declaredContent-Lengthwas fully materialized into memory before being rejected, and the three multipart-control ops (which never callcheck_upload_size) had no size bound at all. Pre-#100, the header-only guard fired before any bytes were read.This restores that ordering: run the header-only
check_upload_sizein theop_needs_buffered_bodybranch, beforecollect_body.2. Fail closed instead of panic on classifier over-match
op_needs_buffered_bodymust mirror theNeedsBodyarms ofdispatch_operation. The under-match direction already fails closed (aNeedsBodyop the classifier missed returns a clean 500). The over-match direction did not: if a buffered-classified op ever dispatched toForward, the body was already taken by the pre-read andbody.take().expect("streaming op retains its body")would panic (worse on Workers than a 500). TheForwardarm now returns a 500 instead, matching the other direction.Not reachable with today's op set, but it's latent fragility on the same hand-maintained invariant.
3. Comment accuracy
FixedLengthStreamPUT branch streams but is not zero-copy (chunks cross the transform boundary); only the raw-stream branch is.pipe_topromise isn't a silent failure — a pipe error also errorsreadable, so the awaited outbound fetch fails and surfaces it.Tests
Core suite (115) passes. cf-workers is wasm-checked. (Note for maintainers: cf-workers has no executable test coverage —
worker::Fetch's future is!Sendon the host target so the crate doesn't compile natively, and CI onlycargo checks it on wasm32.fixed_body_lengthwould be a clean unit test if that's ever resolved.)Deliberately out of scope (review noted, not done here)
resolve_request_with_metadatainto a sync parse phase + async authorize phase and derive the buffer/stream decision from the single parsedS3Operation. Removes the double-parse, theop_needs_buffered_bodyclassifier, the drift hazard, and the need for fix Support temporary credential generation #2 entirely. Larger refactor — separate PR.Content-Length(currently falls back to the chunked path that hangs).PutObjectdropsx-amz-checksum-*while plainUploadPartnow preserves them — worth reconciling.🤖 Generated with Claude Code