@@ -80,7 +80,6 @@ public class MultipartReaderTests
8080"<!DOCTYPE html><title>Content of a.html.</title>\r \n " +
8181"\r \n " +
8282"--9051914041544843365972754266--\r \n " ;
83-
8483 private const string TwoPartBodyIncompleteBuffer =
8584"--9051914041544843365972754266\r \n " +
8685"Content-Disposition: form-data; name=\" text\" \r \n " +
@@ -93,6 +92,26 @@ public class MultipartReaderTests
9392"Content of a.txt.\r \n " +
9493"\r \n " +
9594"--9051914041544843365" ;
95+ private const string ThreePartBodyWithMixedFiles =
96+ "--9051914041544843365972754266\r \n " +
97+ "Content-Disposition: form-data; name=\" file1\" ; filename=\" a.txt\" \r \n " +
98+ "Content-Type: text/plain\r \n " +
99+ "\r \n " +
100+ "Content of a.txt.\r \n " +
101+ "\r \n " +
102+ "--9051914041544843365972754266\r \n " +
103+ "Content-Disposition: form-data; name=\" file2\" ; filename=\" a.html\" \r \n " +
104+ "Content-Type: text/html\r \n " +
105+ "\r \n " +
106+ "<!DOCTYPE html><title>Content of a.html.</title>\r \n " +
107+ "\r \n " +
108+ "--9051914041544843365972754266\r \n " +
109+ "Content-Disposition: form-data; name=\" file3\" ; filename=\" a.json\" \r \n " +
110+ "Content-Type: application/json\r \n " +
111+ "\r \n " +
112+ "{ \" Text\" : \" Content of a.json.\" }\r \n " +
113+ "\r \n " +
114+ "--9051914041544843365972754266--\r \n " ;
96115
97116 private static MemoryStream MakeStream ( string text )
98117 {
@@ -315,6 +334,57 @@ public void MultipartReader_BufferSizeMustBeLargerThanBoundary_Throws()
315334 } ) ;
316335 }
317336
337+ [ Fact ]
338+ public async Task MultipartReader_ReadMultipartBodyWithFilesForDeferredCopy_Success ( )
339+ {
340+ var stream = MakeStream ( ThreePartBodyWithMixedFiles ) ;
341+ var reader = new MultipartReader ( Boundary , stream ) ;
342+
343+ var section = await reader . ReadNextSectionAsync ( ) ;
344+ Assert . NotNull ( section ) ;
345+ Assert . Equal ( 2 , section . Headers . Count ) ;
346+ Assert . Equal ( "form-data; name=\" file1\" ; filename=\" a.txt\" " , section . Headers [ "Content-Disposition" ] [ 0 ] ) ;
347+ Assert . Equal ( "text/plain" , section . Headers [ "Content-Type" ] [ 0 ] ) ;
348+ var stream1 = section . Body ;
349+
350+ section = await reader . ReadNextSectionAsync ( ) ;
351+ Assert . NotNull ( section ) ;
352+ Assert . Equal ( 2 , section . Headers . Count ) ;
353+ Assert . Equal ( "form-data; name=\" file2\" ; filename=\" a.html\" " , section . Headers [ "Content-Disposition" ] [ 0 ] ) ;
354+ Assert . Equal ( "text/html" , section . Headers [ "Content-Type" ] [ 0 ] ) ;
355+ var stream2 = section . Body ;
356+
357+ section = await reader . ReadNextSectionAsync ( ) ;
358+ Assert . NotNull ( section ) ;
359+ Assert . Equal ( 2 , section . Headers . Count ) ;
360+ Assert . Equal ( "form-data; name=\" file3\" ; filename=\" a.json\" " , section . Headers [ "Content-Disposition" ] [ 0 ] ) ;
361+ Assert . Equal ( "application/json" , section . Headers [ "Content-Type" ] [ 0 ] ) ;
362+ var stream3 = section . Body ;
363+
364+ Assert . Null ( await reader . ReadNextSectionAsync ( ) ) ;
365+
366+ Assert . True ( stream1 . CanSeek ) ;
367+ Assert . Equal ( 0 , stream1 . Seek ( 0 , SeekOrigin . Begin ) ) ;
368+ var buffer = new MemoryStream ( ) ;
369+ var exception = await Record . ExceptionAsync ( ( ) => stream1 . CopyToAsync ( buffer ) ) ;
370+ Assert . Null ( exception ) ;
371+ Assert . Equal ( "Content of a.txt.\r \n " , Encoding . ASCII . GetString ( buffer . ToArray ( ) ) ) ;
372+
373+ Assert . True ( stream2 . CanSeek ) ;
374+ Assert . Equal ( 0 , stream2 . Seek ( 0 , SeekOrigin . Begin ) ) ;
375+ buffer = new MemoryStream ( ) ;
376+ exception = await Record . ExceptionAsync ( ( ) => stream2 . CopyToAsync ( buffer ) ) ;
377+ Assert . Null ( exception ) ;
378+ Assert . Equal ( "<!DOCTYPE html><title>Content of a.html.</title>\r \n " , Encoding . ASCII . GetString ( buffer . ToArray ( ) ) ) ;
379+
380+ Assert . True ( stream3 . CanSeek ) ;
381+ Assert . Equal ( 0 , stream3 . Seek ( 0 , SeekOrigin . Begin ) ) ;
382+ buffer = new MemoryStream ( ) ;
383+ exception = await Record . ExceptionAsync ( ( ) => stream3 . CopyToAsync ( buffer ) ) ;
384+ Assert . Null ( exception ) ;
385+ Assert . Equal ( "{ \" Text\" : \" Content of a.json.\" }\r \n " , Encoding . ASCII . GetString ( buffer . ToArray ( ) ) ) ;
386+ }
387+
318388 [ Fact ]
319389 public async Task MultipartReader_TwoPartBodyIncompleteBuffer_TwoSectionsReadSuccessfullyThirdSectionThrows ( )
320390 {
0 commit comments