React to new SocketHttpHandler (#434)

This commit is contained in:
Chris Ross 2018-03-16 10:56:36 -07:00 committed by GitHub
parent 80345b7f8f
commit fbc5b64cd8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 131 additions and 137 deletions

View File

@ -4,17 +4,17 @@
</PropertyGroup>
<PropertyGroup Label="Package Versions">
<InternalAspNetCoreSdkPackageVersion>2.1.0-preview2-15728</InternalAspNetCoreSdkPackageVersion>
<MicrosoftAspNetCoreAuthenticationCorePackageVersion>2.1.0-preview2-30272</MicrosoftAspNetCoreAuthenticationCorePackageVersion>
<MicrosoftAspNetCoreHostingPackageVersion>2.1.0-preview2-30272</MicrosoftAspNetCoreHostingPackageVersion>
<MicrosoftAspNetCoreTestingPackageVersion>2.1.0-preview2-30272</MicrosoftAspNetCoreTestingPackageVersion>
<MicrosoftExtensionsLoggingConsolePackageVersion>2.1.0-preview2-30272</MicrosoftExtensionsLoggingConsolePackageVersion>
<MicrosoftAspNetCoreAuthenticationCorePackageVersion>2.1.0-preview2-30301</MicrosoftAspNetCoreAuthenticationCorePackageVersion>
<MicrosoftAspNetCoreHostingPackageVersion>2.1.0-preview2-30301</MicrosoftAspNetCoreHostingPackageVersion>
<MicrosoftAspNetCoreTestingPackageVersion>2.1.0-preview2-30301</MicrosoftAspNetCoreTestingPackageVersion>
<MicrosoftExtensionsLoggingConsolePackageVersion>2.1.0-preview2-30301</MicrosoftExtensionsLoggingConsolePackageVersion>
<MicrosoftNETCoreApp20PackageVersion>2.0.0</MicrosoftNETCoreApp20PackageVersion>
<MicrosoftNETCoreApp21PackageVersion>2.1.0-preview2-26225-03</MicrosoftNETCoreApp21PackageVersion>
<MicrosoftNetHttpHeadersPackageVersion>2.1.0-preview2-30272</MicrosoftNetHttpHeadersPackageVersion>
<MicrosoftNETCoreApp21PackageVersion>2.1.0-preview2-26308-01</MicrosoftNETCoreApp21PackageVersion>
<MicrosoftNetHttpHeadersPackageVersion>2.1.0-preview2-30301</MicrosoftNetHttpHeadersPackageVersion>
<MicrosoftNETTestSdkPackageVersion>15.6.0</MicrosoftNETTestSdkPackageVersion>
<MicrosoftWin32RegistryPackageVersion>4.5.0-preview2-26224-02</MicrosoftWin32RegistryPackageVersion>
<SystemNetHttpWinHttpHandlerPackageVersion>4.5.0-preview2-26224-02</SystemNetHttpWinHttpHandlerPackageVersion>
<SystemSecurityPrincipalWindowsPackageVersion>4.5.0-preview2-26224-02</SystemSecurityPrincipalWindowsPackageVersion>
<MicrosoftWin32RegistryPackageVersion>4.5.0-preview2-26308-02</MicrosoftWin32RegistryPackageVersion>
<SystemNetHttpWinHttpHandlerPackageVersion>4.5.0-preview2-26308-02</SystemNetHttpWinHttpHandlerPackageVersion>
<SystemSecurityPrincipalWindowsPackageVersion>4.5.0-preview2-26308-02</SystemSecurityPrincipalWindowsPackageVersion>
<XunitPackageVersion>2.3.1</XunitPackageVersion>
<XunitRunnerVisualStudioPackageVersion>2.4.0-beta.1.build3945</XunitRunnerVisualStudioPackageVersion>
</PropertyGroup>

View File

@ -133,12 +133,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys
dataRead = _requestContext.Request.GetChunks(ref _dataChunkIndex, ref _dataChunkOffset, buffer, offset, size);
}
if (_dataChunkIndex == -1 && dataRead < size)
if (_dataChunkIndex == -1 && dataRead == 0)
{
uint statusCode = 0;
uint extraDataRead = 0;
offset += (int)dataRead;
size -= (int)dataRead;
// the http.sys team recommends that we limit the size to 128kb
if (size > MaxReadSize)
@ -209,72 +207,68 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{
dataRead = _requestContext.Request.GetChunks(ref _dataChunkIndex, ref _dataChunkOffset, buffer, offset, size);
if (_dataChunkIndex != -1 && dataRead == size)
if (dataRead > 0)
{
asyncResult = new RequestStreamAsyncResult(this, state, callback, buffer, offset, 0);
asyncResult.Complete((int)dataRead);
return asyncResult;
}
}
if (_dataChunkIndex == -1 && dataRead < size)
uint statusCode = 0;
// the http.sys team recommends that we limit the size to 128kb
if (size > MaxReadSize)
{
uint statusCode = 0;
offset += (int)dataRead;
size -= (int)dataRead;
size = MaxReadSize;
}
// the http.sys team recommends that we limit the size to 128kb
if (size > MaxReadSize)
{
size = MaxReadSize;
}
asyncResult = new RequestStreamAsyncResult(this, state, callback, buffer, offset, dataRead);
uint bytesReturned;
asyncResult = new RequestStreamAsyncResult(this, state, callback, buffer, offset, dataRead);
uint bytesReturned;
try
{
uint flags = 0;
try
{
uint flags = 0;
statusCode =
HttpApi.HttpReceiveRequestEntityBody(
RequestQueueHandle,
RequestId,
flags,
asyncResult.PinnedBuffer,
(uint)size,
out bytesReturned,
asyncResult.NativeOverlapped);
}
catch (Exception e)
{
LogHelper.LogException(Logger, "BeginRead", e);
asyncResult.Dispose();
throw;
}
statusCode =
HttpApi.HttpReceiveRequestEntityBody(
RequestQueueHandle,
RequestId,
flags,
asyncResult.PinnedBuffer,
(uint)size,
out bytesReturned,
asyncResult.NativeOverlapped);
}
catch (Exception e)
if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING)
{
asyncResult.Dispose();
if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_HANDLE_EOF)
{
LogHelper.LogException(Logger, "BeginRead", e);
asyncResult.Dispose();
throw;
asyncResult = new RequestStreamAsyncResult(this, state, callback, dataRead);
asyncResult.Complete((int)bytesReturned);
}
if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING)
else
{
asyncResult.Dispose();
if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_HANDLE_EOF)
{
asyncResult = new RequestStreamAsyncResult(this, state, callback, dataRead);
asyncResult.Complete((int)bytesReturned);
}
else
{
Exception exception = new IOException(string.Empty, new HttpSysException((int)statusCode));
LogHelper.LogException(Logger, "BeginRead", exception);
Abort();
throw exception;
}
}
else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
HttpSysListener.SkipIOCPCallbackOnSuccess)
{
// IO operation completed synchronously - callback won't be called to signal completion.
asyncResult.IOCompleted(statusCode, bytesReturned);
Exception exception = new IOException(string.Empty, new HttpSysException((int)statusCode));
LogHelper.LogException(Logger, "BeginRead", exception);
Abort();
throw exception;
}
}
else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
HttpSysListener.SkipIOCPCallbackOnSuccess)
{
// IO operation completed synchronously - callback won't be called to signal completion.
asyncResult.IOCompleted(statusCode, bytesReturned);
}
return asyncResult;
}
@ -322,7 +316,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
if (_dataChunkIndex != -1)
{
dataRead = _requestContext.Request.GetChunks(ref _dataChunkIndex, ref _dataChunkOffset, buffer, offset, size);
if (_dataChunkIndex != -1 && dataRead == size)
if (dataRead > 0)
{
UpdateAfterRead(UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS, dataRead);
if (TryCheckSizeLimit((int)dataRead, out var exception))
@ -334,85 +328,82 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
}
if (_dataChunkIndex == -1 && dataRead < size)
uint statusCode = 0;
offset += (int)dataRead;
size -= (int)dataRead;
// the http.sys team recommends that we limit the size to 128kb
if (size > MaxReadSize)
{
uint statusCode = 0;
offset += (int)dataRead;
size -= (int)dataRead;
size = MaxReadSize;
}
// the http.sys team recommends that we limit the size to 128kb
if (size > MaxReadSize)
{
size = MaxReadSize;
}
var cancellationRegistration = default(CancellationTokenRegistration);
if (cancellationToken.CanBeCanceled)
{
cancellationRegistration = RequestContext.RegisterForCancellation(cancellationToken);
}
var cancellationRegistration = default(CancellationTokenRegistration);
if (cancellationToken.CanBeCanceled)
{
cancellationRegistration = RequestContext.RegisterForCancellation(cancellationToken);
}
asyncResult = new RequestStreamAsyncResult(this, null, null, buffer, offset, dataRead, cancellationRegistration);
uint bytesReturned;
asyncResult = new RequestStreamAsyncResult(this, null, null, buffer, offset, dataRead, cancellationRegistration);
uint bytesReturned;
try
{
uint flags = 0;
try
{
uint flags = 0;
statusCode =
HttpApi.HttpReceiveRequestEntityBody(
RequestQueueHandle,
RequestId,
flags,
asyncResult.PinnedBuffer,
(uint)size,
out bytesReturned,
asyncResult.NativeOverlapped);
}
catch (Exception e)
{
asyncResult.Dispose();
Abort();
LogHelper.LogException(Logger, "ReadAsync", e);
throw;
}
statusCode =
HttpApi.HttpReceiveRequestEntityBody(
RequestQueueHandle,
RequestId,
flags,
asyncResult.PinnedBuffer,
(uint)size,
out bytesReturned,
asyncResult.NativeOverlapped);
}
catch (Exception e)
if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING)
{
asyncResult.Dispose();
if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_HANDLE_EOF)
{
asyncResult.Dispose();
Abort();
LogHelper.LogException(Logger, "ReadAsync", e);
throw;
}
if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING)
{
asyncResult.Dispose();
if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_HANDLE_EOF)
{
uint totalRead = dataRead + bytesReturned;
UpdateAfterRead(statusCode, totalRead);
if (TryCheckSizeLimit((int)totalRead, out var exception))
{
return Task.FromException<int>(exception);
}
// TODO: Verbose log totalRead
return Task.FromResult<int>((int)totalRead);
}
else
{
Exception exception = new IOException(string.Empty, new HttpSysException((int)statusCode));
LogHelper.LogException(Logger, "ReadAsync", exception);
Abort();
throw exception;
}
}
else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
HttpSysListener.SkipIOCPCallbackOnSuccess)
{
// IO operation completed synchronously - callback won't be called to signal completion.
asyncResult.Dispose();
uint totalRead = dataRead + bytesReturned;
UpdateAfterRead(statusCode, totalRead);
if (TryCheckSizeLimit((int)totalRead, out var exception))
{
return Task.FromException<int>(exception);
}
// TODO: Verbose log
// TODO: Verbose log totalRead
return Task.FromResult<int>((int)totalRead);
}
else
{
Exception exception = new IOException(string.Empty, new HttpSysException((int)statusCode));
LogHelper.LogException(Logger, "ReadAsync", exception);
Abort();
throw exception;
}
}
else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
HttpSysListener.SkipIOCPCallbackOnSuccess)
{
// IO operation completed synchronously - callback won't be called to signal completion.
asyncResult.Dispose();
uint totalRead = dataRead + bytesReturned;
UpdateAfterRead(statusCode, totalRead);
if (TryCheckSizeLimit((int)totalRead, out var exception))
{
return Task.FromException<int>(exception);
}
// TODO: Verbose log
return Task.FromResult<int>((int)totalRead);
}
return asyncResult.Task;
}

View File

@ -344,7 +344,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
content.Block.Release();
context.Dispose();
await Assert.ThrowsAsync<TaskCanceledException>(async () => await responseTask);
await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await responseTask);
}
}
@ -421,6 +421,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
protected async override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
await stream.WriteAsync(new byte[5], 0, 5);
await stream.FlushAsync();
await Block.WaitAsync();
await stream.WriteAsync(new byte[5], 0, 5);
}

View File

@ -427,7 +427,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
// First write sends headers
cts.Cancel();
await Assert.ThrowsAsync<TaskCanceledException>(() => responseTask);
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => responseTask);
Assert.True(context.DisconnectToken.WaitHandle.WaitOne(TimeSpan.FromSeconds(5)));
Assert.Throws<IOException>(() =>
{
@ -458,7 +458,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
// First write sends headers
cts.Cancel();
await Assert.ThrowsAsync<TaskCanceledException>(() => responseTask);
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => responseTask);
Assert.True(context.DisconnectToken.WaitHandle.WaitOne(TimeSpan.FromSeconds(5)));
await Assert.ThrowsAsync<IOException>(async () =>
@ -489,7 +489,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
// First write sends headers
cts.Cancel();
await Assert.ThrowsAsync<TaskCanceledException>(() => responseTask);
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => responseTask);
Assert.True(context.DisconnectToken.WaitHandle.WaitOne(TimeSpan.FromSeconds(5)));
// It can take several tries before Write notices the disconnect.
for (int i = 0; i < Utilities.WriteRetryLimit; i++)
@ -512,7 +512,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
// First write sends headers
cts.Cancel();
await Assert.ThrowsAsync<TaskCanceledException>(() => responseTask);
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => responseTask);
Assert.True(context.DisconnectToken.WaitHandle.WaitOne(TimeSpan.FromSeconds(5)));
// It can take several tries before Write notices the disconnect.
for (int i = 0; i < Utilities.WriteRetryLimit; i++)

View File

@ -468,7 +468,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
// First write sends headers
cts.Cancel();
await Assert.ThrowsAsync<TaskCanceledException>(() => responseTask);
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => responseTask);
Assert.True(context.DisconnectToken.WaitHandle.WaitOne(TimeSpan.FromSeconds(5)));
await Assert.ThrowsAsync<IOException>(async () =>
@ -499,7 +499,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
// First write sends headers
cts.Cancel();
await Assert.ThrowsAsync<TaskCanceledException>(() => responseTask);
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => responseTask);
Assert.True(context.DisconnectToken.WaitHandle.WaitOne(TimeSpan.FromSeconds(5)));
// It can take several tries before Send notices the disconnect.
for (int i = 0; i < Utilities.WriteRetryLimit; i++)

View File

@ -96,7 +96,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
Assert.True(canceled.WaitOne(interval), "canceled");
Assert.True(ct.IsCancellationRequested, "IsCancellationRequested");
await Assert.ThrowsAsync<TaskCanceledException>(() => responseTask);
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => responseTask);
context.Dispose();
}
@ -119,7 +119,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
client.CancelPendingRequests();
await Assert.ThrowsAsync<TaskCanceledException>(() => responseTask);
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => responseTask);
var ct = context.DisconnectToken;
Assert.True(ct.CanBeCanceled, "CanBeCanceled");

View File

@ -413,6 +413,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
protected async override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
await stream.WriteAsync(new byte[10], 0, 10);
await stream.FlushAsync();
Assert.True(await Block.WaitAsync(TimeSpan.FromSeconds(10)));
await stream.WriteAsync(new byte[10], 0, 10);
}

View File

@ -232,7 +232,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys
protected async override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
await stream.WriteAsync(new byte[5], 0, 5);
await Block.WaitAsync();
await stream.FlushAsync();
Assert.True(await Block.WaitAsync(TimeSpan.FromSeconds(10)));
await stream.WriteAsync(new byte[5], 0, 5);
}