#366 Add flag to disable synchronous IO
This commit is contained in:
parent
ac4157c627
commit
13b867a90e
|
|
@ -29,7 +29,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
IHttpAuthenticationFeature,
|
IHttpAuthenticationFeature,
|
||||||
IHttpUpgradeFeature,
|
IHttpUpgradeFeature,
|
||||||
IHttpRequestIdentifierFeature,
|
IHttpRequestIdentifierFeature,
|
||||||
IHttpMaxRequestBodySizeFeature
|
IHttpMaxRequestBodySizeFeature,
|
||||||
|
IHttpBodyControlFeature
|
||||||
{
|
{
|
||||||
private RequestContext _requestContext;
|
private RequestContext _requestContext;
|
||||||
private IFeatureCollection _features;
|
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;
|
bool IHttpMaxRequestBodySizeFeature.IsReadOnly => Request.HasRequestBodyStarted;
|
||||||
|
|
||||||
long? IHttpMaxRequestBodySizeFeature.MaxRequestBodySize
|
long? IHttpMaxRequestBodySizeFeature.MaxRequestBodySize
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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`.
|
||||||
|
/// </summary>
|
||||||
|
public bool AllowSynchronousIO { get; set; } = true;
|
||||||
|
|
||||||
internal void Apply(UrlGroup urlGroup, RequestQueue requestQueue)
|
internal void Apply(UrlGroup urlGroup, RequestQueue requestQueue)
|
||||||
{
|
{
|
||||||
_urlGroup = urlGroup;
|
_urlGroup = urlGroup;
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
// private byte[] _referredTokenBindingId;
|
// private byte[] _referredTokenBindingId;
|
||||||
|
|
||||||
private BoundaryType _contentBoundaryType;
|
private BoundaryType _contentBoundaryType;
|
||||||
|
|
||||||
private long? _contentLength;
|
private long? _contentLength;
|
||||||
private RequestStream _nativeStream;
|
private RequestStream _nativeStream;
|
||||||
|
|
||||||
|
|
@ -149,10 +150,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
{
|
{
|
||||||
if (_nativeStream == null && HasEntityBody)
|
if (_nativeStream == null && HasEntityBody)
|
||||||
{
|
{
|
||||||
_nativeStream = new RequestStream(RequestContext)
|
_nativeStream = new RequestStream(RequestContext);
|
||||||
{
|
|
||||||
MaxSize = RequestContext.Server.Options.MaxRequestBodySize
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
return _nativeStream;
|
return _nativeStream;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
_memoryBlob = memoryBlob;
|
_memoryBlob = memoryBlob;
|
||||||
Request = new Request(this, _memoryBlob);
|
Request = new Request(this, _memoryBlob);
|
||||||
Response = new Response(this);
|
Response = new Response(this);
|
||||||
|
AllowSynchronousIO = server.Options.AllowSynchronousIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal HttpSysListener Server { get; }
|
internal HttpSysListener Server { get; }
|
||||||
|
|
@ -88,6 +89,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
|
|
||||||
public bool IsUpgradableRequest => Request.IsUpgradable;
|
public bool IsUpgradableRequest => Request.IsUpgradable;
|
||||||
|
|
||||||
|
internal bool AllowSynchronousIO { get; set; }
|
||||||
|
|
||||||
public Task<Stream> UpgradeAsync()
|
public Task<Stream> UpgradeAsync()
|
||||||
{
|
{
|
||||||
if (!IsUpgradableRequest)
|
if (!IsUpgradableRequest)
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
internal RequestStream(RequestContext httpContext)
|
internal RequestStream(RequestContext httpContext)
|
||||||
{
|
{
|
||||||
_requestContext = httpContext;
|
_requestContext = httpContext;
|
||||||
|
_maxSize = _requestContext.Server.Options.MaxRequestBodySize;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal RequestContext RequestContext
|
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)
|
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);
|
ValidateReadBuffer(buffer, offset, size);
|
||||||
CheckSizeLimit();
|
CheckSizeLimit();
|
||||||
if (_closed)
|
if (_closed)
|
||||||
|
|
|
||||||
|
|
@ -91,10 +91,16 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
// Send headers
|
// Send headers
|
||||||
public override void Flush()
|
public override void Flush()
|
||||||
{
|
{
|
||||||
|
if (!RequestContext.AllowSynchronousIO)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Synchronous IO APIs are disabled, see AllowSynchronousIO.");
|
||||||
|
}
|
||||||
|
|
||||||
if (_disposed)
|
if (_disposed)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FlushInternal(endOfRequest: false);
|
FlushInternal(endOfRequest: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -449,9 +455,15 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
|
|
||||||
public override void Write(byte[] buffer, int offset, int count)
|
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.
|
// Validates for null and bounds. Allows count == 0.
|
||||||
// TODO: Verbose log parameters
|
// TODO: Verbose log parameters
|
||||||
var data = new ArraySegment<byte>(buffer, offset, count);
|
var data = new ArraySegment<byte>(buffer, offset, count);
|
||||||
|
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
||||||
CheckWriteCount(count);
|
CheckWriteCount(count);
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
{ typeof(IHttpRequestIdentifierFeature), _identityFunc },
|
{ typeof(IHttpRequestIdentifierFeature), _identityFunc },
|
||||||
{ typeof(RequestContext), ctx => ctx.RequestContext },
|
{ typeof(RequestContext), ctx => ctx.RequestContext },
|
||||||
{ typeof(IHttpMaxRequestBodySizeFeature), _identityFunc },
|
{ typeof(IHttpMaxRequestBodySizeFeature), _identityFunc },
|
||||||
|
{ typeof(IHttpBodyControlFeature), _identityFunc },
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly FeatureContext _featureContext;
|
private readonly FeatureContext _featureContext;
|
||||||
|
|
|
||||||
|
|
@ -60,10 +60,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||||
string input = new StreamReader(context.Request.Body).ReadToEnd();
|
string input = new StreamReader(context.Request.Body).ReadToEnd();
|
||||||
Assert.Equal("Hello World", input);
|
Assert.Equal("Hello World", input);
|
||||||
context.Response.ContentLength = 11;
|
context.Response.ContentLength = 11;
|
||||||
using (var writer = new StreamWriter(context.Response.Body))
|
var writer = new StreamWriter(context.Response.Body);
|
||||||
{
|
await writer.WriteAsync("Hello World");
|
||||||
writer.Write("Hello World");
|
await writer.FlushAsync();
|
||||||
}
|
|
||||||
|
|
||||||
string response = await responseTask;
|
string response = await responseTask;
|
||||||
Assert.Equal("Hello World", response);
|
Assert.Equal("Hello World", response);
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||||
|
|
||||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||||
byte[] body = Encoding.UTF8.GetBytes("Hello World");
|
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<InvalidOperationException>(() => context.Response.Headers["Upgrade"] = "WebSocket"); // Win8.1 blocks anything but WebSocket
|
Assert.Throws<InvalidOperationException>(() => context.Response.Headers["Upgrade"] = "WebSocket"); // Win8.1 blocks anything but WebSocket
|
||||||
await Assert.ThrowsAsync<InvalidOperationException>(async () => await context.UpgradeAsync());
|
await Assert.ThrowsAsync<InvalidOperationException>(async () => await context.UpgradeAsync());
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,32 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||||
{
|
{
|
||||||
public class RequestBodyTests
|
public class RequestBodyTests
|
||||||
{
|
{
|
||||||
|
[ConditionalFact]
|
||||||
|
public async Task RequestBody_SyncReadEnabledByDefault_ThrowsWhenDisabled()
|
||||||
|
{
|
||||||
|
string address;
|
||||||
|
using (var server = Utilities.CreateHttpServer(out address))
|
||||||
|
{
|
||||||
|
Task<string> 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<InvalidOperationException>(() => context.Request.Body.Read(input, 0, input.Length));
|
||||||
|
|
||||||
|
string response = await responseTask;
|
||||||
|
Assert.Equal("Hello World", response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[ConditionalFact]
|
[ConditionalFact]
|
||||||
public async Task RequestBody_ReadSync_Success()
|
public async Task RequestBody_ReadSync_Success()
|
||||||
{
|
{
|
||||||
|
|
@ -24,6 +50,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||||
{
|
{
|
||||||
Task<string> responseTask = SendRequestAsync(address, "Hello World");
|
Task<string> responseTask = SendRequestAsync(address, "Hello World");
|
||||||
|
|
||||||
|
server.Options.AllowSynchronousIO = true;
|
||||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||||
byte[] input = new byte[100];
|
byte[] input = new byte[100];
|
||||||
int read = context.Request.Body.Read(input, 0, input.Length);
|
int read = context.Request.Body.Read(input, 0, input.Length);
|
||||||
|
|
@ -81,6 +108,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||||
{
|
{
|
||||||
Task<string> responseTask = SendRequestAsync(address, "Hello World");
|
Task<string> responseTask = SendRequestAsync(address, "Hello World");
|
||||||
|
|
||||||
|
server.Options.AllowSynchronousIO = true;
|
||||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||||
byte[] input = new byte[100];
|
byte[] input = new byte[100];
|
||||||
Assert.Throws<ArgumentNullException>("buffer", () => context.Request.Body.Read(null, 0, 1));
|
Assert.Throws<ArgumentNullException>("buffer", () => context.Request.Body.Read(null, 0, 1));
|
||||||
|
|
@ -106,6 +134,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||||
{
|
{
|
||||||
Task<string> responseTask = SendRequestAsync(address, content);
|
Task<string> responseTask = SendRequestAsync(address, content);
|
||||||
|
|
||||||
|
server.Options.AllowSynchronousIO = true;
|
||||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||||
byte[] input = new byte[10];
|
byte[] input = new byte[10];
|
||||||
int read = context.Request.Body.Read(input, 0, input.Length);
|
int read = context.Request.Body.Read(input, 0, input.Length);
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,41 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||||
{
|
{
|
||||||
public class ResponseBodyTests
|
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<InvalidOperationException>(() => context.Response.Body.Flush());
|
||||||
|
Assert.Throws<InvalidOperationException>(() => context.Response.Body.Write(new byte[10], 0, 10));
|
||||||
|
Assert.Throws<InvalidOperationException>(() => 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<string> 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]
|
[ConditionalFact]
|
||||||
public async Task ResponseBody_WriteNoHeaders_DefaultsToChunked()
|
public async Task ResponseBody_WriteNoHeaders_DefaultsToChunked()
|
||||||
{
|
{
|
||||||
|
|
@ -24,6 +59,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||||
{
|
{
|
||||||
var responseTask = SendRequestAsync(address);
|
var responseTask = SendRequestAsync(address);
|
||||||
|
|
||||||
|
server.Options.AllowSynchronousIO = true;
|
||||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||||
context.Response.Body.Write(new byte[10], 0, 10);
|
context.Response.Body.Write(new byte[10], 0, 10);
|
||||||
await context.Response.Body.WriteAsync(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;
|
string address;
|
||||||
using (var server = Utilities.CreateHttpServer(out address))
|
using (var server = Utilities.CreateHttpServer(out address))
|
||||||
{
|
{
|
||||||
|
server.Options.AllowSynchronousIO = true;
|
||||||
var responseTask = SendRequestAsync(address);
|
var responseTask = SendRequestAsync(address);
|
||||||
|
|
||||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||||
|
|
@ -95,6 +132,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||||
{
|
{
|
||||||
var responseTask = SendRequestAsync(address);
|
var responseTask = SendRequestAsync(address);
|
||||||
|
|
||||||
|
server.Options.AllowSynchronousIO = true;
|
||||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||||
context.Response.Headers["Content-lenGth"] = " 30 ";
|
context.Response.Headers["Content-lenGth"] = " 30 ";
|
||||||
var stream = context.Response.Body;
|
var stream = context.Response.Body;
|
||||||
|
|
@ -181,6 +219,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||||
{
|
{
|
||||||
var responseTask = SendRequestAsync(address);
|
var responseTask = SendRequestAsync(address);
|
||||||
|
|
||||||
|
server.Options.AllowSynchronousIO = true;
|
||||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||||
context.Response.Headers["Content-lenGth"] = " 10 ";
|
context.Response.Headers["Content-lenGth"] = " 10 ";
|
||||||
context.Response.Body.Write(new byte[10], 0, 10);
|
context.Response.Body.Write(new byte[10], 0, 10);
|
||||||
|
|
@ -206,6 +245,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||||
{
|
{
|
||||||
var responseTask = SendRequestAsync(address);
|
var responseTask = SendRequestAsync(address);
|
||||||
|
|
||||||
|
server.Options.AllowSynchronousIO = true;
|
||||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||||
context.Response.Body.Write(new byte[10], 0, 0);
|
context.Response.Body.Write(new byte[10], 0, 0);
|
||||||
Assert.True(context.Response.HasStarted);
|
Assert.True(context.Response.HasStarted);
|
||||||
|
|
@ -380,6 +420,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||||
using (var server = Utilities.CreateHttpServer(out address))
|
using (var server = Utilities.CreateHttpServer(out address))
|
||||||
{
|
{
|
||||||
server.Options.ThrowWriteExceptions = true;
|
server.Options.ThrowWriteExceptions = true;
|
||||||
|
server.Options.AllowSynchronousIO = true;
|
||||||
var cts = new CancellationTokenSource();
|
var cts = new CancellationTokenSource();
|
||||||
var responseTask = SendRequestAsync(address, cts.Token);
|
var responseTask = SendRequestAsync(address, cts.Token);
|
||||||
|
|
||||||
|
|
@ -444,6 +485,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||||
var cts = new CancellationTokenSource();
|
var cts = new CancellationTokenSource();
|
||||||
var responseTask = SendRequestAsync(address, cts.Token);
|
var responseTask = SendRequestAsync(address, cts.Token);
|
||||||
|
|
||||||
|
server.Options.AllowSynchronousIO = true;
|
||||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||||
// First write sends headers
|
// First write sends headers
|
||||||
cts.Cancel();
|
cts.Cancel();
|
||||||
|
|
@ -555,6 +597,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||||
string address;
|
string address;
|
||||||
using (var server = Utilities.CreateHttpServer(out address))
|
using (var server = Utilities.CreateHttpServer(out address))
|
||||||
{
|
{
|
||||||
|
server.Options.AllowSynchronousIO = true;
|
||||||
RequestContext context;
|
RequestContext context;
|
||||||
using (var client = new HttpClient())
|
using (var client = new HttpClient())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||||
context.Response.ContentLength = 10;
|
context.Response.ContentLength = 10;
|
||||||
context.Response.CacheTtl = TimeSpan.FromSeconds(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
|
// Http.Sys will add this for us
|
||||||
Assert.Null(context.Response.ContentLength);
|
Assert.Null(context.Response.ContentLength);
|
||||||
context.Dispose();
|
context.Dispose();
|
||||||
|
|
@ -381,6 +381,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||||
{
|
{
|
||||||
var responseTask = SendRequestAsync(address);
|
var responseTask = SendRequestAsync(address);
|
||||||
|
|
||||||
|
server.Options.AllowSynchronousIO = true;
|
||||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||||
context.Response.Headers["x-request-count"] = "1";
|
context.Response.Headers["x-request-count"] = "1";
|
||||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
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["x-request-count"] = "1";
|
||||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||||
context.Response.CacheTtl = TimeSpan.FromSeconds(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);
|
||||||
context.Response.Body.Flush();
|
await context.Response.Body.FlushAsync();
|
||||||
context.Dispose();
|
context.Dispose();
|
||||||
|
|
||||||
var response = await responseTask;
|
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.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||||
context.Response.ContentLength = 10;
|
context.Response.ContentLength = 10;
|
||||||
context.Response.CacheTtl = TimeSpan.FromSeconds(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
|
// Http.Sys will add this for us
|
||||||
Assert.Null(context.Response.ContentLength);
|
Assert.Null(context.Response.ContentLength);
|
||||||
context.Dispose();
|
context.Dispose();
|
||||||
|
|
@ -999,7 +1000,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||||
context.Response.Headers["content-range"] = "bytes 0-10/100";
|
context.Response.Headers["content-range"] = "bytes 0-10/100";
|
||||||
context.Response.ContentLength = 11;
|
context.Response.ContentLength = 11;
|
||||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
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();
|
context.Dispose();
|
||||||
|
|
||||||
var response = await responseTask;
|
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.Headers["content-range"] = "bytes 0-10/100";
|
||||||
context.Response.ContentLength = 11;
|
context.Response.ContentLength = 11;
|
||||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
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();
|
context.Dispose();
|
||||||
|
|
||||||
response = await responseTask;
|
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.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||||
context.Response.ContentLength = 100;
|
context.Response.ContentLength = 100;
|
||||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
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();
|
context.Dispose();
|
||||||
|
|
||||||
var response = await responseTask;
|
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.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||||
context.Response.ContentLength = 100;
|
context.Response.ContentLength = 100;
|
||||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
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();
|
context.Dispose();
|
||||||
|
|
||||||
var response = await responseTask;
|
var response = await responseTask;
|
||||||
|
|
|
||||||
|
|
@ -390,6 +390,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||||
{
|
{
|
||||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
|
Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
|
||||||
|
|
||||||
|
server.Options.AllowSynchronousIO = true;
|
||||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||||
var responseHeaders = context.Response.Headers;
|
var responseHeaders = context.Response.Headers;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,10 +42,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||||
|
|
||||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||||
context.Response.ContentLength = 11;
|
context.Response.ContentLength = 11;
|
||||||
using (var writer = new StreamWriter(context.Response.Body))
|
var writer = new StreamWriter(context.Response.Body);
|
||||||
{
|
await writer.WriteAsync("Hello World");
|
||||||
writer.Write("Hello World");
|
await writer.FlushAsync();
|
||||||
}
|
|
||||||
|
|
||||||
string response = await responseTask;
|
string response = await responseTask;
|
||||||
Assert.Equal("Hello World", response);
|
Assert.Equal("Hello World", response);
|
||||||
|
|
@ -61,13 +60,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||||
var responseTask = SendRequestAsync(address, "Hello World");
|
var responseTask = SendRequestAsync(address, "Hello World");
|
||||||
|
|
||||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
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);
|
Assert.Equal("Hello World", input);
|
||||||
context.Response.ContentLength = 11;
|
context.Response.ContentLength = 11;
|
||||||
using (var writer = new StreamWriter(context.Response.Body))
|
var writer = new StreamWriter(context.Response.Body);
|
||||||
{
|
await writer.WriteAsync("Hello World");
|
||||||
writer.Write("Hello World");
|
await writer.FlushAsync();
|
||||||
}
|
|
||||||
|
|
||||||
var response = await responseTask;
|
var response = await responseTask;
|
||||||
Assert.Equal("Hello World", response);
|
Assert.Equal("Hello World", response);
|
||||||
|
|
@ -218,10 +216,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||||
context.Response.Headers["Connection"] = "close";
|
context.Response.Headers["Connection"] = "close";
|
||||||
|
|
||||||
context.Response.ContentLength = 11;
|
context.Response.ContentLength = 11;
|
||||||
using (var writer = new StreamWriter(context.Response.Body))
|
var writer = new StreamWriter(context.Response.Body);
|
||||||
{
|
await writer.WriteAsync("Hello World");
|
||||||
writer.Write("Hello World");
|
await writer.FlushAsync();
|
||||||
}
|
|
||||||
|
|
||||||
Assert.True(canceled.WaitOne(interval), "Disconnected");
|
Assert.True(canceled.WaitOne(interval), "Disconnected");
|
||||||
Assert.True(ct.IsCancellationRequested, "IsCancellationRequested");
|
Assert.True(ct.IsCancellationRequested, "IsCancellationRequested");
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
Assert.True(feature.IsReadOnly);
|
Assert.True(feature.IsReadOnly);
|
||||||
Assert.Null(feature.MaxRequestBodySize);
|
Assert.Null(feature.MaxRequestBodySize);
|
||||||
Assert.Throws<InvalidOperationException>(() => feature.MaxRequestBodySize = 12);
|
Assert.Throws<InvalidOperationException>(() => 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;
|
upgraded = true;
|
||||||
waitHandle.Set();
|
waitHandle.Set();
|
||||||
}))
|
}))
|
||||||
|
|
@ -131,7 +131,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
using (Stream stream = await SendOpaqueRequestAsync("GET", address))
|
using (Stream stream = await SendOpaqueRequestAsync("GET", address))
|
||||||
{
|
{
|
||||||
stream.Write(new byte[15], 0, 15);
|
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.HasValue, "Upgraded not set");
|
||||||
Assert.True(upgraded.Value, "Upgrade failed");
|
Assert.True(upgraded.Value, "Upgrade failed");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
string address;
|
string address;
|
||||||
using (Utilities.CreateHttpServer(out address, options => options.MaxRequestBodySize = 11, httpContext =>
|
using (Utilities.CreateHttpServer(out address, options => options.MaxRequestBodySize = 11, httpContext =>
|
||||||
{
|
{
|
||||||
|
httpContext.Features.Get<IHttpBodyControlFeature>().AllowSynchronousIO = true;
|
||||||
var feature = httpContext.Features.Get<IHttpMaxRequestBodySizeFeature>();
|
var feature = httpContext.Features.Get<IHttpMaxRequestBodySizeFeature>();
|
||||||
Assert.NotNull(feature);
|
Assert.NotNull(feature);
|
||||||
Assert.False(feature.IsReadOnly);
|
Assert.False(feature.IsReadOnly);
|
||||||
|
|
@ -86,6 +87,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
string address;
|
string address;
|
||||||
using (Utilities.CreateHttpServer(out address, options => options.MaxRequestBodySize = 11, httpContext =>
|
using (Utilities.CreateHttpServer(out address, options => options.MaxRequestBodySize = 11, httpContext =>
|
||||||
{
|
{
|
||||||
|
httpContext.Features.Get<IHttpBodyControlFeature>().AllowSynchronousIO = true;
|
||||||
var feature = httpContext.Features.Get<IHttpMaxRequestBodySizeFeature>();
|
var feature = httpContext.Features.Get<IHttpMaxRequestBodySizeFeature>();
|
||||||
Assert.NotNull(feature);
|
Assert.NotNull(feature);
|
||||||
Assert.False(feature.IsReadOnly);
|
Assert.False(feature.IsReadOnly);
|
||||||
|
|
@ -151,6 +153,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
string address;
|
string address;
|
||||||
using (Utilities.CreateHttpServer(out address, options => options.MaxRequestBodySize = 10, httpContext =>
|
using (Utilities.CreateHttpServer(out address, options => options.MaxRequestBodySize = 10, httpContext =>
|
||||||
{
|
{
|
||||||
|
httpContext.Features.Get<IHttpBodyControlFeature>().AllowSynchronousIO = true;
|
||||||
var feature = httpContext.Features.Get<IHttpMaxRequestBodySizeFeature>();
|
var feature = httpContext.Features.Get<IHttpMaxRequestBodySizeFeature>();
|
||||||
Assert.NotNull(feature);
|
Assert.NotNull(feature);
|
||||||
Assert.False(feature.IsReadOnly);
|
Assert.False(feature.IsReadOnly);
|
||||||
|
|
@ -220,6 +223,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
string address;
|
string address;
|
||||||
using (Utilities.CreateHttpServer(out address, options => options.MaxRequestBodySize = 10, httpContext =>
|
using (Utilities.CreateHttpServer(out address, options => options.MaxRequestBodySize = 10, httpContext =>
|
||||||
{
|
{
|
||||||
|
httpContext.Features.Get<IHttpBodyControlFeature>().AllowSynchronousIO = true;
|
||||||
var feature = httpContext.Features.Get<IHttpMaxRequestBodySizeFeature>();
|
var feature = httpContext.Features.Get<IHttpMaxRequestBodySizeFeature>();
|
||||||
Assert.NotNull(feature);
|
Assert.NotNull(feature);
|
||||||
Assert.False(feature.IsReadOnly);
|
Assert.False(feature.IsReadOnly);
|
||||||
|
|
@ -290,6 +294,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
string address;
|
string address;
|
||||||
using (Utilities.CreateHttpServer(out address, options => options.MaxRequestBodySize = 10, httpContext =>
|
using (Utilities.CreateHttpServer(out address, options => options.MaxRequestBodySize = 10, httpContext =>
|
||||||
{
|
{
|
||||||
|
httpContext.Features.Get<IHttpBodyControlFeature>().AllowSynchronousIO = true;
|
||||||
var feature = httpContext.Features.Get<IHttpMaxRequestBodySizeFeature>();
|
var feature = httpContext.Features.Get<IHttpMaxRequestBodySizeFeature>();
|
||||||
Assert.NotNull(feature);
|
Assert.NotNull(feature);
|
||||||
Assert.False(feature.IsReadOnly);
|
Assert.False(feature.IsReadOnly);
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ using System.Net.Sockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Http.Features;
|
||||||
using Microsoft.AspNetCore.Testing.xunit;
|
using Microsoft.AspNetCore.Testing.xunit;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -23,6 +24,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
using (Utilities.CreateHttpServer(out address, httpContext =>
|
using (Utilities.CreateHttpServer(out address, httpContext =>
|
||||||
{
|
{
|
||||||
byte[] input = new byte[100];
|
byte[] input = new byte[100];
|
||||||
|
httpContext.Features.Get<IHttpBodyControlFeature>().AllowSynchronousIO = true;
|
||||||
int read = httpContext.Request.Body.Read(input, 0, input.Length);
|
int read = httpContext.Request.Body.Read(input, 0, input.Length);
|
||||||
httpContext.Response.ContentLength = read;
|
httpContext.Response.ContentLength = read;
|
||||||
httpContext.Response.Body.Write(input, 0, read);
|
httpContext.Response.Body.Write(input, 0, read);
|
||||||
|
|
@ -75,6 +77,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
string address;
|
string address;
|
||||||
using (Utilities.CreateHttpServer(out address, httpContext =>
|
using (Utilities.CreateHttpServer(out address, httpContext =>
|
||||||
{
|
{
|
||||||
|
httpContext.Features.Get<IHttpBodyControlFeature>().AllowSynchronousIO = true;
|
||||||
byte[] input = new byte[100];
|
byte[] input = new byte[100];
|
||||||
Assert.Throws<ArgumentNullException>("buffer", () => httpContext.Request.Body.Read(null, 0, 1));
|
Assert.Throws<ArgumentNullException>("buffer", () => httpContext.Request.Body.Read(null, 0, 1));
|
||||||
Assert.Throws<ArgumentOutOfRangeException>("offset", () => httpContext.Request.Body.Read(input, -1, 1));
|
Assert.Throws<ArgumentOutOfRangeException>("offset", () => httpContext.Request.Body.Read(input, -1, 1));
|
||||||
|
|
@ -99,6 +102,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
using (Utilities.CreateHttpServer(out address, httpContext =>
|
using (Utilities.CreateHttpServer(out address, httpContext =>
|
||||||
{
|
{
|
||||||
byte[] input = new byte[10];
|
byte[] input = new byte[10];
|
||||||
|
httpContext.Features.Get<IHttpBodyControlFeature>().AllowSynchronousIO = true;
|
||||||
int read = httpContext.Request.Body.Read(input, 0, input.Length);
|
int read = httpContext.Request.Body.Read(input, 0, input.Length);
|
||||||
Assert.Equal(5, read);
|
Assert.Equal(5, read);
|
||||||
content.Block.Release();
|
content.Block.Release();
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ using System.Net.Http;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Http.Features;
|
||||||
using Microsoft.AspNetCore.Testing.xunit;
|
using Microsoft.AspNetCore.Testing.xunit;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -22,6 +23,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
string address;
|
string address;
|
||||||
using (Utilities.CreateHttpServer(out address, httpContext =>
|
using (Utilities.CreateHttpServer(out address, httpContext =>
|
||||||
{
|
{
|
||||||
|
httpContext.Features.Get<IHttpBodyControlFeature>().AllowSynchronousIO = true;
|
||||||
httpContext.Response.Body.Write(new byte[10], 0, 10);
|
httpContext.Response.Body.Write(new byte[10], 0, 10);
|
||||||
return httpContext.Response.Body.WriteAsync(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;
|
string address;
|
||||||
using (Utilities.CreateHttpServer(out address, async httpContext =>
|
using (Utilities.CreateHttpServer(out address, async httpContext =>
|
||||||
{
|
{
|
||||||
|
httpContext.Features.Get<IHttpBodyControlFeature>().AllowSynchronousIO = true;
|
||||||
httpContext.Response.Body.Write(new byte[10], 0, 10);
|
httpContext.Response.Body.Write(new byte[10], 0, 10);
|
||||||
await httpContext.Response.Body.WriteAsync(new byte[10], 0, 10);
|
await httpContext.Response.Body.WriteAsync(new byte[10], 0, 10);
|
||||||
await httpContext.Response.Body.FlushAsync();
|
await httpContext.Response.Body.FlushAsync();
|
||||||
|
|
@ -85,6 +88,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
string address;
|
string address;
|
||||||
using (Utilities.CreateHttpServer(out address, async httpContext =>
|
using (Utilities.CreateHttpServer(out address, async httpContext =>
|
||||||
{
|
{
|
||||||
|
httpContext.Features.Get<IHttpBodyControlFeature>().AllowSynchronousIO = true;
|
||||||
httpContext.Response.Headers["Content-lenGth"] = " 30 ";
|
httpContext.Response.Headers["Content-lenGth"] = " 30 ";
|
||||||
Stream stream = httpContext.Response.Body;
|
Stream stream = httpContext.Response.Body;
|
||||||
stream.EndWrite(stream.BeginWrite(new byte[10], 0, 10, null, null));
|
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 =>
|
using (Utilities.CreateHttpServer(out address, httpContext =>
|
||||||
{
|
{
|
||||||
httpContext.Response.Headers["Content-lenGth"] = " 20 ";
|
httpContext.Response.Headers["Content-lenGth"] = " 20 ";
|
||||||
httpContext.Response.Body.Write(new byte[5], 0, 5);
|
return httpContext.Response.Body.WriteAsync(new byte[5], 0, 5);
|
||||||
return Task.FromResult(0);
|
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
Assert.Throws<AggregateException>(() => SendRequestAsync(address).Result);
|
Assert.Throws<AggregateException>(() => SendRequestAsync(address).Result);
|
||||||
|
|
@ -137,13 +140,13 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
{
|
{
|
||||||
var completed = false;
|
var completed = false;
|
||||||
string address;
|
string address;
|
||||||
using (Utilities.CreateHttpServer(out address, httpContext =>
|
using (Utilities.CreateHttpServer(out address, async httpContext =>
|
||||||
{
|
{
|
||||||
httpContext.Response.Headers["Content-lenGth"] = " 10 ";
|
httpContext.Response.Headers["Content-lenGth"] = " 10 ";
|
||||||
httpContext.Response.Body.Write(new byte[5], 0, 5);
|
await httpContext.Response.Body.WriteAsync(new byte[5], 0, 5);
|
||||||
Assert.Throws<InvalidOperationException>(() => httpContext.Response.Body.Write(new byte[6], 0, 6));
|
await Assert.ThrowsAsync<InvalidOperationException>(() =>
|
||||||
|
httpContext.Response.Body.WriteAsync(new byte[6], 0, 6));
|
||||||
completed = true;
|
completed = true;
|
||||||
return Task.FromResult(0);
|
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
await Assert.ThrowsAsync<HttpRequestException>(() => SendRequestAsync(address));
|
await Assert.ThrowsAsync<HttpRequestException>(() => SendRequestAsync(address));
|
||||||
|
|
@ -161,6 +164,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
httpContext.Features.Get<IHttpBodyControlFeature>().AllowSynchronousIO = true;
|
||||||
httpContext.Response.Headers["Content-lenGth"] = " 10 ";
|
httpContext.Response.Headers["Content-lenGth"] = " 10 ";
|
||||||
httpContext.Response.Body.Write(new byte[10], 0, 10);
|
httpContext.Response.Body.Write(new byte[10], 0, 10);
|
||||||
httpContext.Response.Body.Write(new byte[9], 0, 9);
|
httpContext.Response.Body.Write(new byte[9], 0, 9);
|
||||||
|
|
@ -197,6 +201,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
string address;
|
string address;
|
||||||
using (Utilities.CreateHttpServer(out address, httpContext =>
|
using (Utilities.CreateHttpServer(out address, httpContext =>
|
||||||
{
|
{
|
||||||
|
httpContext.Features.Get<IHttpBodyControlFeature>().AllowSynchronousIO = true;
|
||||||
httpContext.Response.OnStarting(state =>
|
httpContext.Response.OnStarting(state =>
|
||||||
{
|
{
|
||||||
onStartingCalled = true;
|
onStartingCalled = true;
|
||||||
|
|
|
||||||
|
|
@ -130,8 +130,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
var responseInfo = httpContext.Features.Get<IHttpResponseFeature>();
|
var responseInfo = httpContext.Features.Get<IHttpResponseFeature>();
|
||||||
var responseHeaders = responseInfo.Headers;
|
var responseHeaders = responseInfo.Headers;
|
||||||
responseHeaders["Connection"] = new string[] { "Close" };
|
responseHeaders["Connection"] = new string[] { "Close" };
|
||||||
httpContext.Response.Body.Flush(); // Http.Sys adds the Content-Length: header for us if we don't flush
|
return httpContext.Response.Body.FlushAsync(); // Http.Sys adds the Content-Length: header for us if we don't flush
|
||||||
return Task.FromResult(0);
|
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
HttpResponseMessage response = await SendRequestAsync(address);
|
HttpResponseMessage response = await SendRequestAsync(address);
|
||||||
|
|
@ -204,6 +203,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
string address;
|
string address;
|
||||||
using (Utilities.CreateHttpServer(out address, httpContext =>
|
using (Utilities.CreateHttpServer(out address, httpContext =>
|
||||||
{
|
{
|
||||||
|
httpContext.Features.Get<IHttpBodyControlFeature>().AllowSynchronousIO = true;
|
||||||
var responseInfo = httpContext.Features.Get<IHttpResponseFeature>();
|
var responseInfo = httpContext.Features.Get<IHttpResponseFeature>();
|
||||||
var responseHeaders = responseInfo.Headers;
|
var responseHeaders = responseInfo.Headers;
|
||||||
responseHeaders.Add("Custom1", new string[] { "value1a", "value1b" });
|
responseHeaders.Add("Custom1", new string[] { "value1a", "value1b" });
|
||||||
|
|
|
||||||
|
|
@ -53,12 +53,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
public async Task Server_EchoHelloWorld_Success()
|
public async Task Server_EchoHelloWorld_Success()
|
||||||
{
|
{
|
||||||
string address;
|
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);
|
Assert.Equal("Hello World", input);
|
||||||
httpContext.Response.ContentLength = 11;
|
httpContext.Response.ContentLength = 11;
|
||||||
return httpContext.Response.WriteAsync("Hello World");
|
await httpContext.Response.WriteAsync("Hello World");
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
string response = await SendRequestAsync(address, "Hello World");
|
string response = await SendRequestAsync(address, "Hello World");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue