Skip to content

Fix pass_through with HTTP proxy - #303

Merged
lundberg merged 6 commits into
lundberg:masterfrom
tboerstad:master
Apr 15, 2026
Merged

lundberg merged 6 commits into
lundberg:masterfrom
tboerstad:master

Conversation

@tboerstad

@tboerstad tboerstad commented Jan 10, 2026 •

Copy link
Copy Markdown
Contributor

This PR addresses an issue where pass_through in a proxy environment causes requests to fail:

$ https_proxy=http://proxy:8080 python
>>> with respx.mock:
...     respx.route().pass_through()
...     httpx.get("https://example.com")
httpx.InvalidURL: Invalid port: '8080example.com:443'

When a proxy is configured, httpcore sends a CONNECT request to establish a tunnel. This request uses authority-form URLs (e.g. example.com:443) with no scheme. When respx intercepts this and tries to parse it into an httpx.URL, the parser crashes.

This PR fixes the URL construction in to_httpx_request so that CONNECT requests flow through the normal route matching system. This means CONNECT tunnels can be mocked just like any other request:

with respx.mock:
    respx.route(method="CONNECT").pass_through()
    respx.get("https://foo.bar/").pass_through()
    httpx.Client(proxy="https://proxy:8080").get("https://foo.bar/")

Or mock proxy errors:

with respx.mock:
    respx.route(method="CONNECT").mock(return_value=httpx.Response(407))
    ...

@tboerstad

Copy link
Copy Markdown
Contributor Author

First, thank you for making respx, very neat!

This PR is a compromise, a small implementation which I think could solve a real issue for users, namely using this library behind a proxy. I ran into this myself when using Anthropic web based Claude Code offering, which is behind a proxy.

However this also means mocking the proxy CONNECT request will not work properly, which is not great.
I leave it up to the maintainer to make a decision here, full understanding if this PR is closed instead

@lundberg

lundberg commented Mar 2, 2026 •

Copy link
Copy Markdown
Owner

Thanks for raising the issue @tboerstad, and sorry for the late reply 😅 ..

.. It feels like there should be a better place to address the issue, e.g. where the URL parsing error happens, and let the connect request successfully flow through the respx router and properly be passed through 🤔

i.e. ending up with this being possible ..

respx.route(method="CONNECT").pass_through()

@tboerstad

Copy link
Copy Markdown
Contributor Author

Thank you @lundberg. I agree, that's a better solution.
I've updated this PR with a new approach better matching your suggestion

Comment thread tests/test_api.py Outdated
@lundberg lundberg added the bug Something isn't working label Apr 7, 2026
Comment thread respx/mocks.py Outdated
@codecov

codecov Bot commented Apr 13, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (4dd0eec) to head (12590d1).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff            @@
##            master      #303   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           22        22           
  Lines         2941      2996   +55     
  Branches       200       204    +4     
=========================================
+ Hits          2941      2996   +55     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@lundberg lundberg left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, fix failing workflow jobs and we're good to go!

Btw, you can locally run lint fix, test matrix etc with task command (no args)

Comment thread tests/test_mock.py Outdated
@tboerstad

Copy link
Copy Markdown
Contributor Author

Looks good, fix failing workflow jobs and we're good to go!

Btw, you can locally run lint fix, test matrix etc with task command (no args)

Oops, sorry for the back and forth. It's working locally now, except for a formatter issue with CHANGELOG.md (which this PR didn't touch).

@lundberg

Copy link
Copy Markdown
Owner

.. formatter issue with CHANGELOG.md (which this PR didn't touch).

My bad 😉 .. I've pushed a fix to master, please rebase.

tboerstad and others added 6 commits April 15, 2026 06:22
    Using pass_through fails when behind a proxy (e.g. corporate network
    with http_proxy/https_proxy environment variables):

        $ https_proxy=http://proxy:8080 python
        >>> with respx.mock:
        ...     respx.route().pass_through()
        ...     httpx.get("https://example.com")
        httpx.InvalidURL: Invalid port: 8080example.com:443

    Bypass CONNECT requests in HTTPCoreMocker to allow proxy tunnel
    establishment.
CONNECT requests were silently forwarded to the real transport, so there
was no way to mock proxy tunnel behavior. This parses them into proper
httpx.Request objects so they go through normal route matching like
everything else.
@tboerstad

Copy link
Copy Markdown
Contributor Author

My bad 😉 .. I've pushed a fix to master, please rebase.

Thanks, have rebased, everything is passing locally now.

@lundberg
lundberg merged commit 06091fa into lundberg:master Apr 15, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants