Skip to content

Conversation

@patchback
Copy link
Contributor

@patchback patchback bot commented Oct 3, 2023

This is a backport of PR #7644 as merged into master (6639f7d).

What do these changes do?

Fixes an issue reported in 7616 - An iteration of the chunks of an EmptyStreamReader with iter_chunks() never ends.

Are there changes in behavior for the user?

  • EmptyStreamReader iter_chunks() does not get stuck
  • First call of EmptyStreamReader readchunk() now returns (b"", False). All the subsequent calls return (b"", True). Before this PR it was always (b"", True).

Related issue number

7616

Checklist

  • I think the code is well written
  • Unit tests for the changes exist
  • Documentation reflects the changes
  • If you provide code modification, please add yourself to CONTRIBUTORS.txt
    • The format is <Name> <Surname>.
    • Please keep alphabetical order, the file is sorted by names.
  • Add a new news fragment into the CHANGES folder
    • name it <issue_id>.<type> for example (588.bugfix)
    • if you don't have an issue_id change it to the pr id after creating the pr
    • ensure type is one of the following:
      • .feature: Signifying a new feature.
      • .bugfix: Signifying a bug fix.
      • .doc: Signifying a documentation improvement.
      • .removal: Signifying a deprecation or removal of public API.
      • .misc: A ticket has been closed, but it is not of interest to users.
    • Make sure to use full sentences with correct case and punctuation, for example: "Fix issue with non-ascii contents in doctest text files."

## What do these changes do?

Fixes an issue reported in
[7616](#7616) - An iteration
of the chunks of an EmptyStreamReader with iter_chunks() never ends.
## Are there changes in behavior for the user?

- `EmptyStreamReader` `iter_chunks()` does not get stuck
- First call of `EmptyStreamReader` `readchunk()` now returns `(b"",
False)`. All the subsequent calls return `(b"", True)`. Before this PR
it was always `(b"", True)`.

## Related issue number

[7616](#7616)

(cherry picked from commit 6639f7d)
@rgeronimi
Copy link

rgeronimi commented Oct 3, 2023

A subtle bug comes from
https://github.com/aio-libs/aiohttp/blob/2a73d4699c0b7de1460d831eea48895edff6f9af/aiohttp/streams.py#L565C1-L565C14

which shares a single instance of the empty reader for all cases where an HTTP response has no body.

This instance being shared, it will not return properly (b"", False) on the first iteration call of each API client calling it. It will return it properly only for the very first API client

2 alternative solutions:

  • Make it not shared, creating a new object every time an empty HTTP response is parsed
  • Simplify the API contract to remove the obligation to return (b"", False) as the first iteration result. I don't know the reason why this contract was added in the first place (it was added through another issue)

@Dreamsorcerer
Copy link
Member

  • Make it not shared, creating a new object every time an empty HTTP response is parsed

Yes, maybe we can do that. Then also deprecate the EMPTY_PAYLOAD global as well, I guess. Not sure how better to solve it.

  • Simplify the API contract to remove the obligation to return (b"", False) as the first iteration result. I don't know the reason why this contract was added in the first place (it was added through another issue)

From what I could see, that is the message sent when an EOF byte is received. So, I'm not sure this logic can be changed without breaking things.

@Dreamsorcerer Dreamsorcerer merged commit 56d2be3 into 3.9 Oct 3, 2023
@Dreamsorcerer Dreamsorcerer deleted the patchback/backports/3.9/6639f7df32bea3ee6952299173bdf90c95f9ee5f/pr-7644 branch October 3, 2023 14:26
agners added a commit to agners/aiohttp that referenced this pull request Aug 7, 2025
When aiohttp returns an empty reader, the first time the iter_chunks()
iterator stops after the first read as expected. However, on the second
empty reader return, iter_chunks() loops forever.

This is due to state sharing caused by the global EmptyStreamReader
instance. It has been noticed during review in aio-libs#7645, but so far hasn't
been addressed.

This PR attempts to address the issue by returning a new instance.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants