Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/Http/WebUtilities/src/BufferedReadStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
72 changes: 71 additions & 1 deletion src/Http/WebUtilities/test/MultipartReaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ public class MultipartReaderTests
"<!DOCTYPE html><title>Content of a.html.</title>\r\n" +
"\r\n" +
"--9051914041544843365972754266--\r\n";

private const string TwoPartBodyIncompleteBuffer =
"--9051914041544843365972754266\r\n" +
"Content-Disposition: form-data; name=\"text\"\r\n" +
Expand All @@ -93,6 +92,26 @@ public class MultipartReaderTests
"Content of a.txt.\r\n" +
"\r\n" +
"--9051914041544843365";
private const string ThreePartBodyWithMixedFiles =
"--9051914041544843365972754266\r\n" +
"Content-Disposition: form-data; name=\"file1\"; filename=\"a.txt\"\r\n" +
"Content-Type: text/plain\r\n" +
"\r\n" +
"Content of a.txt.\r\n" +
"\r\n" +
"--9051914041544843365972754266\r\n" +
"Content-Disposition: form-data; name=\"file2\"; filename=\"a.html\"\r\n" +
"Content-Type: text/html\r\n" +
"\r\n" +
"<!DOCTYPE html><title>Content of a.html.</title>\r\n" +
"\r\n" +
"--9051914041544843365972754266\r\n" +
"Content-Disposition: form-data; name=\"file3\"; filename=\"a.json\"\r\n" +
"Content-Type: application/json\r\n" +
"\r\n" +
"{ \"Text\": \"Content of a.json.\" }\r\n" +
"\r\n" +
"--9051914041544843365972754266--\r\n";

private static MemoryStream MakeStream(string text)
{
Expand Down Expand Up @@ -315,6 +334,57 @@ public void MultipartReader_BufferSizeMustBeLargerThanBoundary_Throws()
});
}

[Fact]
public async Task MultipartReader_ReadMultipartBodyWithFilesForDeferredCopy_Success()
{
var stream = MakeStream(ThreePartBodyWithMixedFiles);
var reader = new MultipartReader(Boundary, stream);

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;

section = await reader.ReadNextSectionAsync();
Assert.NotNull(section);
Assert.Equal(2, section.Headers.Count);
Assert.Equal("form-data; name=\"file3\"; filename=\"a.json\"", section.Headers["Content-Disposition"][0]);
Assert.Equal("application/json", section.Headers["Content-Type"][0]);
var stream3 = section.Body;

Assert.Null(await reader.ReadNextSectionAsync());

Assert.True(stream1.CanSeek);
Assert.Equal(0, stream1.Seek(0, SeekOrigin.Begin));
var buffer = new MemoryStream();
var exception = await Record.ExceptionAsync(() => stream1.CopyToAsync(buffer));
Assert.Null(exception);
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();
exception = await Record.ExceptionAsync(() => stream2.CopyToAsync(buffer));
Assert.Null(exception);
Assert.Equal("<!DOCTYPE html><title>Content of a.html.</title>\r\n", Encoding.ASCII.GetString(buffer.ToArray()));

Assert.True(stream3.CanSeek);
Assert.Equal(0, stream3.Seek(0, SeekOrigin.Begin));
buffer = new MemoryStream();
exception = await Record.ExceptionAsync(() => stream3.CopyToAsync(buffer));
Assert.Null(exception);
Assert.Equal("{ \"Text\": \"Content of a.json.\" }\r\n", Encoding.ASCII.GetString(buffer.ToArray()));
}

[Fact]
public async Task MultipartReader_TwoPartBodyIncompleteBuffer_TwoSectionsReadSuccessfullyThirdSectionThrows()
{
Expand Down
Loading