Skip to content

base_url with a query string produces malformed request URLs #1236

Description

@lesnik512

A base_url that contains a query string is not rejected, but every relative request built from it has a broken URL. Reproduced on httpx2 2.13.1:

import httpx2

client = httpx2.Client(base_url="https://example.com/api?key=k")
print(repr(client.base_url))
# URL('https://example.com/api?key=k/')

print(client.build_request("GET", "items").url)
# https://example.com/api?key=k/items

print(client.build_request("GET", "items", params={"b": "2"}).url)
# https://example.com/api?b=2

In the first request the path ends up inside the query (key becomes k/items). In the second the path items is lost entirely. No error is raised in either case, so the request silently goes to the wrong URL.

Cause

Both steps operate on raw_path, which includes the query:

  • _enforce_trailing_slash (_client.py) appends / to url.raw_path, so the slash lands after the query: /api?key=k/.
  • _merge_url builds self.base_url.raw_path + merge_url.raw_path.lstrip(b"/"), so the request path is appended after the query too.

The second case then loses the path because params= replaces the whole query (#905), and the query now holds the path.

Possible fixes

  1. Reject a base_url with a query string in the base_url setter, with a message pointing to params=.
  2. Support it: operate on path rather than raw_path in both places and merge the base query into the request's params.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions