@@ -230,6 +230,59 @@ await client.GetAsync(remoteServer.EchoUri, HttpCompletionOption.ResponseHeaders
230
230
231
231
#if NETCOREAPP
232
232
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
+
233
286
[ OuterLoop ]
234
287
[ ConditionalTheory ( typeof ( PlatformDetection ) , nameof ( PlatformDetection . IsBrowser ) ) ]
235
288
[ InlineData ( true ) ]
@@ -242,17 +295,17 @@ public async Task BrowserHttpHandler_StreamingRequest(bool useStringContent)
242
295
243
296
req . Options . Set ( WebAssemblyEnableStreamingRequestKey , true ) ;
244
297
245
- int expectedBodyLength ;
298
+ int size ;
246
299
if ( useStringContent )
247
300
{
248
301
string bodyContent = "Hello World" ;
249
- expectedBodyLength = bodyContent . Length ;
302
+ size = bodyContent . Length ;
250
303
req . Content = new StringContent ( bodyContent ) ;
251
304
}
252
305
else
253
306
{
254
- expectedBodyLength = 1500 * 1024 * 1024 ;
255
- int remaining = expectedBodyLength ;
307
+ size = 1500 * 1024 * 1024 ;
308
+ int remaining = size ;
256
309
req . Content = new StreamContent ( new DelegateStream (
257
310
readAsyncFunc : ( buffer , offset , count , cancellationToken ) =>
258
311
{
@@ -273,11 +326,12 @@ public async Task BrowserHttpHandler_StreamingRequest(bool useStringContent)
273
326
using ( HttpResponseMessage response = await client . SendAsync ( req ) )
274
327
{
275
328
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
277
331
Assert . Equal ( useStringContent , response . Headers . Contains ( "X-HttpRequest-Headers-ContentLength" ) ) ;
278
332
if ( useStringContent )
279
333
{
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" ) ) ) ;
281
335
}
282
336
}
283
337
}
@@ -327,6 +381,7 @@ public async Task BrowserHttpHandler_StreamingResponse()
327
381
// we need to switch off Response buffering of default ResponseContentRead option
328
382
using ( HttpResponseMessage response = await client . SendAsync ( req , HttpCompletionOption . ResponseHeadersRead ) )
329
383
{
384
+ // Streaming response uses StreamContent
330
385
Assert . Equal ( typeof ( StreamContent ) , response . Content . GetType ( ) ) ;
331
386
332
387
Assert . Equal ( "application/octet-stream" , response . Content . Headers . ContentType . MediaType ) ;
0 commit comments