websockets icon indicating copy to clipboard operation
websockets copied to clipboard

Add support for HTTP(S) proxies to connect()

Open youngkylejan opened this issue 6 years ago • 29 comments

how to make the websocket connection go through with http proxy?

youngkylejan avatar Mar 19 '18 15:03 youngkylejan

Are you making connections with connect or receiving connections with serve?

aaugustin avatar Mar 23 '18 08:03 aaugustin

yep. for example, i want there exists function like websockets.connect('host', http_proxy_host='proxy_host', http_proxy_port=port)

because my running environment is in the mainland of china where limits connections to lots of hosts overseas. I have to make websocket connections through my socks5 proxy which communicates with shadowsocksR server.

youngkylejan avatar Mar 23 '18 08:03 youngkylejan

OK. This isn't currently implemented.

aaugustin avatar Mar 24 '18 12:03 aaugustin

This feature request is for implemting: https://tools.ietf.org/html/rfc7231#section-4.3.6

We must take care of handling TLS properly:

  • connect with or without TLS to the proxy
  • connect with or without TLS to the destination

This may require handling the TLS handshake manually where asyncio currently handles it.

aaugustin avatar Mar 24 '18 13:03 aaugustin

I have a patch that manages the four cases: TLS / not TLS between client and proxy / proxy and server.

The patch needs tests and I'm not sure how to write them.

aaugustin avatar Jun 02 '18 16:06 aaugustin

TLS between proxy and server is very messy due to https://bugs.python.org/issue23749

Also we're likely to run into issues like https://github.com/aio-libs/aiosmtpd/issues/83 until we add code to handle that.

aaugustin avatar Jun 02 '18 16:06 aaugustin

According to https://bugs.python.org/issue23749 the bug was fixed as of 2018-05-28. Might be worth retaking a look at? @aaugustin

bird avatar Aug 20 '18 20:08 bird

I can consider that bug resolved after I drop support for all Python versions before 3.7, about five years from now.

aaugustin avatar Aug 21 '18 05:08 aaugustin

Any news?

Yevgnen avatar Sep 10 '18 06:09 Yevgnen

No.

aaugustin avatar Sep 10 '18 12:09 aaugustin

Would supporting only client proxies to which you connect over HTTP be any easier? From the discussion above, it looks like the difficulties were all when connecting to the proxy over HTTPS.

I ask because, at least as I understand it, an proxy to which you connect over HTTP is still pretty secure, even when you're using it to ultimately connect to a site over HTTPS. The pattern is:

Client makes an HTTP connection to the proxy and sends a message like

CONNECT something.com:443 HTTP/1.1

The proxy, if it's happy to proxy the request, and is able to connect to that host on that port, replies

HTTP/1.1 200 Connection established

...and then the proxy just forwards data blindly down the pipe. The data that is sent and received can be TLS (or indeed SSH or any other TCP-based protocol).

It's worth noting that everything is reasonably secure. The only information that is sent in the clear from the client to the proxy is the port number (which is effectively in the clear for all TCP connections anyway) and the hostname, which TLS handshakes already send in the clear via the SNI field.

It's possible (or perhaps likely) that I'm missing something important here, though.

gpjt avatar Dec 07 '18 20:12 gpjt

Partial support would be better than no support at all, indeed.

However, since there's a working PoC in #422 that does what you said and is merely missing error handling and tests, once it's complete for HTTP proxies, I don't think it would be very hard to also complete it for HTTP proxies.

aaugustin avatar Dec 08 '18 09:12 aaugustin

For anyone still looking for this, I recommend using the websocket-client library, which has supported proxies since 2014 and works perfectly. I honestly find the fact that this issue has been open for 3 years and has a "funding needed" label laughable. Why exactly do you need funding for such a simple feature? This is just an incredibly distasteful attempt at a cash grab. It would have been far better to say something like "I'm not willing to spend time on this, but PRs are welcome".

0xallie avatar Oct 29 '21 17:10 0xallie

@nyuszika7h Proxies are a pain. If you find this laughable easy, then just make a PR. PRs are always welcome. The only thing distasteful here is your comment.

lgrahl avatar Oct 29 '21 17:10 lgrahl

I didn't say HTTPS proxies are trivial, but definitely not the kind of thing you need to beg for funding for. There's plenty of prior art to look at.

0xallie avatar Oct 29 '21 17:10 0xallie

"The community house in this area could use some cleaning. Are you available tomorrow? Don't ask for payment though, cleaning has already been done to other community houses in the past."

lgrahl avatar Oct 29 '21 23:10 lgrahl

It would have been far better to say something like "I'm not willing to spend time on this, but PRs are welcome".

@nyuszika7h This is basically what the last comment before yours said — glad to see that we agree on this1

aaugustin avatar Oct 30 '21 05:10 aaugustin

watching this, any update?

weaming avatar Apr 29 '22 07:04 weaming

I can consider that bug resolved after I drop support for all Python versions before 3.7, about five years from now.

Hello from 2023! I see this comment was made in 2018 :) And also noticed support for Python versions older than 3.7 was dropped in version 10.0, any plans to add this soon? I love the async features of this library and wouldn't want to switch to something else.

kyochikuto avatar Jun 05 '23 14:06 kyochikuto

Good job following up :-) No specific plans in this area at the time being, though.

aaugustin avatar Jun 05 '23 18:06 aaugustin

@kyochikuto @weaming hey. You can check out my package: https://github.com/racinette/websockets_proxy . I subclassed the original connect and added to it the functionality by using a third party asyncio proxy connection package.

racinette avatar Dec 21 '23 10:12 racinette

Nic job! Although I'm not writing Python code now. You guys can try this.

weaming avatar Dec 22 '23 05:12 weaming

I can consider that bug resolved after I drop support for all Python versions before 3.7, about five years from now.

Five years have passed.

Maxhem2 avatar Jan 05 '24 15:01 Maxhem2

Yes, that obstacle no longer exists.

aaugustin avatar Jan 05 '24 22:01 aaugustin

You can check out my package: https://github.com/racinette/websockets_proxy . I subclassed the original connect and added to it the functionality by using a third party asyncio proxy connection package.

I just tested this and it's working flawlessly, really appreciate it! I love how it is only a wrapper around the original module and not a modified fork, this way you can easily keep it updated with the original module.

Keep up the good job!

kyochikuto avatar Jan 08 '24 11:01 kyochikuto

@kyochikuto thanks man, appreciate it.

It can be used as drop-in replacement via monkey-patching, in case some other package using websockets needs proxy access. I didn't consider it for now, but I can extend the module, if the community needs it.

Also, please, do star the repo, so I can gain recognition.

racinette avatar Jan 08 '24 12:01 racinette

It can be used as drop-in replacement via monkey-patching, in case some other package using websockets needs proxy access. I didn't consider it for now, but I can extend the module, if the community needs it.

Drop-in replacements are always preferred, thanks!

Also, please, do star the repo, so I can gain recognition.

Done!

kyochikuto avatar Jan 08 '24 12:01 kyochikuto