fix(dispatch): stop misreading list/dict handler returns as raw bytes/wrong status - #233
Merged
Merged
Conversation
…/wrong status
map_handler_return() tried extract::<Vec<u8>>() before checking for a
plain dict/list. pyo3 happily extracts any Python sequence of small
ints as Vec<u8> - including an empty list - so `return []` sent an
empty application/octet-stream body instead of JSON `[]`, and
`return [1, 2, 3]` sent raw bytes \x01\x02\x03 instead of JSON
`[1,2,3]`.
Separately, any dict containing both a "status" and "body" key was
unconditionally treated as a structured HTTP response, so ordinary
JSON data shaped that way (e.g. {"status": 1, "body": "x"}) had its
HTTP status silently set to 1 instead of being returned as data.
Fix:
- Check for PyDict/PyList before the String/Vec<u8> extraction
attempts, so JSON payloads always fall through to JSON
serialization instead of being coerced to bytes.
- Require "status" to be a plausible HTTP status code (100-599,
RFC 9110 Sec 15) before treating a dict as a structured response,
preserving the existing documented {"status": ..., "body": ...}
shorthand (docs/usage.md, tests/test_exception_handlers.py) for
real status codes while letting ambiguous data round-trip as JSON.
Closes #211
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.
Problem
map_handler_return()triedextract::<Vec<u8>>()before checking for a plaindict/list. pyo3 happily extracts any Python sequence of small ints asVec<u8>— including an empty list — so:return []sent an emptyapplication/octet-streambody instead of JSON[].return [1, 2, 3]sent raw bytes\x01\x02\x03instead of JSON[1,2,3].Separately, any
dictcontaining both astatusandbodykey was unconditionally treated as a structured HTTP response — so ordinary JSON data shaped that way (e.g.{"status": 1, "body": "x"}) had its HTTP status silently set to1instead of being returned as data.Fix
PyDict/PyListbefore theString/Vec<u8>extraction attempts, so JSON payloads always fall through to JSON serialization instead of being coerced to bytes.statusto be a plausible HTTP status code (100-599, RFC 9110 §15) before treating a dict as a structured response — preserves the existing documented{"status": ..., "body": ...}shorthand (docs/usage.md,tests/test_exception_handlers.py) for real status codes, while letting ambiguous data round-trip as JSON.Testing
New
tests/test_handler_return_mapping.py:test_empty_list_is_json_not_octet_streamtest_int_list_is_json_not_raw_bytestest_dict_with_out_of_range_status_roundtrips_as_datatest_dict_with_valid_status_and_body_is_still_a_structured_response(confirms the documented shorthand still works)cargo build --lib/cargo clippy --all-targets: clean.cargo test --lib: 26 passed.Full suite: 168 passed (164 + 4 new), 1 skipped.
ruff check/ruff format --check: clean.Closes #211