fix(lite): return helpful BadPath error for unencoded '/' in stream names - #704
Open
vjymisal0 wants to merge 1 commit into
Open
fix(lite): return helpful BadPath error for unencoded '/' in stream names#704vjymisal0 wants to merge 1 commit into
vjymisal0 wants to merge 1 commit into
Conversation
…ames
Stream names may legitimately contain '/' (e.g. "cdc/products"), but
callers who forget to percent-encode it hit a bare, bodyless 404 from
axum's default unmatched-route handler instead of a diagnosable error.
Add a fallback route scoped to one segment past /streams/{stream} that
returns a BadPath error explaining the fix, without shadowing the more
specific /streams/{stream} and /streams/{stream}/records* routes.
Closes s2-streamstore#635
Signed-off-by: vjymisal0 <vjymisal0@users.noreply.github.com>
Contributor
|
PR author is not in the allowed authors list. |
Author
what do you mean? |
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.
Summary
Closes #635.
Stream names may legitimately contain
/(e.g.cdc/products), but a REST request that forgets to percent-encode it (/v1/streams/cdc/products/recordsinstead of/v1/streams/cdc%2Fproducts/records) resolves to more path segments than any registered route expects. axum's default router rejects that as a bare, bodyless 404 — a head-scratcher, since an encoded-but-nonexistent stream correctly returns a JSONstream_not_foundbody.Fix
Added a fallback route in
lite/src/handlers/v1/streams.rs:This is scoped to one segment past
{stream}rather than/streams/{*rest}directly — registering the wildcard at the same depth as the existing/streams/{stream}route panics at router-build time with a matchit conflict (confirmed locally; see Tests). Scoping it one level deeper lets it coexist: literal children like.../recordsand.../records/tailstill win over the wildcard (more specific routes take priority in matchit), and the bare/streams/{stream}route is untouched since the wildcard requires at least one more segment.Added
ServiceError::AmbiguousStreamPath, mapped to the existingErrorCode::BadPath(400), with a message pointing at percent-encoding — matching the issue's first suggested fix option. I left the second option (documenting the%2Frequirement in the OpenAPI spec / protocol docs) out of this PR to keep the diff focused on the routing behavior; happy to follow up on the docs separately if useful.Tests
lite/src/handlers/v1/streams.rs, newmod tests(following the existing pattern inrecords.rs):unencoded_slash_in_stream_name_returns_helpful_bad_path_error— hits/v1/streams/cdc/products/recordsand asserts a400/bad_pathJSON body containing "percent-encoded".percent_encoded_slash_in_stream_name_reaches_the_records_route— hits/v1/streams/cdc%2Fproducts/recordsand asserts the response is a normal (non-bad_path) JSON error from the records handler, not the bare unmatched-route 404.Both pass locally. Note on the RED step specifically: my first attempt registered the wildcard at
/streams/{*rest}(matching the issue's exact suggested path), which panics withInsertion failed due to conflict with previously registered route: /streams/{stream}— that's what pushed me to the one-segment-deeper scoping above.Verification
cargo test -p s2-lite --lib handlers::v1::streams— 2 passed.cargo clippy -p s2-lite --all-features --lib -- -D warnings --allow deprecated— clean.cargo +nightly fmt -p s2-lite— clean.Ran all three against a local, uncommitted patch to
lite/Cargo.tomlthat disables thetikv-jemallocatordependency on the GNU target — my local Windows toolchain can't link it (unrelatedmingw32-makefailure building jemalloc from source, and separately the MSVC toolchain here fails at the link step on completely unrelated crates likequote/getrandom, before reaching this crate at all — looks like an incomplete local VS Build Tools linker setup, not anything about this change). That Cargo.toml edit is not part of this diff — confirmed withgit diff --statshowing only the two files above.🤖 Generated with the help of Claude Code, reviewed and tested by me before opening.