diff --git a/src/Http/WebUtilities/src/BufferedReadStream.cs b/src/Http/WebUtilities/src/BufferedReadStream.cs
index 1860e607b9f2..7d9221b915d8 100644
--- a/src/Http/WebUtilities/src/BufferedReadStream.cs
+++ b/src/Http/WebUtilities/src/BufferedReadStream.cs
@@ -108,8 +108,8 @@ public override long Position
if (innerOffset <= _bufferCount)
{
// Yes, just skip some of the buffered data
- _bufferOffset += innerOffset;
- _bufferCount -= innerOffset;
+ _bufferOffset += _bufferCount - innerOffset;
+ _bufferCount = innerOffset;
}
else
{
diff --git a/src/Http/WebUtilities/test/MultipartReaderTests.cs b/src/Http/WebUtilities/test/MultipartReaderTests.cs
index 9055e14a10aa..f97045e07b01 100644
--- a/src/Http/WebUtilities/test/MultipartReaderTests.cs
+++ b/src/Http/WebUtilities/test/MultipartReaderTests.cs
@@ -80,7 +80,6 @@ public class MultipartReaderTests
"
Content of a.html.\r\n" +
"\r\n" +
"--9051914041544843365972754266--\r\n";
-
private const string TwoPartBodyIncompleteBuffer =
"--9051914041544843365972754266\r\n" +
"Content-Disposition: form-data; name=\"text\"\r\n" +
@@ -315,6 +314,43 @@ public void MultipartReader_BufferSizeMustBeLargerThanBoundary_Throws()
});
}
+ [Fact]
+ public async Task MultipartReader_ReadMultipartBodyWithFilesForDeferredCopy_Success()
+ {
+ var stream = MakeStream(ThreePartBody);
+ var reader = new MultipartReader(Boundary, stream);
+
+ await reader.ReadNextSectionAsync(); // skip text field section
+
+ var section = await reader.ReadNextSectionAsync();
+ Assert.NotNull(section);
+ Assert.Equal(2, section.Headers.Count);
+ Assert.Equal("form-data; name=\"file1\"; filename=\"a.txt\"", section.Headers["Content-Disposition"][0]);
+ Assert.Equal("text/plain", section.Headers["Content-Type"][0]);
+ var stream1 = section.Body;
+
+ section = await reader.ReadNextSectionAsync();
+ Assert.NotNull(section);
+ Assert.Equal(2, section.Headers.Count);
+ Assert.Equal("form-data; name=\"file2\"; filename=\"a.html\"", section.Headers["Content-Disposition"][0]);
+ Assert.Equal("text/html", section.Headers["Content-Type"][0]);
+ var stream2 = section.Body;
+
+ Assert.Null(await reader.ReadNextSectionAsync());
+
+ Assert.True(stream1.CanSeek);
+ Assert.Equal(0, stream1.Seek(0, SeekOrigin.Begin));
+ var buffer = new MemoryStream();
+ await stream1.CopyToAsync(buffer);
+ Assert.Equal("Content of a.txt.\r\n", Encoding.ASCII.GetString(buffer.ToArray()));
+
+ Assert.True(stream2.CanSeek);
+ Assert.Equal(0, stream2.Seek(0, SeekOrigin.Begin));
+ buffer = new MemoryStream();
+ await stream2.CopyToAsync(buffer);
+ Assert.Equal("Content of a.html.\r\n", Encoding.ASCII.GetString(buffer.ToArray()));
+ }
+
[Fact]
public async Task MultipartReader_TwoPartBodyIncompleteBuffer_TwoSectionsReadSuccessfullyThirdSectionThrows()
{