diff --git a/src/Microsoft.AspNetCore.Server.HttpSys/FeatureContext.cs b/src/Microsoft.AspNetCore.Server.HttpSys/FeatureContext.cs
index b2e41d46aa..9acef96deb 100644
--- a/src/Microsoft.AspNetCore.Server.HttpSys/FeatureContext.cs
+++ b/src/Microsoft.AspNetCore.Server.HttpSys/FeatureContext.cs
@@ -29,7 +29,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys
IHttpAuthenticationFeature,
IHttpUpgradeFeature,
IHttpRequestIdentifierFeature,
- IHttpMaxRequestBodySizeFeature
+ IHttpMaxRequestBodySizeFeature,
+ IHttpBodyControlFeature
{
private RequestContext _requestContext;
private IFeatureCollection _features;
@@ -464,6 +465,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
}
+ bool IHttpBodyControlFeature.AllowSynchronousIO
+ {
+ get => _requestContext.AllowSynchronousIO;
+ set => _requestContext.AllowSynchronousIO = value;
+ }
+
bool IHttpMaxRequestBodySizeFeature.IsReadOnly => Request.HasRequestBodyStarted;
long? IHttpMaxRequestBodySizeFeature.MaxRequestBodySize
diff --git a/src/Microsoft.AspNetCore.Server.HttpSys/HttpSysOptions.cs b/src/Microsoft.AspNetCore.Server.HttpSys/HttpSysOptions.cs
index 720eee3739..cf34e6e368 100644
--- a/src/Microsoft.AspNetCore.Server.HttpSys/HttpSysOptions.cs
+++ b/src/Microsoft.AspNetCore.Server.HttpSys/HttpSysOptions.cs
@@ -131,6 +131,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
}
+ ///
+ /// Gets or sets a value that controls whether synchronous IO is allowed for the HttpContext.Request.Body and HttpContext.Response.Body.
+ /// The default is `true`.
+ ///
+ public bool AllowSynchronousIO { get; set; } = true;
+
internal void Apply(UrlGroup urlGroup, RequestQueue requestQueue)
{
_urlGroup = urlGroup;
diff --git a/src/Microsoft.AspNetCore.Server.HttpSys/RequestProcessing/Request.cs b/src/Microsoft.AspNetCore.Server.HttpSys/RequestProcessing/Request.cs
index 0147b84f03..7e4ef322d6 100644
--- a/src/Microsoft.AspNetCore.Server.HttpSys/RequestProcessing/Request.cs
+++ b/src/Microsoft.AspNetCore.Server.HttpSys/RequestProcessing/Request.cs
@@ -23,6 +23,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
// private byte[] _referredTokenBindingId;
private BoundaryType _contentBoundaryType;
+
private long? _contentLength;
private RequestStream _nativeStream;
@@ -149,10 +150,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{
if (_nativeStream == null && HasEntityBody)
{
- _nativeStream = new RequestStream(RequestContext)
- {
- MaxSize = RequestContext.Server.Options.MaxRequestBodySize
- };
+ _nativeStream = new RequestStream(RequestContext);
}
return _nativeStream;
}
diff --git a/src/Microsoft.AspNetCore.Server.HttpSys/RequestProcessing/RequestContext.cs b/src/Microsoft.AspNetCore.Server.HttpSys/RequestProcessing/RequestContext.cs
index 22b3ca6b13..a57064fb55 100644
--- a/src/Microsoft.AspNetCore.Server.HttpSys/RequestProcessing/RequestContext.cs
+++ b/src/Microsoft.AspNetCore.Server.HttpSys/RequestProcessing/RequestContext.cs
@@ -30,6 +30,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
_memoryBlob = memoryBlob;
Request = new Request(this, _memoryBlob);
Response = new Response(this);
+ AllowSynchronousIO = server.Options.AllowSynchronousIO;
}
internal HttpSysListener Server { get; }
@@ -88,6 +89,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys
public bool IsUpgradableRequest => Request.IsUpgradable;
+ internal bool AllowSynchronousIO { get; set; }
+
public Task UpgradeAsync()
{
if (!IsUpgradableRequest)
diff --git a/src/Microsoft.AspNetCore.Server.HttpSys/RequestProcessing/RequestStream.cs b/src/Microsoft.AspNetCore.Server.HttpSys/RequestProcessing/RequestStream.cs
index ce7642dacf..baef4c5a9f 100644
--- a/src/Microsoft.AspNetCore.Server.HttpSys/RequestProcessing/RequestStream.cs
+++ b/src/Microsoft.AspNetCore.Server.HttpSys/RequestProcessing/RequestStream.cs
@@ -25,6 +25,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
internal RequestStream(RequestContext httpContext)
{
_requestContext = httpContext;
+ _maxSize = _requestContext.Server.Options.MaxRequestBodySize;
}
internal RequestContext RequestContext
@@ -111,6 +112,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys
public override unsafe int Read([In, Out] byte[] buffer, int offset, int size)
{
+ if (!RequestContext.AllowSynchronousIO)
+ {
+ throw new InvalidOperationException("Synchronous IO APIs are disabled, see AllowSynchronousIO.");
+ }
+
ValidateReadBuffer(buffer, offset, size);
CheckSizeLimit();
if (_closed)
diff --git a/src/Microsoft.AspNetCore.Server.HttpSys/RequestProcessing/ResponseBody.cs b/src/Microsoft.AspNetCore.Server.HttpSys/RequestProcessing/ResponseBody.cs
index 506bba99a7..35eb89c6e7 100644
--- a/src/Microsoft.AspNetCore.Server.HttpSys/RequestProcessing/ResponseBody.cs
+++ b/src/Microsoft.AspNetCore.Server.HttpSys/RequestProcessing/ResponseBody.cs
@@ -91,10 +91,16 @@ namespace Microsoft.AspNetCore.Server.HttpSys
// Send headers
public override void Flush()
{
+ if (!RequestContext.AllowSynchronousIO)
+ {
+ throw new InvalidOperationException("Synchronous IO APIs are disabled, see AllowSynchronousIO.");
+ }
+
if (_disposed)
{
return;
}
+
FlushInternal(endOfRequest: false);
}
@@ -449,9 +455,15 @@ namespace Microsoft.AspNetCore.Server.HttpSys
public override void Write(byte[] buffer, int offset, int count)
{
+ if (!RequestContext.AllowSynchronousIO)
+ {
+ throw new InvalidOperationException("Synchronous IO APIs are disabled, see AllowSynchronousIO.");
+ }
+
// Validates for null and bounds. Allows count == 0.
// TODO: Verbose log parameters
var data = new ArraySegment(buffer, offset, count);
+
CheckDisposed();
CheckWriteCount(count);
diff --git a/src/Microsoft.AspNetCore.Server.HttpSys/StandardFeatureCollection.cs b/src/Microsoft.AspNetCore.Server.HttpSys/StandardFeatureCollection.cs
index d0fa5789dc..0830de0fec 100644
--- a/src/Microsoft.AspNetCore.Server.HttpSys/StandardFeatureCollection.cs
+++ b/src/Microsoft.AspNetCore.Server.HttpSys/StandardFeatureCollection.cs
@@ -27,6 +27,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{ typeof(IHttpRequestIdentifierFeature), _identityFunc },
{ typeof(RequestContext), ctx => ctx.RequestContext },
{ typeof(IHttpMaxRequestBodySizeFeature), _identityFunc },
+ { typeof(IHttpBodyControlFeature), _identityFunc },
};
private readonly FeatureContext _featureContext;
diff --git a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/HttpsTests.cs b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/HttpsTests.cs
index 4291f00e6e..a4c16c785c 100644
--- a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/HttpsTests.cs
+++ b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/HttpsTests.cs
@@ -60,10 +60,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
string input = new StreamReader(context.Request.Body).ReadToEnd();
Assert.Equal("Hello World", input);
context.Response.ContentLength = 11;
- using (var writer = new StreamWriter(context.Response.Body))
- {
- writer.Write("Hello World");
- }
+ var writer = new StreamWriter(context.Response.Body);
+ await writer.WriteAsync("Hello World");
+ await writer.FlushAsync();
string response = await responseTask;
Assert.Equal("Hello World", response);
diff --git a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/OpaqueUpgradeTests.cs b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/OpaqueUpgradeTests.cs
index 26cc299f09..d749fdb285 100644
--- a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/OpaqueUpgradeTests.cs
+++ b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/OpaqueUpgradeTests.cs
@@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
byte[] body = Encoding.UTF8.GetBytes("Hello World");
- context.Response.Body.Write(body, 0, body.Length);
+ await context.Response.Body.WriteAsync(body, 0, body.Length);
Assert.Throws(() => context.Response.Headers["Upgrade"] = "WebSocket"); // Win8.1 blocks anything but WebSocket
await Assert.ThrowsAsync(async () => await context.UpgradeAsync());
diff --git a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/RequestBodyTests.cs b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/RequestBodyTests.cs
index b34cd35ed6..9ea7f4805f 100644
--- a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/RequestBodyTests.cs
+++ b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/RequestBodyTests.cs
@@ -16,6 +16,32 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
{
public class RequestBodyTests
{
+ [ConditionalFact]
+ public async Task RequestBody_SyncReadEnabledByDefault_ThrowsWhenDisabled()
+ {
+ string address;
+ using (var server = Utilities.CreateHttpServer(out address))
+ {
+ Task responseTask = SendRequestAsync(address, "Hello World");
+
+ Assert.True(server.Options.AllowSynchronousIO);
+
+ var context = await server.AcceptAsync(Utilities.DefaultTimeout);
+ byte[] input = new byte[100];
+
+ Assert.True(context.AllowSynchronousIO);
+ var read = context.Request.Body.Read(input, 0, input.Length);
+ context.Response.ContentLength = read;
+ context.Response.Body.Write(input, 0, read);
+
+ context.AllowSynchronousIO = false;
+ Assert.Throws(() => context.Request.Body.Read(input, 0, input.Length));
+
+ string response = await responseTask;
+ Assert.Equal("Hello World", response);
+ }
+ }
+
[ConditionalFact]
public async Task RequestBody_ReadSync_Success()
{
@@ -24,6 +50,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
{
Task responseTask = SendRequestAsync(address, "Hello World");
+ server.Options.AllowSynchronousIO = true;
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
byte[] input = new byte[100];
int read = context.Request.Body.Read(input, 0, input.Length);
@@ -81,6 +108,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
{
Task responseTask = SendRequestAsync(address, "Hello World");
+ server.Options.AllowSynchronousIO = true;
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
byte[] input = new byte[100];
Assert.Throws("buffer", () => context.Request.Body.Read(null, 0, 1));
@@ -106,6 +134,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
{
Task responseTask = SendRequestAsync(address, content);
+ server.Options.AllowSynchronousIO = true;
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
byte[] input = new byte[10];
int read = context.Request.Body.Read(input, 0, input.Length);
diff --git a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/ResponseBodyTests.cs b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/ResponseBodyTests.cs
index c3e681b848..c41ef371a7 100644
--- a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/ResponseBodyTests.cs
+++ b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/ResponseBodyTests.cs
@@ -16,6 +16,41 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
{
public class ResponseBodyTests
{
+ [ConditionalFact]
+ public async Task ResponseBody_SyncWriteEnabledByDefault_ThrowsWhenDisabled()
+ {
+ string address;
+ using (var server = Utilities.CreateHttpServer(out address))
+ {
+ var responseTask = SendRequestAsync(address);
+
+ var context = await server.AcceptAsync(Utilities.DefaultTimeout);
+
+ Assert.True(context.AllowSynchronousIO);
+
+ context.Response.Body.Flush();
+ context.Response.Body.Write(new byte[10], 0, 10);
+ context.Response.Body.Flush();
+
+ context.AllowSynchronousIO = false;
+
+ Assert.Throws(() => context.Response.Body.Flush());
+ Assert.Throws(() => context.Response.Body.Write(new byte[10], 0, 10));
+ Assert.Throws(() => context.Response.Body.Flush());
+
+ await context.Response.Body.WriteAsync(new byte[10], 0, 10);
+ context.Dispose();
+
+ var response = await responseTask;
+ Assert.Equal(200, (int)response.StatusCode);
+ Assert.Equal(new Version(1, 1), response.Version);
+ IEnumerable ignored;
+ Assert.False(response.Content.Headers.TryGetValues("content-length", out ignored), "Content-Length");
+ Assert.True(response.Headers.TransferEncodingChunked.Value, "Chunked");
+ Assert.Equal(new byte[20], await response.Content.ReadAsByteArrayAsync());
+ }
+ }
+
[ConditionalFact]
public async Task ResponseBody_WriteNoHeaders_DefaultsToChunked()
{
@@ -24,6 +59,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
{
var responseTask = SendRequestAsync(address);
+ server.Options.AllowSynchronousIO = true;
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
context.Response.Body.Write(new byte[10], 0, 10);
await context.Response.Body.WriteAsync(new byte[10], 0, 10);
@@ -45,6 +81,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
string address;
using (var server = Utilities.CreateHttpServer(out address))
{
+ server.Options.AllowSynchronousIO = true;
var responseTask = SendRequestAsync(address);
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
@@ -95,6 +132,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
{
var responseTask = SendRequestAsync(address);
+ server.Options.AllowSynchronousIO = true;
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
context.Response.Headers["Content-lenGth"] = " 30 ";
var stream = context.Response.Body;
@@ -181,6 +219,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
{
var responseTask = SendRequestAsync(address);
+ server.Options.AllowSynchronousIO = true;
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
context.Response.Headers["Content-lenGth"] = " 10 ";
context.Response.Body.Write(new byte[10], 0, 10);
@@ -206,6 +245,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
{
var responseTask = SendRequestAsync(address);
+ server.Options.AllowSynchronousIO = true;
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
context.Response.Body.Write(new byte[10], 0, 0);
Assert.True(context.Response.HasStarted);
@@ -380,6 +420,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
using (var server = Utilities.CreateHttpServer(out address))
{
server.Options.ThrowWriteExceptions = true;
+ server.Options.AllowSynchronousIO = true;
var cts = new CancellationTokenSource();
var responseTask = SendRequestAsync(address, cts.Token);
@@ -444,6 +485,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
var cts = new CancellationTokenSource();
var responseTask = SendRequestAsync(address, cts.Token);
+ server.Options.AllowSynchronousIO = true;
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
// First write sends headers
cts.Cancel();
@@ -555,6 +597,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
string address;
using (var server = Utilities.CreateHttpServer(out address))
{
+ server.Options.AllowSynchronousIO = true;
RequestContext context;
using (var client = new HttpClient())
{
diff --git a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/ResponseCachingTests.cs b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/ResponseCachingTests.cs
index 1505fd1dba..1ed657515e 100644
--- a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/ResponseCachingTests.cs
+++ b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/ResponseCachingTests.cs
@@ -324,7 +324,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
context.Response.ContentLength = 10;
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
- context.Response.Body.Write(new byte[10], 0, 10);
+ await context.Response.Body.WriteAsync(new byte[10], 0, 10);
// Http.Sys will add this for us
Assert.Null(context.Response.ContentLength);
context.Dispose();
@@ -381,6 +381,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
{
var responseTask = SendRequestAsync(address);
+ server.Options.AllowSynchronousIO = true;
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
context.Response.Headers["x-request-count"] = "1";
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
@@ -418,8 +419,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
context.Response.Headers["x-request-count"] = "1";
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
- context.Response.Body.Write(new byte[10], 0, 10);
- context.Response.Body.Flush();
+ await context.Response.Body.WriteAsync(new byte[10], 0, 10);
+ await context.Response.Body.FlushAsync();
context.Dispose();
var response = await responseTask;
@@ -453,7 +454,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
context.Response.ContentLength = 10;
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
- context.Response.Body.Write(new byte[10], 0, 10);
+ await context.Response.Body.WriteAsync(new byte[10], 0, 10);
// Http.Sys will add this for us
Assert.Null(context.Response.ContentLength);
context.Dispose();
@@ -999,7 +1000,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
context.Response.Headers["content-range"] = "bytes 0-10/100";
context.Response.ContentLength = 11;
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
- context.Response.Body.Write(new byte[100], 0, 11);
+ await context.Response.Body.WriteAsync(new byte[100], 0, 11);
context.Dispose();
var response = await responseTask;
@@ -1016,7 +1017,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
context.Response.Headers["content-range"] = "bytes 0-10/100";
context.Response.ContentLength = 11;
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
- context.Response.Body.Write(new byte[100], 0, 11);
+ await context.Response.Body.WriteAsync(new byte[100], 0, 11);
context.Dispose();
response = await responseTask;
@@ -1041,7 +1042,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
context.Response.ContentLength = 100;
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
- context.Response.Body.Write(new byte[100], 0, 100);
+ await context.Response.Body.WriteAsync(new byte[100], 0, 100);
context.Dispose();
var response = await responseTask;
@@ -1071,7 +1072,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
context.Response.ContentLength = 100;
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
- context.Response.Body.Write(new byte[100], 0, 100);
+ await context.Response.Body.WriteAsync(new byte[100], 0, 100);
context.Dispose();
var response = await responseTask;
diff --git a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/ResponseHeaderTests.cs b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/ResponseHeaderTests.cs
index 982024730e..66ecbd7e19 100644
--- a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/ResponseHeaderTests.cs
+++ b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/ResponseHeaderTests.cs
@@ -390,6 +390,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
{
Task responseTask = SendRequestAsync(address);
+ server.Options.AllowSynchronousIO = true;
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
var responseHeaders = context.Response.Headers;
diff --git a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/ServerTests.cs b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/ServerTests.cs
index cbd7000614..e12488f13e 100644
--- a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/ServerTests.cs
+++ b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/Listener/ServerTests.cs
@@ -42,10 +42,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
context.Response.ContentLength = 11;
- using (var writer = new StreamWriter(context.Response.Body))
- {
- writer.Write("Hello World");
- }
+ var writer = new StreamWriter(context.Response.Body);
+ await writer.WriteAsync("Hello World");
+ await writer.FlushAsync();
string response = await responseTask;
Assert.Equal("Hello World", response);
@@ -61,13 +60,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
var responseTask = SendRequestAsync(address, "Hello World");
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
- string input = new StreamReader(context.Request.Body).ReadToEnd();
+ var input = await new StreamReader(context.Request.Body).ReadToEndAsync();
Assert.Equal("Hello World", input);
context.Response.ContentLength = 11;
- using (var writer = new StreamWriter(context.Response.Body))
- {
- writer.Write("Hello World");
- }
+ var writer = new StreamWriter(context.Response.Body);
+ await writer.WriteAsync("Hello World");
+ await writer.FlushAsync();
var response = await responseTask;
Assert.Equal("Hello World", response);
@@ -218,10 +216,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
context.Response.Headers["Connection"] = "close";
context.Response.ContentLength = 11;
- using (var writer = new StreamWriter(context.Response.Body))
- {
- writer.Write("Hello World");
- }
+ var writer = new StreamWriter(context.Response.Body);
+ await writer.WriteAsync("Hello World");
+ await writer.FlushAsync();
Assert.True(canceled.WaitOne(interval), "Disconnected");
Assert.True(ct.IsCancellationRequested, "IsCancellationRequested");
diff --git a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/OpaqueUpgradeTests.cs b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/OpaqueUpgradeTests.cs
index 48421ddcaa..a37daceb04 100644
--- a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/OpaqueUpgradeTests.cs
+++ b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/OpaqueUpgradeTests.cs
@@ -123,7 +123,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
Assert.True(feature.IsReadOnly);
Assert.Null(feature.MaxRequestBodySize);
Assert.Throws(() => feature.MaxRequestBodySize = 12);
- Assert.Equal(15, stream.Read(new byte[15], 0, 15));
+ Assert.Equal(15, await stream.ReadAsync(new byte[15], 0, 15));
upgraded = true;
waitHandle.Set();
}))
@@ -131,7 +131,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
using (Stream stream = await SendOpaqueRequestAsync("GET", address))
{
stream.Write(new byte[15], 0, 15);
- Assert.True(waitHandle.WaitOne(TimeSpan.FromSeconds(1)), "Timed out");
+ Assert.True(waitHandle.WaitOne(TimeSpan.FromSeconds(10)), "Timed out");
Assert.True(upgraded.HasValue, "Upgraded not set");
Assert.True(upgraded.Value, "Upgrade failed");
}
diff --git a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/RequestBodyLimitTests.cs b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/RequestBodyLimitTests.cs
index ed835f345f..ebc0fa9f98 100644
--- a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/RequestBodyLimitTests.cs
+++ b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/RequestBodyLimitTests.cs
@@ -21,6 +21,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
string address;
using (Utilities.CreateHttpServer(out address, options => options.MaxRequestBodySize = 11, httpContext =>
{
+ httpContext.Features.Get().AllowSynchronousIO = true;
var feature = httpContext.Features.Get();
Assert.NotNull(feature);
Assert.False(feature.IsReadOnly);
@@ -86,6 +87,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
string address;
using (Utilities.CreateHttpServer(out address, options => options.MaxRequestBodySize = 11, httpContext =>
{
+ httpContext.Features.Get().AllowSynchronousIO = true;
var feature = httpContext.Features.Get();
Assert.NotNull(feature);
Assert.False(feature.IsReadOnly);
@@ -151,6 +153,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
string address;
using (Utilities.CreateHttpServer(out address, options => options.MaxRequestBodySize = 10, httpContext =>
{
+ httpContext.Features.Get().AllowSynchronousIO = true;
var feature = httpContext.Features.Get();
Assert.NotNull(feature);
Assert.False(feature.IsReadOnly);
@@ -220,6 +223,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
string address;
using (Utilities.CreateHttpServer(out address, options => options.MaxRequestBodySize = 10, httpContext =>
{
+ httpContext.Features.Get().AllowSynchronousIO = true;
var feature = httpContext.Features.Get();
Assert.NotNull(feature);
Assert.False(feature.IsReadOnly);
@@ -290,6 +294,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
string address;
using (Utilities.CreateHttpServer(out address, options => options.MaxRequestBodySize = 10, httpContext =>
{
+ httpContext.Features.Get().AllowSynchronousIO = true;
var feature = httpContext.Features.Get();
Assert.NotNull(feature);
Assert.False(feature.IsReadOnly);
diff --git a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/RequestBodyTests.cs b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/RequestBodyTests.cs
index 23c7c56be1..1b87920103 100644
--- a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/RequestBodyTests.cs
+++ b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/RequestBodyTests.cs
@@ -9,6 +9,7 @@ using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Testing.xunit;
using Xunit;
@@ -23,6 +24,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
using (Utilities.CreateHttpServer(out address, httpContext =>
{
byte[] input = new byte[100];
+ httpContext.Features.Get().AllowSynchronousIO = true;
int read = httpContext.Request.Body.Read(input, 0, input.Length);
httpContext.Response.ContentLength = read;
httpContext.Response.Body.Write(input, 0, read);
@@ -75,6 +77,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
string address;
using (Utilities.CreateHttpServer(out address, httpContext =>
{
+ httpContext.Features.Get().AllowSynchronousIO = true;
byte[] input = new byte[100];
Assert.Throws("buffer", () => httpContext.Request.Body.Read(null, 0, 1));
Assert.Throws("offset", () => httpContext.Request.Body.Read(input, -1, 1));
@@ -99,6 +102,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
using (Utilities.CreateHttpServer(out address, httpContext =>
{
byte[] input = new byte[10];
+ httpContext.Features.Get().AllowSynchronousIO = true;
int read = httpContext.Request.Body.Read(input, 0, input.Length);
Assert.Equal(5, read);
content.Block.Release();
diff --git a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/ResponseBodyTests.cs b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/ResponseBodyTests.cs
index 18dee99410..4c3089edea 100644
--- a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/ResponseBodyTests.cs
+++ b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/ResponseBodyTests.cs
@@ -9,6 +9,7 @@ using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Testing.xunit;
using Xunit;
@@ -22,6 +23,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
string address;
using (Utilities.CreateHttpServer(out address, httpContext =>
{
+ httpContext.Features.Get().AllowSynchronousIO = true;
httpContext.Response.Body.Write(new byte[10], 0, 10);
return httpContext.Response.Body.WriteAsync(new byte[10], 0, 10);
}))
@@ -42,6 +44,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
string address;
using (Utilities.CreateHttpServer(out address, async httpContext =>
{
+ httpContext.Features.Get().AllowSynchronousIO = true;
httpContext.Response.Body.Write(new byte[10], 0, 10);
await httpContext.Response.Body.WriteAsync(new byte[10], 0, 10);
await httpContext.Response.Body.FlushAsync();
@@ -85,6 +88,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
string address;
using (Utilities.CreateHttpServer(out address, async httpContext =>
{
+ httpContext.Features.Get().AllowSynchronousIO = true;
httpContext.Response.Headers["Content-lenGth"] = " 30 ";
Stream stream = httpContext.Response.Body;
stream.EndWrite(stream.BeginWrite(new byte[10], 0, 10, null, null));
@@ -124,8 +128,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
using (Utilities.CreateHttpServer(out address, httpContext =>
{
httpContext.Response.Headers["Content-lenGth"] = " 20 ";
- httpContext.Response.Body.Write(new byte[5], 0, 5);
- return Task.FromResult(0);
+ return httpContext.Response.Body.WriteAsync(new byte[5], 0, 5);
}))
{
Assert.Throws(() => SendRequestAsync(address).Result);
@@ -137,13 +140,13 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{
var completed = false;
string address;
- using (Utilities.CreateHttpServer(out address, httpContext =>
+ using (Utilities.CreateHttpServer(out address, async httpContext =>
{
httpContext.Response.Headers["Content-lenGth"] = " 10 ";
- httpContext.Response.Body.Write(new byte[5], 0, 5);
- Assert.Throws(() => httpContext.Response.Body.Write(new byte[6], 0, 6));
+ await httpContext.Response.Body.WriteAsync(new byte[5], 0, 5);
+ await Assert.ThrowsAsync(() =>
+ httpContext.Response.Body.WriteAsync(new byte[6], 0, 6));
completed = true;
- return Task.FromResult(0);
}))
{
await Assert.ThrowsAsync(() => SendRequestAsync(address));
@@ -161,6 +164,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{
try
{
+ httpContext.Features.Get().AllowSynchronousIO = true;
httpContext.Response.Headers["Content-lenGth"] = " 10 ";
httpContext.Response.Body.Write(new byte[10], 0, 10);
httpContext.Response.Body.Write(new byte[9], 0, 9);
@@ -197,6 +201,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
string address;
using (Utilities.CreateHttpServer(out address, httpContext =>
{
+ httpContext.Features.Get().AllowSynchronousIO = true;
httpContext.Response.OnStarting(state =>
{
onStartingCalled = true;
diff --git a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/ResponseHeaderTests.cs b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/ResponseHeaderTests.cs
index 96b112ae59..0b169e906e 100644
--- a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/ResponseHeaderTests.cs
+++ b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/ResponseHeaderTests.cs
@@ -130,8 +130,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
var responseInfo = httpContext.Features.Get();
var responseHeaders = responseInfo.Headers;
responseHeaders["Connection"] = new string[] { "Close" };
- httpContext.Response.Body.Flush(); // Http.Sys adds the Content-Length: header for us if we don't flush
- return Task.FromResult(0);
+ return httpContext.Response.Body.FlushAsync(); // Http.Sys adds the Content-Length: header for us if we don't flush
}))
{
HttpResponseMessage response = await SendRequestAsync(address);
@@ -204,6 +203,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
string address;
using (Utilities.CreateHttpServer(out address, httpContext =>
{
+ httpContext.Features.Get().AllowSynchronousIO = true;
var responseInfo = httpContext.Features.Get();
var responseHeaders = responseInfo.Headers;
responseHeaders.Add("Custom1", new string[] { "value1a", "value1b" });
diff --git a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/ServerTests.cs b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/ServerTests.cs
index 4d8129d7f4..01224b2bc6 100644
--- a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/ServerTests.cs
+++ b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/ServerTests.cs
@@ -53,12 +53,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys
public async Task Server_EchoHelloWorld_Success()
{
string address;
- using (Utilities.CreateHttpServer(out address, httpContext =>
+ using (Utilities.CreateHttpServer(out address, async httpContext =>
{
- string input = new StreamReader(httpContext.Request.Body).ReadToEnd();
+ var input = await new StreamReader(httpContext.Request.Body).ReadToEndAsync();
Assert.Equal("Hello World", input);
httpContext.Response.ContentLength = 11;
- return httpContext.Response.WriteAsync("Hello World");
+ await httpContext.Response.WriteAsync("Hello World");
}))
{
string response = await SendRequestAsync(address, "Hello World");