Fix base_url query parameters being corrupted during URL merging
When base_url contains query parameters (e.g. "https://example.com/get?data=1"), _enforce_trailing_slash() appended "/" to raw_path which includes the query string, corrupting "?data=1" into "?data=1/". Similarly, _merge_url() concatenated paths without separating the query string from the path component. Fix both methods to split raw_path at "?" before manipulating the path, then rejoin with the query string intact. Fixes #3614 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
ae1b9f6623
commit
18927fa8e8
@ -232,9 +232,15 @@ class BaseClient:
|
||||
return self._trust_env
|
||||
|
||||
def _enforce_trailing_slash(self, url: URL) -> URL:
|
||||
if url.raw_path.endswith(b"/"):
|
||||
raw_path = url.raw_path
|
||||
if b"?" in raw_path:
|
||||
path_part, query_part = raw_path.split(b"?", 1)
|
||||
if path_part.endswith(b"/"):
|
||||
return url
|
||||
return url.copy_with(raw_path=path_part + b"/?" + query_part)
|
||||
if raw_path.endswith(b"/"):
|
||||
return url
|
||||
return url.copy_with(raw_path=url.raw_path + b"/")
|
||||
return url.copy_with(raw_path=raw_path + b"/")
|
||||
|
||||
def _get_proxy_map(
|
||||
self, proxy: ProxyTypes | None, allow_env_proxies: bool
|
||||
@ -406,7 +412,19 @@ class BaseClient:
|
||||
# URL('https://www.example.com/subpath/')
|
||||
# >>> client.build_request("GET", "/path").url
|
||||
# URL('https://www.example.com/subpath/path')
|
||||
merge_raw_path = self.base_url.raw_path + merge_url.raw_path.lstrip(b"/")
|
||||
base_raw_path = self.base_url.raw_path
|
||||
if b"?" in base_raw_path:
|
||||
base_path, base_query = base_raw_path.split(b"?", 1)
|
||||
merge_raw_path = (
|
||||
base_path
|
||||
+ merge_url.raw_path.lstrip(b"/")
|
||||
+ b"?"
|
||||
+ base_query
|
||||
)
|
||||
else:
|
||||
merge_raw_path = (
|
||||
base_raw_path + merge_url.raw_path.lstrip(b"/")
|
||||
)
|
||||
return self.base_url.copy_with(raw_path=merge_raw_path)
|
||||
return merge_url
|
||||
|
||||
|
||||
@ -229,6 +229,17 @@ def test_merge_relative_url_with_encoded_slashes():
|
||||
assert request.url == "https://www.example.com/base%2Fpath/testing"
|
||||
|
||||
|
||||
def test_merge_url_with_base_url_query_params():
|
||||
# https://github.com/encode/httpx/issues/3614
|
||||
client = httpx.Client(base_url="https://www.example.com/get?data=1")
|
||||
|
||||
request = client.build_request("GET", "")
|
||||
assert str(request.url) == "https://www.example.com/get/?data=1"
|
||||
|
||||
request = client.build_request("GET", "/users")
|
||||
assert str(request.url) == "https://www.example.com/get/users?data=1"
|
||||
|
||||
|
||||
def test_context_managed_transport():
|
||||
class Transport(httpx.BaseTransport):
|
||||
def __init__(self) -> None:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user