React to new SocketHttpHandler (#434)
This commit is contained in:
parent
80345b7f8f
commit
fbc5b64cd8
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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++)
|
||||
|
|
|
|||
|
|
@ -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++)
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue