qwj / python-proxy

HTTP/HTTP2/HTTP3/Socks4/Socks5/Shadowsocks/ShadowsocksR/SSH/Redirect/Pf TCP/UDP asynchronous tunnel proxy implemented in Python 3 asyncio.
MIT License
1.93k stars 323 forks source link

Initial HTTP CONNECT and GET requests fail on 3.11.x, but work on 3.10.x and below #161

Open rlaphoenix opened 1 year ago

rlaphoenix commented 1 year ago

The following is the log when running on Python 3.11.2:

$ python -m pproxy -r "http+ssl://uk2144.nordvpn.com:89#user:pass" --test "https://ipinfo.io/json" -d -v
============ uk2144.nordvpn.com:89 ============
 from 194.35.x.x
Traceback (most recent call last):
  File "C:\Program Files\Python311\Lib\asyncio\tasks.py", line 490, in wait_for
    return fut.result()
           ^^^^^^^^^^^^
  File "C:\Program Files\Python311\Lib\asyncio\streams.py", line 637, in readuntil
    await self._wait_for_data('readuntil')
  File "C:\Program Files\Python311\Lib\asyncio\streams.py", line 522, in _wait_for_data
    await self._waiter
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\x\AppData\Roaming\Python\Python311\site-packages\pproxy\server.py", line 860, in test_url
    reader, writer = await roption.prepare_connection(reader, writer, host_name, port)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\x\AppData\Roaming\Python\Python311\site-packages\pproxy\server.py", line 297, in prepare_connection
    await self.rproto.connect(reader_remote=reader_remote, writer_remote=writer_remote, rauth=self.auth, host_name=whost, port=wport, writer_cipher_r=writer_cipher_r, myhost=self.host_name, sock=writer_remote.get_extra_info('socket'))
  File "C:\Users\x\AppData\Roaming\Python\Python311\site-packages\pproxy\proto.py", line 333, in connect
    await reader_remote.read_until(b'\r\n\r\n')
  File "C:\Program Files\Python311\Lib\asyncio\tasks.py", line 492, in wait_for
    raise exceptions.TimeoutError() from exc
TimeoutError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Users\x\AppData\Roaming\Python\Python311\site-packages\pproxy\__main__.py", line 3, in <module>
    main()
  File "C:\Users\x\AppData\Roaming\Python\Python311\site-packages\pproxy\server.py", line 912, in main
    asyncio.get_event_loop().run_until_complete(test_url(args.test, args.rserver))
  File "C:\Program Files\Python311\Lib\asyncio\base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "C:\Users\x\AppData\Roaming\Python\Python311\site-packages\pproxy\server.py", line 863, in test_url
    raise Exception('Unknown remote protocol')
Exception: Unknown remote protocol

And the following is the exact same call through Python 3.10.9 on the same system:

python -m pproxy -r "http+ssl://uk2144.nordvpn.com:89#user:pass" --test "https://ipinfo.io/json" -d -v
============ uk2144.nordvpn.com:89 ============
HTTP/1.1 200 OK
access-control-allow-origin: *
x-content-type-options: nosniff
content-type: application/json; charset=utf-8
content-length: 244
date: Fri, 03 Mar 2023 06:11:15 GMT
x-envoy-upstream-service-time: 2
strict-transport-security: max-age=2592000; includeSubDomains
vary: Accept-Encoding
Via: 1.1 google
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
Connection: close
--------------------------------
{
  "ip": "178.238.x.x",
  "city": "London",
  "region": "England",
  "country": "GB",
  "loc": "x,-x",
  "org": "x",
  "postal": "x",
  "timezone": "Europe/London",
  "readme": "https://ipinfo.io/missingauth"
}
============ success ============

You can see it's failing on the initial GET request where it reads until it finds \r\n\r\n.

Tested:

So it seems like Python 3.11.0a6 introduced an issue. If I install 3.11.0a6, and overwrite the Lib/asyncio folder with the one from 3.11.0a5, it works.

After further testing if I overwrite just the Lib/asyncio/sslproto.py file with the one from 3.11.0a5, it works. So the error is there somewhere.

Jonney commented 1 year ago

Fixed, waiting for merge.

163