Fix #19991 Made TestHost fail when Response Flush is called with AllowSynchronossIO being dissabled (#20059)
This commit is contained in:
parent
d0cc04f957
commit
e21fb7e93c
|
|
@ -46,6 +46,11 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
|
||||
public override void Flush()
|
||||
{
|
||||
if (!_allowSynchronousIO())
|
||||
{
|
||||
throw new InvalidOperationException("Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true.");
|
||||
}
|
||||
|
||||
FlushAsync().GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -289,7 +289,7 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
var handler = new ClientHandler(PathString.Empty, new DummyApplication(async context =>
|
||||
{
|
||||
context.Response.Headers["TestHeader"] = "TestValue";
|
||||
context.Response.Body.Flush();
|
||||
await context.Response.Body.FlushAsync();
|
||||
await block.Task;
|
||||
await context.Response.WriteAsync("BodyFinished");
|
||||
}));
|
||||
|
|
@ -305,11 +305,11 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
public async Task ClientDisposalCloses()
|
||||
{
|
||||
var block = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var handler = new ClientHandler(PathString.Empty, new DummyApplication(context =>
|
||||
var handler = new ClientHandler(PathString.Empty, new DummyApplication(async context =>
|
||||
{
|
||||
context.Response.Headers["TestHeader"] = "TestValue";
|
||||
context.Response.Body.Flush();
|
||||
return block.Task;
|
||||
await context.Response.Body.FlushAsync();
|
||||
await block.Task;
|
||||
}));
|
||||
var httpClient = new HttpClient(handler);
|
||||
HttpResponseMessage response = await httpClient.GetAsync("https://example.com/",
|
||||
|
|
@ -327,11 +327,11 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
public async Task ClientCancellationAborts()
|
||||
{
|
||||
var block = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var handler = new ClientHandler(PathString.Empty, new DummyApplication(context =>
|
||||
var handler = new ClientHandler(PathString.Empty, new DummyApplication(async context =>
|
||||
{
|
||||
context.Response.Headers["TestHeader"] = "TestValue";
|
||||
context.Response.Body.Flush();
|
||||
return block.Task;
|
||||
await context.Response.Body.FlushAsync();
|
||||
await block.Task;
|
||||
}));
|
||||
var httpClient = new HttpClient(handler);
|
||||
HttpResponseMessage response = await httpClient.GetAsync("https://example.com/",
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
app.Run(async c =>
|
||||
{
|
||||
c.Response.Headers["TestHeader"] = "TestValue";
|
||||
c.Response.Body.Flush();
|
||||
await c.Response.Body.FlushAsync();
|
||||
await block.Task;
|
||||
await c.Response.WriteAsync("BodyFinished");
|
||||
});
|
||||
|
|
@ -198,7 +198,7 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
app.Run(async c =>
|
||||
{
|
||||
c.Response.Headers["TestHeader"] = "TestValue";
|
||||
c.Response.Body.Flush();
|
||||
await c.Response.Body.FlushAsync();
|
||||
await block.Task;
|
||||
await c.Response.WriteAsync("BodyFinished");
|
||||
});
|
||||
|
|
@ -247,7 +247,7 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
app.Run(async c =>
|
||||
{
|
||||
c.Response.Headers["TestHeader"] = "TestValue";
|
||||
c.Response.Body.Flush();
|
||||
await c.Response.Body.FlushAsync();
|
||||
await block.Task;
|
||||
await c.Response.WriteAsync("BodyFinished");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
|
@ -46,6 +48,80 @@ namespace Microsoft.AspNetCore.TestHost.Tests
|
|||
Assert.Equal(length, bytes.Length);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task BodyStream_SyncDisabled_WriteThrows()
|
||||
{
|
||||
var contentBytes = new byte[] {32};
|
||||
using var host = await CreateHost(async httpContext =>
|
||||
{
|
||||
await httpContext.Response.StartAsync();
|
||||
httpContext.Response.Body.Write(contentBytes, 0, contentBytes.Length);
|
||||
await httpContext.Response.CompleteAsync();
|
||||
});
|
||||
|
||||
var client = host.GetTestServer().CreateClient();
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(()=> client.GetAsync("/"));
|
||||
Assert.Contains("Synchronous operations are disallowed.", ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task BodyStream_SyncEnabled_WriteSucceeds()
|
||||
{
|
||||
var contentBytes = new byte[] {32};
|
||||
using var host = await CreateHost(async httpContext =>
|
||||
{
|
||||
await httpContext.Response.StartAsync();
|
||||
httpContext.Response.Body.Write(contentBytes, 0, contentBytes.Length);
|
||||
await httpContext.Response.CompleteAsync();
|
||||
});
|
||||
|
||||
host.GetTestServer().AllowSynchronousIO = true;
|
||||
|
||||
var client = host.GetTestServer().CreateClient();
|
||||
var response = await client.GetAsync("/");
|
||||
var responseBytes = await response.Content.ReadAsByteArrayAsync();
|
||||
Assert.Equal(contentBytes, responseBytes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task BodyStream_SyncDisabled_FlushThrows()
|
||||
{
|
||||
var contentBytes = new byte[] {32};
|
||||
using var host = await CreateHost(async httpContext =>
|
||||
{
|
||||
await httpContext.Response.StartAsync();
|
||||
await httpContext.Response.Body.WriteAsync(contentBytes, 0, contentBytes.Length);
|
||||
httpContext.Response.Body.Flush();
|
||||
await httpContext.Response.CompleteAsync();
|
||||
});
|
||||
|
||||
var client = host.GetTestServer().CreateClient();
|
||||
var requestException = await Assert.ThrowsAsync<HttpRequestException>(()=> client.GetAsync("/"));
|
||||
var ex = (InvalidOperationException) requestException?.InnerException?.InnerException;
|
||||
Assert.NotNull(ex);
|
||||
Assert.Contains("Synchronous operations are disallowed.", ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task BodyStream_SyncEnabled_FlushSucceeds()
|
||||
{
|
||||
var contentBytes = new byte[] {32};
|
||||
using var host = await CreateHost(async httpContext =>
|
||||
{
|
||||
await httpContext.Response.StartAsync();
|
||||
await httpContext.Response.Body.WriteAsync(contentBytes, 0, contentBytes.Length);
|
||||
httpContext.Response.Body.Flush();
|
||||
await httpContext.Response.CompleteAsync();
|
||||
});
|
||||
|
||||
host.GetTestServer().AllowSynchronousIO = true;
|
||||
|
||||
var client = host.GetTestServer().CreateClient();
|
||||
var response = await client.GetAsync("/");
|
||||
var responseBytes = await response.Content.ReadAsByteArrayAsync();
|
||||
Assert.Equal(contentBytes, responseBytes);
|
||||
}
|
||||
|
||||
private Task<IHost> CreateHost(RequestDelegate appDelegate)
|
||||
{
|
||||
return new HostBuilder()
|
||||
|
|
|
|||
|
|
@ -598,7 +598,10 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
});
|
||||
});
|
||||
|
||||
var server = new TestServer(builder);
|
||||
var server = new TestServer(builder)
|
||||
{
|
||||
AllowSynchronousIO = true // needed for synchronous flush
|
||||
};
|
||||
var client = server.CreateClient();
|
||||
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, "");
|
||||
|
|
|
|||
Loading…
Reference in New Issue