Skip to content

Always read from underlying stream in StreamPipeReader #118041

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

BrennanConroy
Copy link
Member

As part of dotnet/aspnetcore#62895 we realized that StreamPipeReader was internally storing the fact that the underlying Stream returned 0 indicating end of stream. This causes problems with code that might modify the Stream.Position after the Stream was completely read from. Meaning future read calls on StreamPipeReader will always complete without re-reading the Stream.

This behavior doesn't seem necessary so relaxing the restrictions to always read from the underlying Stream, assuming the PipeReader isn't completed and there isn't any unexamined buffered data.

@BrennanConroy BrennanConroy self-assigned this Jul 24, 2025
@Copilot Copilot AI review requested due to automatic review settings July 24, 2025 21:42
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes an issue in StreamPipeReader where the reader would incorrectly cache that the underlying stream had reached its end, preventing it from re-reading data when the stream position was reset. The change removes internal state tracking of stream completion and always attempts to read from the underlying stream when there's no unexamined buffered data.

  • Removes the _isStreamCompleted field that was preventing subsequent reads after the stream reached EOF
  • Updates read logic to determine completion status dynamically rather than caching it
  • Modifies test cases to use standard MemoryStream instead of custom test streams and adds a new test for stream position reset scenarios

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/StreamPipeReader.cs Removes _isStreamCompleted field and associated logic that cached stream completion state
src/libraries/System.IO.Pipelines/tests/StreamPipeReaderTests.cs Updates existing tests and adds new test case for stream position reset behavior

@NinoFloris
Copy link
Contributor

NinoFloris commented Jul 25, 2025

This would mean wrapping a networkstream would now throw after the EOF is read? (As it'll transition to non-readable, causing an exception on the next ReadAsync). EDIT: nevermind, this won't happen until Close is called.

@BrennanConroy
Copy link
Member Author

Right, most Streams should continue working until Close/Dispose is called on them.

@davidfowl
Copy link
Member

I’m remembering this was added for a reason ….

@BrennanConroy
Copy link
Member Author

I’m remembering this was added for a reason ….

Was it a good reason? 😆

@BrennanConroy
Copy link
Member Author

Would checking Stream.CanSeek to determine if we should store completion state be more desirable?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants