Skip to content

Fix: Prevent query parameter corruption in base_url - #3760

Open
veeceey wants to merge 1 commit into
encode:masterfrom
veeceey:fix/issue-3614-base-url-query-corruption
Open

Fix: Prevent query parameter corruption in base_url#3760
veeceey wants to merge 1 commit into
encode:masterfrom
veeceey:fix/issue-3614-base-url-query-corruption

Conversation

@veeceey

@veeceey veeceey commented Feb 8, 2026

Copy link
Copy Markdown

Summary

Fixes #3614

When a base_url contains query parameters, the trailing slash enforcement was corrupting the query parameter values by appending the slash to the query string instead of just the path.

Problem

client = httpx.Client(base_url="https://api.com/get?data=1")
print(client.base_url.query)  
# Before: b'data=1/' ❌ (corrupted!)
# After:  b'data=1'  ✅ (correct)

The _enforce_trailing_slash() method was appending / to the entire raw_path, which includes both the path and query string. For a URL like /get?data=1, this became /get?data=1/, corrupting the query parameter value.

Solution

Modified _enforce_trailing_slash() in _client.py to:

  1. Split raw_path into path and query components (using ? as delimiter)
  2. Add trailing slash only to the path portion
  3. Recombine path and query

Examples

base_url with query parameters:

client = httpx.Client(base_url="https://api.com/get?data=1")
# Before: https://api.com/get?data=1/  (corrupted)
# After:  https://api.com/get/?data=1  (correct)

base_url with trailing slash and query:

client = httpx.Client(base_url="https://api.com/get/?key=value")
# Result: https://api.com/get/?key=value  (no double slash)

base_url without query (unchanged behavior):

client = httpx.Client(base_url="https://api.com/get")
# Result: https://api.com/get/  (trailing slash added as before)

Testing

  • ✅ Manual testing with various base_url configurations
  • ✅ Added regression tests in tests/client/test_client.py
  • ✅ Verified backward compatibility with existing behavior
@veeceey

veeceey commented Feb 8, 2026

Copy link
Copy Markdown
Author

All CI passing on Python 3.9-3.13, ready for merge

@veeceey

veeceey commented Feb 19, 2026

Copy link
Copy Markdown
Author

Friendly ping - any chance someone could take a look at this when they get a chance? Happy to make any changes if needed.

…ement

When a base_url contained query parameters, _enforce_trailing_slash() was
appending a slash to the entire raw_path (including the query string), which
corrupted the query parameter values.

For example:
- Before: base_url="https://api.com?data=1" became "https://api.com?data=1/"
  (query param corrupted to "data=1/" instead of "data=1")
- After: base_url="https://api.com?data=1" becomes "https://api.com/?data=1"
  (query param correctly preserved as "data=1")

The fix splits the raw_path into path and query components, adds the trailing
slash only to the path portion, then recombines them.

Fixes #3614
@veeceey
veeceey force-pushed the fix/issue-3614-base-url-query-corruption branch from 2fba056 to b2adc52 Compare March 10, 2026 13:08
@lovelydinosaur

Copy link
Copy Markdown
Member

Heya... thanks for this.

Development of the next version is shifting across to a rewrite.
I'll communicate about this more fully in due course.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants