Skip to content

Commit

Permalink
fix(h2_connection_reset): add stream reset when client cancel the req…
Browse files Browse the repository at this point in the history
…uest
  • Loading branch information
MarkLux committed Sep 4, 2024
1 parent 7d87c9d commit 18422ff
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 0 deletions.
9 changes: 9 additions & 0 deletions httpcore/_async/http2.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,9 @@ async def _receive_remote_settings_change(self, event: h2.events.Event) -> None:
await self._max_streams_semaphore.acquire()
self._max_streams -= 1

async def _reset_steam(self, stream_id: int, error_code: int) -> None:
self._h2_state.reset_stream(stream_id=stream_id, error_code=error_code)

async def _response_closed(self, stream_id: int) -> None:
await self._max_streams_semaphore.release()
del self._events[stream_id]
Expand Down Expand Up @@ -578,6 +581,12 @@ async def __aiter__(self) -> typing.AsyncIterator[bytes]:
# we want to close the response (and possibly the connection)
# before raising that exception.
with AsyncShieldCancellation():
# need send cancel frame when the exception is not from remote peer.
if not isinstance(exc, RemoteProtocolError):
await self._connection._reset_steam(
stream_id=self._stream_id,
error_code=h2.settings.ErrorCodes.CANCEL,
)
await self.aclose()
raise exc

Expand Down
9 changes: 9 additions & 0 deletions httpcore/_sync/http2.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,9 @@ def _receive_remote_settings_change(self, event: h2.events.Event) -> None:
self._max_streams_semaphore.acquire()
self._max_streams -= 1

def _reset_steam(self, stream_id: int, error_code: int) -> None:
self._h2_state.reset_stream(stream_id=stream_id, error_code=error_code)

def _response_closed(self, stream_id: int) -> None:
self._max_streams_semaphore.release()
del self._events[stream_id]
Expand Down Expand Up @@ -578,6 +581,12 @@ def __iter__(self) -> typing.Iterator[bytes]:
# we want to close the response (and possibly the connection)
# before raising that exception.
with ShieldCancellation():
# need send cancel frame when the exception is not from remote peer.
if not isinstance(exc, RemoteProtocolError):
self._connection._reset_steam(
stream_id=self._stream_id,
error_code=h2.settings.ErrorCodes.CANCEL,
)
self.close()
raise exc

Expand Down

0 comments on commit 18422ff

Please sign in to comment.