Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed the problem with socket, which might leak when tunnel proxy connection couldn't be establish #223

Merged
merged 8 commits into from
Oct 30, 2020

Conversation

cdeler
Copy link
Member

@cdeler cdeler commented Oct 14, 2020

Fixes encode/httpx#1360

I extracted a tunnel proxy connection establishing into the separated method, and wrapped it by try-except statement, closing the proxy_connection if it's necessary.

Also I added the unit test and a test fixture from encode/httpx#1360 comments

@cdeler
Copy link
Member Author

cdeler commented Oct 14, 2020

In the test case I had to filter out any warnings from encode/httpx#825

The couldn't appear in this test case (as it's run under trio), so I felt free to do that

@cdeler cdeler requested review from a team, florimondmanca and tomchristie October 14, 2020 12:47
@@ -172,33 +172,22 @@ async def _forward_request(

return status_code, headers, wrapped_stream, ext

async def _tunnel_request(
Copy link
Member

Choose a reason for hiding this comment

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

Great stuff! So...

I think the first thing would be to try to get the change footprint of this PR down a bit.

  • I'd suggest we keep a single _tunnel_request method, rather than splitting out into two methods here?
  • Can we catch the exception more narrowly? Perhaps we could have a top-level TransportError class, in the same way as httpx. Then, in cases like this we could just catch TransportError.

Copy link
Member

Choose a reason for hiding this comment

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

Actually thinking about it let's treat that second line item independently of this pull request.

Copy link
Member Author

@cdeler cdeler Oct 16, 2020

Choose a reason for hiding this comment

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

@tomchristie do I understand correctly the plan:

  1. to introduce the root exception for all httpcore exceptions, to name the class TransportError. This change should go in the separate PR
  2. as soon as (1) has been merged, to merge _establish_tunnel_proxy_connection back into _tunnel_request, catching TransportError instead of Exception?

Talking about (2) we can try. But also it means that there are cases (some error conditions) when we do not clean up resources. The conditions are exceptions not inherited by TransportError...

Copy link
Member

Choose a reason for hiding this comment

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

No don't worry about (2) at all. We can think about that some other day.

Copy link
Member Author

Choose a reason for hiding this comment

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

Therefore I'm to just eliminate _establish_tunnel_proxy_connection, moving this code back to _tunnel_request to reduce the PR footprint, yes? (sorry for repeating questions, I want to fully understand you)

Copy link
Member Author

Choose a reason for hiding this comment

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

@tomchristie
I did that, so the PR became significantly smaller (but it's required to compare it ignoring whitespace changes)

Copy link
Member

@florimondmanca florimondmanca left a comment

Choose a reason for hiding this comment

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

Interesting, and a bit fiddly, so I'm being a bit careful :-)

Comment on lines 205 to 206
url = (protocol, b"example.com", port, b"/")
headers = [(b"host", b"example.org")]
Copy link
Member

Choose a reason for hiding this comment

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

Is the host mismatch between url / headers expected? I think this is somewhat related to the block file passed to pproxy. If so, ad assuming the block file is intended to be a list of URL hosts that cannot be requested through the proxy…

  • Should we set the blocked hostname to something more explicit like blockedhost.org?
  • If the different host in url and headers is on purpose and required, add a small comment to explain why?

Copy link
Member Author

Choose a reason for hiding this comment

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

You are right! I missed that the url and header are different, and it might confuse. Moreover the server name is not so clear. I'm renaming this host to "blockedhost.example.com" (and changing the fixture the same way)

tests/async_tests/test_interfaces.py Outdated Show resolved Hide resolved
ssl_context=self._ssl_context,
socket=proxy_connection.socket,
)
await self._add_to_pool(connection, timeout)
Copy link
Member

Choose a reason for hiding this comment

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

Do we want to explicitly put this operation outside the try/except block? I assume the only operations that we want to fail upon is socket-related stuff, so proxy_connection.arequest() and proxy_connection.start_tls(). Anything that's not related to it, such as adding to the pool, should be left outside the block, correct?

Copy link
Member Author

@cdeler cdeler Oct 17, 2020

Choose a reason for hiding this comment

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

Yes, you are right, the try-except block should be as narrow as possible



@contextlib.contextmanager
def create_proxy_block_file(blocked_domains: List[str]):
Copy link
Member

Choose a reason for hiding this comment

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

I'd suggest we add a small docstring here with any relevant docs material from pproxy (eg a link to relevant docs) describing what a "block file" is and what effect it has?

Copy link
Member Author

Choose a reason for hiding this comment

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

I added some docs to http_proxy_server and create_proxy_block_file

cdeler and others added 2 commits October 17, 2020 19:30
- renamed the blocked host to blockedhost.example.com
- added some docs to http_proxy_server fixture
Co-authored-by: Florimond Manca <florimond.manca@gmail.com>
Co-authored-by: Florimond Manca <florimond.manca@gmail.com>
@cdeler
Copy link
Member Author

cdeler commented Oct 17, 2020

@florimondmanca
Thank you for the review, I fixed all you mentioned

@cdeler cdeler requested a review from a team October 21, 2020 08:39
Copy link
Member

@florimondmanca florimondmanca left a comment

Choose a reason for hiding this comment

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

Rad :) Great one!

@cdeler cdeler merged commit 62b4731 into encode:master Oct 30, 2020
@cdeler cdeler deleted the fix-leaked-socket branch October 30, 2020 08:38
@florimondmanca florimondmanca mentioned this pull request Nov 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

connection leaking in some network condition
4 participants