Conversation
Brownian Motion (Brass)Recommendation: Proceed Summary: PR effectively addresses unnecessary headers in HeadObject requests. Highlights
Next actions
Reflection questions
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe PR prevents ChangesHeadObject Header Omission
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 6/8 reviews remaining, refill in 14 minutes and 1 second.Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
s3/src/request/blocking.rs (1)
244-267: 💤 Low valueLGTM — test covers all three specified objectives cleanly.
The three assertions correctly validate: (1)
Content-LengthandContent-Typeabsent from the requestHeaderMap, (2)x-amz-content-sha256still present, and (3) both fields excluded from theSignedHeaderscomponent of theAuthorizationheader.One optional hardening: the
signed_headers.contains("content-type")substring check would produce a false negative if a future signed header happened to embed"content-type"in its name. Splitting on';'and doing exact-field comparison is marginally more precise:🔍 Optional: exact-field SignedHeaders assertion
-assert!(!signed_headers.contains("content-length")); -assert!(!signed_headers.contains("content-type")); +let signed_header_list: Vec<&str> = signed_headers.split(';').collect(); +assert!(!signed_header_list.contains(&"content-length")); +assert!(!signed_header_list.contains(&"content-type"));No action needed — the current form is safe given the actual header names involved.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@s3/src/request/blocking.rs` around lines 244 - 267, The test head_object_omits_body_headers_from_request_and_signature should verify signed headers by exact field names instead of substring checks; update the Authorization parsing in that test (authorization, signed_headers) so after extracting the SignedHeaders value you split it on ';' (SignedHeaders are semicolon-separated) into discrete header tokens and assert that none of the tokens equals "content-length" or "content-type" (rather than using signed_headers.contains(...)), keeping the rest of the test (headers checks and x-amz-content-sha256) the same.s3/src/request/request_trait.rs (1)
708-726: ⚖️ Poor tradeoffLGTM — correct minimal fix for the no-body-headers oversight.
The
Command::HeadObject => {}arm cleanly preventsCONTENT_LENGTH/CONTENT_TYPEfrom being inserted or signed, matching the same pattern already used forGetObject.Worth noting as a follow-up: several other bodyless commands (
DeleteObject,AbortMultipartUpload,GetObjectRange,GetObjectTorrent,PresignGet,PresignDelete) still fall through to the_arm and silently acquireContent-Length: 0/Content-Type: text/plain. These haven't triggered proxy failures yet, but the underlying inconsistency remains. A futureCommand::has_body()predicate (as noted in the PR description regarding PR#452) would resolve all of them uniformly.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@s3/src/request/request_trait.rs` around lines 708 - 726, The match in request_trait.rs currently special-cases HeadObject to avoid inserting CONTENT_LENGTH/CONTENT_TYPE but several other bodyless commands (e.g., DeleteObject, AbortMultipartUpload, GetObjectRange, GetObjectTorrent, PresignGet, PresignDelete) still fall through and get Content-Length: 0 / Content-Type: text/plain; update the match on self.command() (or implement and call a Command::has_body() predicate) so that all bodyless variants are handled like HeadObject (add explicit arms for DeleteObject, AbortMultipartUpload, GetObjectRange, GetObjectTorrent, PresignGet, PresignDelete to skip inserting CONTENT_LENGTH and CONTENT_TYPE, or replace the current logic with if self.command().has_body() { insert CONTENT_LENGTH/CONTENT_TYPE using self.command().content_length() / content_type() }).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@s3/src/request/blocking.rs`:
- Around line 244-267: The test
head_object_omits_body_headers_from_request_and_signature should verify signed
headers by exact field names instead of substring checks; update the
Authorization parsing in that test (authorization, signed_headers) so after
extracting the SignedHeaders value you split it on ';' (SignedHeaders are
semicolon-separated) into discrete header tokens and assert that none of the
tokens equals "content-length" or "content-type" (rather than using
signed_headers.contains(...)), keeping the rest of the test (headers checks and
x-amz-content-sha256) the same.
In `@s3/src/request/request_trait.rs`:
- Around line 708-726: The match in request_trait.rs currently special-cases
HeadObject to avoid inserting CONTENT_LENGTH/CONTENT_TYPE but several other
bodyless commands (e.g., DeleteObject, AbortMultipartUpload, GetObjectRange,
GetObjectTorrent, PresignGet, PresignDelete) still fall through and get
Content-Length: 0 / Content-Type: text/plain; update the match on self.command()
(or implement and call a Command::has_body() predicate) so that all bodyless
variants are handled like HeadObject (add explicit arms for DeleteObject,
AbortMultipartUpload, GetObjectRange, GetObjectTorrent, PresignGet,
PresignDelete to skip inserting CONTENT_LENGTH and CONTENT_TYPE, or replace the
current logic with if self.command().has_body() { insert
CONTENT_LENGTH/CONTENT_TYPE using self.command().content_length() /
content_type() }).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 34932619-66ec-4855-9d78-b3e45972ff9c
📒 Files selected for processing (2)
s3/src/request/blocking.rss3/src/request/request_trait.rs
49b7980 to
8c08a2c
Compare
Brownian Motion (Brass)Recommendation: Proceed Summary: PR effectively addresses unnecessary headers in HEAD requests. Highlights
Next actions
Reflection questions
|
|
Thanks for the focused fix. This keeps the header/signing change narrow: Verification before merge:
Merging this as the fix for #450. |
Linked issue
Fixes #450.
Problem
Bucket::head_objectbuilds its request through the common request header path. The generic fallback branch addedContent-Length: 0andContent-Type: text/plainfor commands that are not explicitly exempted.GetObjectwas exempted, butHeadObjectwas not, so HEAD requests emitted and signed unnecessary body headers.Solution
Add
Command::HeadObjectto the same narrow no-body-header branch used byGetObject/listing-style commands. This avoids PR #452's broaderhas_body()style change and leaves upload, multipart initiation/completion, GCS-related multipart paths, and other body-bearing commands untouched.Focused verification
cargo test -p rust-s3 --no-default-features --features sync head_object_omits_body_headers_from_request_and_signature -- --nocapturecargo test -p rust-s3 --no-default-features --features sync request::blocking::tests -- --nocapturehead_object_omits_body_headers_from_request_and_signaturetest passed. The failures assert path-style host behavior and are unrelated to HeadObject/body headers.Risk notes
content-lengthandcontent-type; regression coverage asserts those headers are absent both from the request and fromSignedHeaderswhile preservingx-amz-content-sha256.This change is
Summary by CodeRabbit
Bug Fixes
Tests