-
Notifications
You must be signed in to change notification settings - Fork 2.3k
fix: resolve URL path truncation in SSE transport for proxied servers #1211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 3 commits
ebd10b3
3d5d6b7
4f3be62
e814ad8
6ac9017
3b9eea0
3a5b42c
eaee780
a2b8a2a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -291,3 +291,34 @@ async def test_sse_security_post_valid_content_type(server_port: int): | |
finally: | ||
process.terminate() | ||
process.join() | ||
|
||
|
||
@pytest.mark.anyio | ||
async def test_endpoint_validation_rejects_absolute_urls(): | ||
"""Test that SseServerTransport properly validates endpoint format.""" | ||
# These should all raise ValueError due to being absolute URLs or having invalid characters | ||
invalid_endpoints = [ | ||
"http://example.com/messages/", | ||
"https://example.com/messages/", | ||
"//example.com/messages/", | ||
"/messages/?query=test", | ||
"/messages/#fragment", | ||
] | ||
|
||
for invalid_endpoint in invalid_endpoints: | ||
with pytest.raises(ValueError, match="is not a relative path"): | ||
SseServerTransport(invalid_endpoint) | ||
|
||
# These should all be valid - endpoint is stored as-is (no automatic normalization) | ||
valid_endpoints_and_expected = [ | ||
("/messages/", "/messages/"), # Absolute path format | ||
("messages/", "messages/"), # Relative path format | ||
("/api/v1/messages/", "/api/v1/messages/"), | ||
("api/v1/messages/", "api/v1/messages/"), | ||
] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here is the behavior demonstrated with examples:
urllib has some odd behavior imo. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe this is the one we want to coerce/enforce:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I’ve made the necessary updates based on your feedback (store endpoint verbatim, remove leading “/” coercion, clarify docs/tests). When you have a moment, could you please take another look? Thank you |
||
|
||
for valid_endpoint, expected_stored_value in valid_endpoints_and_expected: | ||
# Should not raise an exception | ||
transport = SseServerTransport(valid_endpoint) | ||
# Endpoint should be stored exactly as provided (no normalization) | ||
assert transport._endpoint == expected_stored_value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The behavior I saw was:
urllib.join("http://example.com/some/path", "/messages/")
resulted inhttp://example.com/messages
. I think it would be sufficient to just drop the leading forward slash sense that leads to an unexpected behavior. I would argue that the sdk should not be forcing its route to be at any particular location and that a dev should decide where it gets mounted. Relative path joining should allow that. See comment below for test casesThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @mconflitti-pbc! Thanks for reviewing this PR, and apologies for the late reply.
You’re right about the behavior: auto-prepending “/” to “make it relative” actually made the endpoint origin-absolute, which caused urljoin to drop any base path in proxied/subpath setups. This change removes that normalization and stores the endpoint verbatim.
Thanks again for the thoughtful feedback.