From b4505fe80cd54edb8544926bba6fbaae7a0e4fba Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 15 Jun 2021 14:52:04 +0100 Subject: [PATCH] Close socket when read or write timeouts occur --- httpcore/_backends/anyio.py | 2 ++ httpcore/_backends/trio.py | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/httpcore/_backends/anyio.py b/httpcore/_backends/anyio.py index e229ff06c..b1332a27f 100644 --- a/httpcore/_backends/anyio.py +++ b/httpcore/_backends/anyio.py @@ -59,6 +59,7 @@ async def read(self, n: int, timeout: TimeoutDict) -> bytes: with anyio.fail_after(read_timeout): return await self.stream.receive(n) except TimeoutError: + await self.stream.aclose() raise ReadTimeout from None except BrokenResourceError as exc: raise ReadError from exc @@ -75,6 +76,7 @@ async def write(self, data: bytes, timeout: TimeoutDict) -> None: with anyio.fail_after(write_timeout): return await self.stream.send(data) except TimeoutError: + await self.stream.aclose() raise WriteTimeout from None except BrokenResourceError as exc: raise WriteError from exc diff --git a/httpcore/_backends/trio.py b/httpcore/_backends/trio.py index 55555e8ea..d6e67c2e3 100644 --- a/httpcore/_backends/trio.py +++ b/httpcore/_backends/trio.py @@ -58,8 +58,12 @@ async def read(self, n: int, timeout: TimeoutDict) -> bytes: async with self.read_lock: with map_exceptions(exc_map): - with trio.fail_after(read_timeout): - return await self.stream.receive_some(max_bytes=n) + try: + with trio.fail_after(read_timeout): + return await self.stream.receive_some(max_bytes=n) + except trio.TooSlowError as exc: + await self.stream.aclose() + raise exc async def write(self, data: bytes, timeout: TimeoutDict) -> None: if not data: @@ -73,8 +77,12 @@ async def write(self, data: bytes, timeout: TimeoutDict) -> None: async with self.write_lock: with map_exceptions(exc_map): - with trio.fail_after(write_timeout): - return await self.stream.send_all(data) + try: + with trio.fail_after(write_timeout): + return await self.stream.send_all(data) + except trio.TooSlowError as exc: + await self.stream.aclose() + raise exc async def aclose(self) -> None: async with self.write_lock: