Repository navigation
closedResourceError intermittently when using httpx asyncclient to send the request #2337
Description
we are observing closedResourceError when sending multiple requests using httpx async client. httpx version used is 0.19.0. is this issue known and fixed in any later version?
Logs:
resp = await asyncio.gather(*[self.async_send_request(method,self.dest_host,self.dest_port,uri,i,payload=payload,headers=headers) for i in range(int(times) )])
File "/env/lib64/python3.9/site-packages/ocnftest_lib/scp_Pcf_client.py", line 175, in async_send_request
return await self.conn.request(method,"http://{}:{}{}".format(self.dest_host,self.dest_port,uri),data=payload,headers=headers,allow_redirects=False)
File "/env/lib64/python3.9/site-packages/httpx/_client.py", line 1494, in request
response = await self.send(
File "/env/lib64/python3.9/site-packages/httpx/_client.py", line 1586, in send
response = await self._send_handling_auth(
File "/env/lib64/python3.9/site-packages/httpx/_client.py", line 1616, in _send_handling_auth
response = await self._send_handling_redirects(
File "/env/lib64/python3.9/site-packages/httpx/_client.py", line 1655, in _send_handling_redirects
response = await self._send_single_request(request, timeout)
File "/env/lib64/python3.9/site-packages/httpx/_client.py", line 1699, in _send_single_request
) = await transport.handle_async_request(
File "/env/lib64/python3.9/site-packages/httpx/_transports/default.py", line 281, in handle_async_request
) = await self._pool.handle_async_request(
File "/env/lib64/python3.9/site-packages/httpcore/_async/connection_pool.py", line 234, in handle_async_request
response = await connection.handle_async_request(
File "/env/lib64/python3.9/site-packages/httpcore/_async/connection.py", line 148, in handle_async_request
return await self.connection.handle_async_request(
File "/env/lib64/python3.9/site-packages/httpcore/_async/http2.py", line 165, in handle_async_request
return await h2_stream.handle_async_request(
File "/env/lib64/python3.9/site-packages/httpcore/_async/http2.py", line 339, in handle_async_request
await self.send_headers(method, url, headers, has_body, timeout)
File "/env/lib64/python3.9/site-packages/httpcore/_async/http2.py", line 398, in send_headers
await self.connection.send_headers(self.stream_id, headers, end_stream, timeout)
File "/env/lib64/python3.9/site-packages/httpcore/_async/http2.py", line 274, in send_headers
await self.socket.write(data_to_send, timeout)
File "/env/lib64/python3.9/site-packages/httpcore/_backends/anyio.py", line 77, in write
return await self.stream.send(data)
File "/env/lib64/python3.9/site-packages/anyio/_backends/_asyncio.py", line 1116, in send
raise ClosedResourceError
anyio.ClosedResourceError
Sample code:
async def send_request(self,payload,times,method,uri,headers):
resp = await asyncio.gather(*[self.async_send_request(method,self.dest_host,self.dest_port,uri,i,payload=payload,headers=headers) for i in range(int(times) )])
await self.conn.aclose()
log.logger.info("[+] @{} {} {}".format(method,resp[int(times)-1].status_code,uri))
return resp[int(times)-1]
async def async_send_request(self,method,dest_host,dest_port,uri,times,payload=None,headers=None):
if self.security == 'secure':
return await self.conn.request(method,"https://{}:{}{}".format(self.dest_host,self.dest_port,uri),data=payload,headers=headers,allow_redirects=False)
else:
return await self.conn.request(method,"http://{}:{}{}".format(self.dest_host,self.dest_port,uri),data=payload,headers=headers,allow_redirects=False)
def send_message:
self.conn = httpx.AsyncClient(http2=True,http1=False,proxies=self.proxies,timeout=10)
response = asyncio.run(self.send_request(payload,times,method,uri,headers))
Activity
blazing-gig commentedon Oct 20, 2022
@jainaj81 I faced the same issue as well. I think this has to do something with using
asyncio.gather()maybe. Would help greatly if the core team noticed this. Happy to contribute if needed. Thanks.lovelydinosaur commentedon Nov 8, 2022
The first step here is that we would like
anyio.ClosedResourceErrorto be properly mapped tohttpx.WriteError.I can see in
httpcorethat we're mappinganyio.BrokenResourceErrorproperly, but notanyio.ClosedResourceErrorSee the AnyIO docs https://anyio.readthedocs.io/en/stable/api.html#exceptions
It's clear to me how to resolve that issue in the
httpcorecodebase, but I'd like to be able to test it properly too. Here's what I was trying to start with...server.py:
client.py:
Then...
And Ctrl-C twice on the server while the client is still uploading.
Which results in...
That's not what we need to test this error case.
I think in order to test this I need a server example working just at the socket layer (rather than with an ASGI web server) so I can properly push the various cases.
Let's use
trioto do the server socket programming instead...server.py:
But I'm still seeing this map to a
BrokenResourceError, so I'm not clear how to test theClosedResourceErrorat this point.Looking at Trio's docs helps here...
https://trio.readthedocs.io/en/stable/reference-core.html#trio.BrokenResourceError
Ahhh... to reproduce this we need to client to close the connection while it's still performing an upload.
I'm not quite sure how to do that.
Saving my progress so far.
lovelydinosaur commentedon Nov 8, 2022
@jainaj81 If you format and clean up your example code into a runnable example that would help me progress the issue.
lovelydinosaur commentedon Nov 30, 2022
My working assumption here is that you've got a bug in the client side, where you're closing the client before you've finished with all the connections.
That would result in an
anyio.closedResourceError, or once encode/httpcore#631 is merged it'd result in a neaterhttpx.ReadErrororhttpx.WriteError.I'm going to close this off on that assumption. I'm happy to reopen the ticket if a clearer reproducible example is provided.
KnownBlackHat commentedon Oct 21, 2023
i m facing same error repeatedly
this is sample code: https://paste.disnake.dev/?id=1697879915118304
this is error: https://paste.disnake.dev/?id=169788019594034
And this is how i m invoking it

Summary:
whenever a request is sent to a link which results 404 or any other status code then client also gets closed and i don't think that kind of behavior should be strictly implemented there. there should be an param in client to set whether to close the client on error or not