diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index d9958e9c5209a..98c23bdcde0c0 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -934,11 +934,12 @@ await connection.WriteStringAsync( } [Theory] - [InlineData(true)] - [InlineData(false)] - [InlineData(null)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/54159", TestPlatforms.Browser)] - public async Task ReadAsStreamAsync_HandlerProducesWellBehavedResponseStream(bool? chunked) + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + [InlineData(null, false)] + public async Task ReadAsStreamAsync_HandlerProducesWellBehavedResponseStream(bool? chunked, bool enableWasmStreaming) { if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value) { @@ -960,6 +961,16 @@ public async Task ReadAsStreamAsync_HandlerProducesWellBehavedResponseStream(boo await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { var request = new HttpRequestMessage(HttpMethod.Get, uri) { Version = UseVersion }; + if (PlatformDetection.IsBrowser) + { + if (enableWasmStreaming) + { +#if !NETFRAMEWORK + request.Options.Set(new HttpRequestOptionsKey("WebAssemblyEnableStreamingResponse"), true); +#endif + } + } + using (var client = new HttpMessageInvoker(CreateHttpClientHandler())) using (HttpResponseMessage response = await client.SendAsync(TestAsync, request, CancellationToken.None)) { @@ -970,21 +981,24 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => // Boolean properties returning correct values Assert.True(responseStream.CanRead); Assert.False(responseStream.CanWrite); - Assert.False(responseStream.CanSeek); + Assert.Equal(PlatformDetection.IsBrowser && !enableWasmStreaming, responseStream.CanSeek); // Not supported operations Assert.Throws(() => responseStream.BeginWrite(new byte[1], 0, 1, null, null)); - Assert.Throws(() => responseStream.Length); - Assert.Throws(() => responseStream.Position); - Assert.Throws(() => responseStream.Position = 0); - Assert.Throws(() => responseStream.Seek(0, SeekOrigin.Begin)); + if (!responseStream.CanSeek) + { + Assert.Throws(() => responseStream.Length); + Assert.Throws(() => responseStream.Position); + Assert.Throws(() => responseStream.Position = 0); + Assert.Throws(() => responseStream.Seek(0, SeekOrigin.Begin)); + } Assert.Throws(() => responseStream.SetLength(0)); Assert.Throws(() => responseStream.Write(new byte[1], 0, 1)); #if !NETFRAMEWORK Assert.Throws(() => responseStream.Write(new Span(new byte[1]))); - Assert.Throws(() => { responseStream.WriteAsync(new Memory(new byte[1])); }); + await Assert.ThrowsAsync(async () => await responseStream.WriteAsync(new Memory(new byte[1]))); #endif - Assert.Throws(() => { responseStream.WriteAsync(new byte[1], 0, 1); }); + await Assert.ThrowsAsync(async () => await responseStream.WriteAsync(new byte[1], 0, 1)); Assert.Throws(() => responseStream.WriteByte(1)); // Invalid arguments @@ -998,11 +1012,14 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => Assert.Throws(() => { responseStream.CopyToAsync(Stream.Null, -1, default); }); Assert.Throws(() => { responseStream.CopyToAsync(nonWritableStream, 100, default); }); Assert.Throws(() => { responseStream.CopyToAsync(disposedStream, 100, default); }); - Assert.Throws(() => responseStream.Read(null, 0, 100)); - Assert.Throws(() => responseStream.Read(new byte[1], -1, 1)); - Assert.ThrowsAny(() => responseStream.Read(new byte[1], 2, 1)); - Assert.Throws(() => responseStream.Read(new byte[1], 0, -1)); - Assert.ThrowsAny(() => responseStream.Read(new byte[1], 0, 2)); + if (PlatformDetection.IsNotBrowser) + { + Assert.Throws(() => responseStream.Read(null, 0, 100)); + Assert.Throws(() => responseStream.Read(new byte[1], -1, 1)); + Assert.ThrowsAny(() => responseStream.Read(new byte[1], 2, 1)); + Assert.Throws(() => responseStream.Read(new byte[1], 0, -1)); + Assert.ThrowsAny(() => responseStream.Read(new byte[1], 0, 2)); + } Assert.Throws(() => responseStream.BeginRead(null, 0, 100, null, null)); Assert.Throws(() => responseStream.BeginRead(new byte[1], -1, 1, null, null)); Assert.ThrowsAny(() => responseStream.BeginRead(new byte[1], 2, 1, null, null)); @@ -1018,62 +1035,99 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => // Various forms of reading var buffer = new byte[1]; - Assert.Equal('h', responseStream.ReadByte()); + if (PlatformDetection.IsBrowser) + { +#if !NETFRAMEWORK + Assert.Equal('h', await responseStream.ReadByteAsync()); + Assert.Equal('e', await responseStream.ReadByteAsync()); + Assert.Equal(1, await responseStream.ReadAsync(new Memory(buffer))); + Assert.Equal((byte)'l', buffer[0]); + + Assert.Equal(1, await responseStream.ReadAsync(buffer, 0, 1)); + Assert.Equal((byte)'l', buffer[0]); + + Assert.Equal(1, await responseStream.ReadAsync(buffer)); + Assert.Equal((byte)'o', buffer[0]); + + Assert.Equal(1, await responseStream.ReadAsync(buffer, 0, 1)); + Assert.Equal((byte)' ', buffer[0]); + + // Doing any of these 0-byte reads causes the connection to fail. + Assert.Equal(0, await responseStream.ReadAsync(Memory.Empty)); + Assert.Equal(0, await responseStream.ReadAsync(Array.Empty(), 0, 0)); + + // And copying + var ms = new MemoryStream(); + await responseStream.CopyToAsync(ms); + Assert.Equal("world", Encoding.ASCII.GetString(ms.ToArray())); + + // Read and copy again once we've exhausted all data + ms = new MemoryStream(); + await responseStream.CopyToAsync(ms); + Assert.Equal(0, ms.Length); + Assert.Equal(0, await responseStream.ReadAsync(buffer, 0, 1)); + Assert.Equal(0, await responseStream.ReadAsync(new Memory(buffer))); +#endif + } + else + { + Assert.Equal('h', responseStream.ReadByte()); + Assert.Equal(1, await Task.Factory.FromAsync(responseStream.BeginRead, responseStream.EndRead, buffer, 0, 1, null)); + Assert.Equal((byte)'e', buffer[0]); - Assert.Equal(1, await Task.Factory.FromAsync(responseStream.BeginRead, responseStream.EndRead, buffer, 0, 1, null)); - Assert.Equal((byte)'e', buffer[0]); #if !NETFRAMEWORK - Assert.Equal(1, await responseStream.ReadAsync(new Memory(buffer))); + Assert.Equal(1, await responseStream.ReadAsync(new Memory(buffer))); #else - Assert.Equal(1, await responseStream.ReadAsync(buffer, 0, 1)); + Assert.Equal(1, await responseStream.ReadAsync(buffer, 0, 1)); #endif - Assert.Equal((byte)'l', buffer[0]); + Assert.Equal((byte)'l', buffer[0]); - Assert.Equal(1, await responseStream.ReadAsync(buffer, 0, 1)); - Assert.Equal((byte)'l', buffer[0]); + Assert.Equal(1, await responseStream.ReadAsync(buffer, 0, 1)); + Assert.Equal((byte)'l', buffer[0]); #if !NETFRAMEWORK - Assert.Equal(1, responseStream.Read(new Span(buffer))); + Assert.Equal(1, responseStream.Read(new Span(buffer))); #else - Assert.Equal(1, await responseStream.ReadAsync(buffer, 0, 1)); + Assert.Equal(1, await responseStream.ReadAsync(buffer, 0, 1)); #endif - Assert.Equal((byte)'o', buffer[0]); + Assert.Equal((byte)'o', buffer[0]); - Assert.Equal(1, responseStream.Read(buffer, 0, 1)); - Assert.Equal((byte)' ', buffer[0]); + Assert.Equal(1, responseStream.Read(buffer, 0, 1)); + Assert.Equal((byte)' ', buffer[0]); - // Doing any of these 0-byte reads causes the connection to fail. - Assert.Equal(0, await Task.Factory.FromAsync(responseStream.BeginRead, responseStream.EndRead, Array.Empty(), 0, 0, null)); + // Doing any of these 0-byte reads causes the connection to fail. + Assert.Equal(0, await Task.Factory.FromAsync(responseStream.BeginRead, responseStream.EndRead, Array.Empty(), 0, 0, null)); #if !NETFRAMEWORK - Assert.Equal(0, await responseStream.ReadAsync(Memory.Empty)); + Assert.Equal(0, await responseStream.ReadAsync(Memory.Empty)); #endif - Assert.Equal(0, await responseStream.ReadAsync(Array.Empty(), 0, 0)); + Assert.Equal(0, await responseStream.ReadAsync(Array.Empty(), 0, 0)); #if !NETFRAMEWORK - Assert.Equal(0, responseStream.Read(Span.Empty)); + Assert.Equal(0, responseStream.Read(Span.Empty)); #endif - Assert.Equal(0, responseStream.Read(Array.Empty(), 0, 0)); - - // And copying - var ms = new MemoryStream(); - await responseStream.CopyToAsync(ms); - Assert.Equal("world", Encoding.ASCII.GetString(ms.ToArray())); - - // Read and copy again once we've exhausted all data - ms = new MemoryStream(); - await responseStream.CopyToAsync(ms); - responseStream.CopyTo(ms); - Assert.Equal(0, ms.Length); - Assert.Equal(-1, responseStream.ReadByte()); - Assert.Equal(0, responseStream.Read(buffer, 0, 1)); + Assert.Equal(0, responseStream.Read(Array.Empty(), 0, 0)); + + // And copying + var ms = new MemoryStream(); + await responseStream.CopyToAsync(ms); + Assert.Equal("world", Encoding.ASCII.GetString(ms.ToArray())); + + // Read and copy again once we've exhausted all data + ms = new MemoryStream(); + await responseStream.CopyToAsync(ms); + responseStream.CopyTo(ms); + Assert.Equal(0, ms.Length); + Assert.Equal(-1, responseStream.ReadByte()); + Assert.Equal(0, responseStream.Read(buffer, 0, 1)); #if !NETFRAMEWORK - Assert.Equal(0, responseStream.Read(new Span(buffer))); + Assert.Equal(0, responseStream.Read(new Span(buffer))); #endif - Assert.Equal(0, await responseStream.ReadAsync(buffer, 0, 1)); + Assert.Equal(0, await responseStream.ReadAsync(buffer, 0, 1)); #if !NETFRAMEWORK - Assert.Equal(0, await responseStream.ReadAsync(new Memory(buffer))); + Assert.Equal(0, await responseStream.ReadAsync(new Memory(buffer))); #endif - Assert.Equal(0, await Task.Factory.FromAsync(responseStream.BeginRead, responseStream.EndRead, buffer, 0, 1, null)); + Assert.Equal(0, await Task.Factory.FromAsync(responseStream.BeginRead, responseStream.EndRead, buffer, 0, 1, null)); + } } } }, async server => @@ -1103,7 +1157,6 @@ await server.AcceptConnectionAsync(async connection => } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/54159", TestPlatforms.Browser)] public async Task ReadAsStreamAsync_EmptyResponseBody_HandlerProducesWellBehavedResponseStream() { if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value) @@ -1123,14 +1176,17 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => // Boolean properties returning correct values Assert.True(responseStream.CanRead); Assert.False(responseStream.CanWrite); - Assert.False(responseStream.CanSeek); + Assert.Equal(PlatformDetection.IsBrowser, responseStream.CanSeek); // Not supported operations Assert.Throws(() => responseStream.BeginWrite(new byte[1], 0, 1, null, null)); - Assert.Throws(() => responseStream.Length); - Assert.Throws(() => responseStream.Position); - Assert.Throws(() => responseStream.Position = 0); - Assert.Throws(() => responseStream.Seek(0, SeekOrigin.Begin)); + if (!responseStream.CanSeek) + { + Assert.Throws(() => responseStream.Length); + Assert.Throws(() => responseStream.Position); + Assert.Throws(() => responseStream.Position = 0); + Assert.Throws(() => responseStream.Seek(0, SeekOrigin.Begin)); + } Assert.Throws(() => responseStream.SetLength(0)); Assert.Throws(() => responseStream.Write(new byte[1], 0, 1)); #if !NETFRAMEWORK