Skip to content

EnableBuffering/FileBufferingReadStream doesn't support 0-byte reads #41287

Closed
@Tratcher

Description

@Tratcher

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

The 0-byte read pattern does not work with FileBufferingReadStream.

On first read with a zero-length buffer it returns 0, but that causes the stream to think it's completely buffered and to stop reading from the inner stream.

if (read > 0)
{
await _buffer.WriteAsync(buffer.Slice(0, read), cancellationToken);
}
else
{
_completelyBuffered = true;
}

Expected Behavior

0-byte reads should return 0, but subsequent reads should still return data.

Steps To Reproduce


    [Fact]
    public async Task FileBufferingReadStream_Async0ByteReadUnderThreshold_DoesntCreateFile()
    {
        var inner = MakeStream(1024);
        using (var stream = new FileBufferingReadStream(inner, 1024 * 2, null, Directory.GetCurrentDirectory()))
        {
            var bytes = new byte[1000];
            var read0 = await stream.ReadAsync(bytes, 0, 0);
            Assert.Equal(0, read0);
            Assert.Equal(read0, stream.Length);
            Assert.Equal(read0, stream.Position);
            Assert.True(stream.InMemory);
            Assert.Null(stream.TempFileName);

            var read1 = await stream.ReadAsync(bytes, 0, bytes.Length);
            Assert.Equal(bytes.Length, read1);
            Assert.Equal(read0 + read1, stream.Length);
            Assert.Equal(read0 + read1, stream.Position);
            Assert.True(stream.InMemory);
            Assert.Null(stream.TempFileName);

            var read2 = await stream.ReadAsync(bytes, 0, bytes.Length);
            Assert.Equal(inner.Length - read0 - read1, read2);
            Assert.Equal(read0 + read1 + read2, stream.Length);
            Assert.Equal(read0 + read1 + read2, stream.Position);
            Assert.True(stream.InMemory);
            Assert.Null(stream.TempFileName);

            var read3 = await stream.ReadAsync(bytes, 0, bytes.Length);
            Assert.Equal(0, read3);
        }
    }

Exceptions (if any)

No response

.NET Version

6.0

Anything else?

Discovered by YARP users: dotnet/yarp#1657

Metadata

Metadata

Assignees

Labels

area-networkingIncludes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractionsbugThis issue describes a behavior which is not expected - a bug.

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions