@@ -230,6 +230,59 @@ await client.GetAsync(remoteServer.EchoUri, HttpCompletionOption.ResponseHeaders
230230
231231#if NETCOREAPP
232232
233+ [ OuterLoop ]
234+ [ ConditionalFact ( typeof ( PlatformDetection ) , nameof ( PlatformDetection . IsBrowser ) ) ]
235+ public async Task BrowserHttpHandler_Streaming ( )
236+ {
237+ var WebAssemblyEnableStreamingRequestKey = new HttpRequestOptionsKey < bool > ( "WebAssemblyEnableStreamingRequest" ) ;
238+ var WebAssemblyEnableStreamingResponseKey = new HttpRequestOptionsKey < bool > ( "WebAssemblyEnableStreamingResponse" ) ;
239+
240+ var req = new HttpRequestMessage ( HttpMethod . Post , Configuration . Http . RemoteHttp2Server . BaseUri + "echobody.ashx" ) ;
241+
242+ req . Options . Set ( WebAssemblyEnableStreamingRequestKey , true ) ;
243+ req . Options . Set ( WebAssemblyEnableStreamingResponseKey , true ) ;
244+
245+ byte [ ] body = new byte [ 1024 * 1024 ] ;
246+ Random . Shared . NextBytes ( body ) ;
247+
248+ int readOffset = 0 ;
249+ req . Content = new StreamContent ( new DelegateStream (
250+ readAsyncFunc : async ( buffer , offset , count , cancellationToken ) =>
251+ {
252+ await Task . Delay ( 1 ) ;
253+ if ( readOffset < body . Length )
254+ {
255+ int send = Math . Min ( body . Length - readOffset , count ) ;
256+ body . AsSpan ( readOffset , send ) . CopyTo ( buffer . AsSpan ( offset , send ) ) ;
257+ readOffset += send ;
258+ return send ;
259+ }
260+ return 0 ;
261+ } ) ) ;
262+
263+ using ( HttpClient client = CreateHttpClientForRemoteServer ( Configuration . Http . RemoteHttp2Server ) )
264+ using ( HttpResponseMessage response = await client . SendAsync ( req ) )
265+ {
266+ Assert . Equal ( HttpStatusCode . OK , response . StatusCode ) ;
267+ // Streaming requests can't set Content-Length
268+ Assert . False ( response . Headers . Contains ( "X-HttpRequest-Headers-ContentLength" ) ) ;
269+ // Streaming response uses StreamContent
270+ Assert . Equal ( typeof ( StreamContent ) , response . Content . GetType ( ) ) ;
271+
272+ var stream = await response . Content . ReadAsStreamAsync ( ) ;
273+ var buffer = new byte [ 1024 * 1024 ] ;
274+ int totalCount = 0 ;
275+ int fetchedCount = 0 ;
276+ do
277+ {
278+ fetchedCount = await stream . ReadAsync ( buffer , 0 , buffer . Length ) ;
279+ Assert . True ( body . AsSpan ( totalCount , fetchedCount ) . SequenceEqual ( buffer . AsSpan ( 0 , fetchedCount ) ) ) ;
280+ totalCount += fetchedCount ;
281+ } while ( fetchedCount != 0 ) ;
282+ Assert . Equal ( body . Length , totalCount ) ;
283+ }
284+ }
285+
233286 [ OuterLoop ]
234287 [ ConditionalTheory ( typeof ( PlatformDetection ) , nameof ( PlatformDetection . IsBrowser ) ) ]
235288 [ InlineData ( true ) ]
@@ -242,17 +295,17 @@ public async Task BrowserHttpHandler_StreamingRequest(bool useStringContent)
242295
243296 req . Options . Set ( WebAssemblyEnableStreamingRequestKey , true ) ;
244297
245- int expectedBodyLength ;
298+ int size ;
246299 if ( useStringContent )
247300 {
248301 string bodyContent = "Hello World" ;
249- expectedBodyLength = bodyContent . Length ;
302+ size = bodyContent . Length ;
250303 req . Content = new StringContent ( bodyContent ) ;
251304 }
252305 else
253306 {
254- expectedBodyLength = 1500 * 1024 * 1024 ;
255- int remaining = expectedBodyLength ;
307+ size = 1500 * 1024 * 1024 ;
308+ int remaining = size ;
256309 req . Content = new StreamContent ( new DelegateStream (
257310 readAsyncFunc : ( buffer , offset , count , cancellationToken ) =>
258311 {
@@ -273,11 +326,12 @@ public async Task BrowserHttpHandler_StreamingRequest(bool useStringContent)
273326 using ( HttpResponseMessage response = await client . SendAsync ( req ) )
274327 {
275328 Assert . Equal ( HttpStatusCode . OK , response . StatusCode ) ;
276- Assert . Equal ( expectedBodyLength . ToString ( ) , Assert . Single ( response . Headers . GetValues ( "X-HttpRequest-Body-Length" ) ) ) ;
329+ Assert . Equal ( size . ToString ( ) , Assert . Single ( response . Headers . GetValues ( "X-HttpRequest-Body-Length" ) ) ) ;
330+ // Streaming requests can't set Content-Length
277331 Assert . Equal ( useStringContent , response . Headers . Contains ( "X-HttpRequest-Headers-ContentLength" ) ) ;
278332 if ( useStringContent )
279333 {
280- Assert . Equal ( expectedBodyLength . ToString ( ) , Assert . Single ( response . Headers . GetValues ( "X-HttpRequest-Headers-ContentLength" ) ) ) ;
334+ Assert . Equal ( size . ToString ( ) , Assert . Single ( response . Headers . GetValues ( "X-HttpRequest-Headers-ContentLength" ) ) ) ;
281335 }
282336 }
283337 }
@@ -327,6 +381,7 @@ public async Task BrowserHttpHandler_StreamingResponse()
327381 // we need to switch off Response buffering of default ResponseContentRead option
328382 using ( HttpResponseMessage response = await client . SendAsync ( req , HttpCompletionOption . ResponseHeadersRead ) )
329383 {
384+ // Streaming response uses StreamContent
330385 Assert . Equal ( typeof ( StreamContent ) , response . Content . GetType ( ) ) ;
331386
332387 Assert . Equal ( "application/octet-stream" , response . Content . Headers . ContentType . MediaType ) ;
0 commit comments