You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm using FastAPI on Python 3.11 that by default installs uvloop (not asyncio's event-loop). uvloop's underlying_transport doesn't have_start_tls_compatible attribute, but it does have start_tls.
In order to make this code work with proxy I have to do monkey-patch:
importaiohttp# monkey-patch# Save the original ClientSession classOriginalClientSession=aiohttp.ClientSession# Define a patched ClientSession that forces the proxyclassPatchedClientSession(OriginalClientSession):
def__init__(self, *args, **kwargs):
# Always set trust_env=True to honor proxy environment variableskwargs['trust_env'] =Truesuper().__init__(*args, **kwargs)
# Apply the patchaiohttp.ClientSession=PatchedClientSession
Again, I can't change the code above, it is not under my control. Why trust_env has False as default value in the first place? httpx, requests has True by default..._I have created seperated bug #10682 for it.
The problematic code is in aiohttp.connector.TCPConnector class mostly in: _create_proxy_connection() functions.
In my case req.is_ssl() is True (and runtime_has_start_tls is also True), so:
self._warn_about_tls_in_tls(transport, req) is called and misleading warning is printed.
Work-arround:
warnings.filterwarnings(
'ignore',
category=RuntimeWarning,
message=r".*HTTPS request.*through an HTTPS proxy.*TLS\s+in\s+TLS.*"
)
proxy_resp=awaitproxy_req.send(conn) #proxy_resp is instance of `ClientResponse`
...
resp=awaitproxy_resp.start(conn)
Between these lines, if you actually put break-point inside ClientResponse.__init__() after self._cache: Dict[str, Any] = {} line, you will see, surprise, surprise, that self._cache actually has some key-value in it. In particular, it has 'headers':None. This will lead to the following unpredictable behavior in side start().
...
self._headers=message.headers#assignment succeeds
...
ifcookie_hdrs:=self.headers.getall(hdrs.SET_COOKIE, ()): #fails, because it ignores `self._headers` #and used cached value that is None, so `None.getall()`` call raise Exceptions.
headers uses your's custom method descriptor that has some subtle bug, that I wasn't able to identify. So, I'm disabling cache-behavior in the descriptor alltogether.
message.headers are fine. Moreover self._headers are updated.
BUT headers is under_cached_property aka reify.
So, while _headers=message.headers, headers return None, because for some wired reason _cache as {"headers:None} (it has also URL; URL also uses reify, so maybe their share the same cache...).
Moreover, writing monkey-patch to manually remove headers key from _cache failed. I have no idea why.
Its likely headers is being accessed by something sooner than expected so it gets cached to None. We need to figure out where thats happening to prevent it
Describe the bug
I'm using Fiddler as local Proxy Server
This code is in some 3rd-party library:
.env
I'm using FastAPI on Python 3.11 that by default installs uvloop (not asyncio's event-loop). uvloop's underlying_transport doesn't have
_start_tls_compatible
attribute, but it does havestart_tls
.In order to make this code work with proxy I have to do monkey-patch:
Again, I can't change the code above, it is not under my control. Why
trust_env
has False as default value in the first place?httpx
,requests
has True by default..._I have created seperated bug #10682 for it.The problematic code is in
aiohttp.connector.TCPConnector
class mostly in:_create_proxy_connection()
functions.In my case
req.is_ssl()
is True (andruntime_has_start_tls
is also True), so:self._warn_about_tls_in_tls(transport, req)
is called and misleading warning is printed.Work-arround:
I've opened #10683 as separated bug,
_create_proxy_connection()
functions:Between these lines, if you actually put break-point inside
ClientResponse.__init__()
afterself._cache: Dict[str, Any] = {}
line, you will see, surprise, surprise, thatself._cache
actually has some key-value in it. In particular, it has 'headers':None. This will lead to the following unpredictable behavior in sidestart()
.headers uses your's custom method descriptor that has some subtle bug, that I wasn't able to identify. So, I'm disabling cache-behavior in the descriptor alltogether.
Work-arround:
Python Version
aiohttp Version
multidict Version
propcache Version
yarl Version
OS
python:3.11-slim
Related component
Client
Additional context
No response
Code of Conduct
The text was updated successfully, but these errors were encountered: