Use with_body instead of with_body_text_plain for JSON responses#529
Use with_body instead of with_body_text_plain for JSON responses#529ChristianPavilonis wants to merge 5 commits intomainfrom
Conversation
aram356
left a comment
There was a problem hiding this comment.
@ChristianPavilonis Please resolve conflicts
The with_body_text_plain method sets Content-Type to text/plain, overriding the APPLICATION_JSON type set by with_content_type. Replace all 6 occurrences in request signing endpoints with with_body which preserves the previously set Content-Type. Closes #424
0fde405 to
4830434
Compare
aram356
left a comment
There was a problem hiding this comment.
Summary
Clean fix for with_body_text_plain() clobbering the Content-Type: application/json header at all 6 JSON response sites. The switch to with_body() is correct. However, the bug remains undetectable by the test suite — a regression test for the Content-Type header is needed.
Blocking
🔧 wrench
- Missing Content-Type assertion in tests: None of the existing tests check the
Content-Typeheader on responses. The bug this PR fixes could silently regress. At least one test should assertresp.get_content_type() == Some(APPLICATION_JSON). (crates/trusted-server-core/src/request_signing/endpoints.rs)
Non-blocking
⛏ nitpick
- PR checklist template mentions "tracing macros": The checklist says "Uses
tracingmacros (notprintln!)" but the project convention islogmacros per CLAUDE.md. Template issue only — the actual code correctly useslog::debug!.
🌱 seedling
- Consider a helper for JSON responses: There are 6 nearly-identical response construction patterns in this file. A small helper like
fn json_response(status: u16, body: &str) -> Responsewould eliminate this class of bug entirely. Not for this PR, but worth considering.
CI Status
- fmt: PASS
- clippy: PASS
- rust tests: PASS
- js tests: PASS
- integration tests: PASS
- browser integration tests: PASS
- CodeQL: PASS
aram356
left a comment
There was a problem hiding this comment.
Summary
Clean, well-scoped bug fix. Correctly identifies that with_body_text_plain() clobbers the Content-Type: application/json header and replaces all 6 occurrences with with_body(). All CI passes.
Non-blocking
🤔 thinking
- Content-Type assertions missing for rotate/deactivate endpoints: The PR adds
get_content_type()assertions to verify signature and discovery tests, but not to the rotate/deactivate key tests (test_handle_rotate_key_with_empty_body,test_handle_deactivate_key_request, etc.). The successfulOk(mut resp)arms in those tests could also assert Content-Type for full coverage of the fix across all 6 response sites.
CI Status
- fmt: PASS
- clippy: PASS
- rust tests: PASS
- js tests: PASS
- integration tests: PASS
- browser integration tests: PASS
- CodeQL: PASS
aram356
left a comment
There was a problem hiding this comment.
Summary
Clean, focused fix for JSON API responses returning Content-Type: text/plain instead of application/json. The with_body_text_plain() method was silently overriding the content type set by with_content_type(APPLICATION_JSON) on the preceding line. Replacing with with_body() preserves the correct header. All 6 response sites fixed, tests added.
Non-blocking
🤔 thinking
- Missing Content-Type assertions in rotate/deactivate tests: Content-Type assertions were added to 3 of 6 response sites (verify valid, verify invalid, discovery). The
test_handle_rotate_key_*andtest_handle_deactivate_key_*tests use amatchpattern where both arms justlog::debug!, so they pass regardless — the fix isn't verified there. Addingassert_eq!(resp.get_content_type(), Some(fastly::mime::APPLICATION_JSON), ...)inside theOkarms would close the gap. (endpoints.rs:440-556)
📌 out of scope
to_error_responseinerror.rsstill useswith_body_text_plain: Returns error messages astext/plain, inconsistent with the structured JSON error responses inendpoints.rs(lines 221, 330) that return{ success: false, error: "..." }on 500s. Separate concern — worth a follow-up for API consistency.
👍 praise
- Minimal, mechanical fix with clear motivation and good test coverage. Commit messages and PR description are excellent.
CI Status
- cargo fmt: PASS
- cargo clippy: PASS
- cargo test: PASS
- vitest: PASS
- integration tests: PASS
- browser integration tests: PASS
- CodeQL: PASS
Summary
Content-Type: text/plaininstead ofapplication/jsonwith_body_text_plain()silently overrides theContent-Typeheader set bywith_content_type(APPLICATION_JSON)on the preceding line, breaking automated clients that check Content-Type before parsingwith_body()which sets the body without clobbering headersChanges
crates/common/src/request_signing/endpoints.rswith_body_text_plain()→with_body()across all 6 response sites (discovery, verify signature, rotate key success/error, deactivate key success/error)Closes
Closes #424
Test plan
cargo test --workspacecargo clippy --all-targets --all-features -- -D warningscargo fmt --all -- --checkcd crates/js/lib && npx vitest runcd crates/js/lib && npm run formatcd docs && npm run formatcargo build --bin trusted-server-fastly --release --target wasm32-wasip1fastly compute serveChecklist
unwrap()in production code — useexpect("should ...")tracingmacros (notprintln!)