Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions httpx/_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,19 @@ def trust_env(self) -> bool:
return self._trust_env

def _enforce_trailing_slash(self, url: URL) -> URL:
if url.raw_path.endswith(b"/"):
return url
return url.copy_with(raw_path=url.raw_path + b"/")
# Split raw_path into path and query to avoid corrupting query parameters
raw_path = url.raw_path
if b"?" in raw_path:
# URL has query parameters - only check/add slash to path portion
path, query = raw_path.split(b"?", 1)
if path.endswith(b"/"):
return url
return url.copy_with(raw_path=path + b"/?" + query)
else:
# No query parameters - check/add slash to entire raw_path
if raw_path.endswith(b"/"):
return url
return url.copy_with(raw_path=raw_path + b"/")

def _get_proxy_map(
self, proxy: ProxyTypes | None, allow_env_proxies: bool
Expand Down
33 changes: 33 additions & 0 deletions tests/client/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -460,3 +460,36 @@ def cp1252_but_no_content_type(request):
assert response.reason_phrase == "OK"
assert response.encoding == "ISO-8859-1"
assert response.text == text


def test_base_url_with_query_params():
"""
Test that base_url with query parameters doesn't corrupt the query values.

Regression test for issue #3614.
"""
client = httpx.Client(base_url="https://example.com/api?data=1")

# Query parameter should not be corrupted with trailing slash
assert client.base_url.query == b"data=1"
assert str(client.base_url) == "https://example.com/api/?data=1"


def test_base_url_with_trailing_slash_and_query():
"""
Test that base_url with existing trailing slash and query params works correctly.
"""
client = httpx.Client(base_url="https://example.com/api/?key=value")

assert client.base_url.query == b"key=value"
assert str(client.base_url) == "https://example.com/api/?key=value"


def test_base_url_with_multiple_query_params():
"""
Test that base_url with multiple query parameters works correctly.
"""
client = httpx.Client(base_url="https://example.com/api?a=1&b=2&c=3")

assert client.base_url.query == b"a=1&b=2&c=3"
assert str(client.base_url) == "https://example.com/api/?a=1&b=2&c=3"