Use ConnectionResetException with 'The client disconnected' message (#1364)

This commit is contained in:
Pavel Krymets 2018-09-06 10:10:07 -07:00 committed by GitHub
parent 71b7bb50b2
commit b1f0f173aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 18 deletions

View File

@ -8,6 +8,7 @@
<MicrosoftAspNetCoreAllPackageVersion>2.2.0-preview2-35143</MicrosoftAspNetCoreAllPackageVersion>
<MicrosoftAspNetCoreAuthenticationCorePackageVersion>2.2.0-preview2-35143</MicrosoftAspNetCoreAuthenticationCorePackageVersion>
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>2.2.0-preview2-35143</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
<MicrosoftAspNetCoreConnectionsAbstractionsPackageVersion>2.2.0-preview2-35143</MicrosoftAspNetCoreConnectionsAbstractionsPackageVersion>
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>2.2.0-preview2-35143</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
<MicrosoftAspNetCoreHostingPackageVersion>2.2.0-preview2-35143</MicrosoftAspNetCoreHostingPackageVersion>
<MicrosoftAspNetCoreHttpExtensionsPackageVersion>2.2.0-preview2-35143</MicrosoftAspNetCoreHttpExtensionsPackageVersion>

View File

@ -8,6 +8,7 @@ using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks.Sources;
using Microsoft.AspNetCore.Connections;
namespace Microsoft.AspNetCore.Server.IIS.Core.IO
{
@ -103,7 +104,8 @@ namespace Microsoft.AspNetCore.Server.IIS.Core.IO
_result = bytes;
if (hr != NativeMethods.HR_OK)
{
_exception = new IOException("Native IO operation failed", Marshal.GetExceptionForHR(hr));
// Treat all errors as the client disconnect
_exception = new ConnectionResetException("The client has disconnected", Marshal.GetExceptionForHR(hr));
}
}
else

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
@ -24,6 +24,7 @@
<PackageReference Include="Microsoft.AspNetCore.Authentication.Core" Version="$(MicrosoftAspNetCoreAuthenticationCorePackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="$(MicrosoftAspNetCoreHostingAbstractionsPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Connections.Abstractions" Version="$(MicrosoftAspNetCoreConnectionsAbstractionsPackageVersion)" />
</ItemGroup>
<ItemGroup Condition="'$(VCTargetsPath)' != ''">

View File

@ -5,6 +5,7 @@ using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Server.IntegrationTesting;
using Microsoft.AspNetCore.Testing.xunit;
using Microsoft.Extensions.Logging.Testing;
@ -17,7 +18,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
public class ClientDisconnectTests : LoggedTest
{
[ConditionalFact(Skip = "See: https://github.com/aspnet/IISIntegration/issues/1075")]
[ConditionalFact]
public async Task WritesSucceedAfterClientDisconnect()
{
var requestStartedCompletionSource = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
@ -49,7 +50,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
}
}
[ConditionalFact(Skip = "See: https://github.com/aspnet/IISIntegration/issues/1075")]
[ConditionalFact]
public async Task ReadThrowsAfterClientDisconnect()
{
var requestStartedCompletionSource = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
@ -82,8 +83,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
await requestCompletedCompletionSource.Task.TimeoutAfterDefault();
}
Assert.IsType<IOException>(exception);
Assert.Equal("Native IO operation failed", exception.Message);
Assert.IsType<ConnectionResetException>(exception);
Assert.Equal("The client has disconnected", exception.Message);
}
[ConditionalFact(Skip = "See: https://github.com/aspnet/IISIntegration/issues/1075")]
@ -126,7 +127,6 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
Assert.IsType<OperationCanceledException>(exception);
}
}
[ConditionalFact(Skip = "See: https://github.com/aspnet/IISIntegration/issues/1075")]
public async Task ReaderThrowsCancelledException()
{
@ -163,6 +163,46 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
}
}
[ConditionalFact]
public async Task ReaderThrowsResetExceptionOnInvalidBody()
{
var requestCompletedCompletionSource = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
Exception exception = null;
var data = new byte[1024];
using (var testServer = await TestServer.Create(async ctx =>
{
try
{
await ctx.Request.Body.ReadAsync(data);
}
catch (Exception e)
{
exception = e;
}
requestCompletedCompletionSource.SetResult(true);
}, LoggerFactory))
{
using (var connection = testServer.CreateConnection())
{
await connection.Send(
"POST / HTTP/1.1",
"Transfer-Encoding: chunked",
"Host: localhost",
"Connection: close",
"",
"ZZZ",
"");
await requestCompletedCompletionSource.Task.TimeoutAfterDefault();
}
}
Assert.IsType<ConnectionResetException>(exception);
Assert.Equal("The client has disconnected", exception.Message);
}
private static async Task SendContentLength1Post(TestConnection connection)
{
await connection.Send(

View File

@ -19,17 +19,17 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
var helloWorld = "Hello World";
var expectedPath = "/Path";
string path = null;
using (var testServer = await TestServer.Create(ctx =>
{
path = ctx.Request.Path.ToString();
return ctx.Response.WriteAsync(helloWorld);
}, LoggerFactory))
{
var result = await testServer.HttpClient.GetAsync(expectedPath);
Assert.Equal(helloWorld, await result.Content.ReadAsStringAsync());
Assert.Equal(expectedPath, path);
}
string path = null;
using (var testServer = await TestServer.Create(ctx =>
{
path = ctx.Request.Path.ToString();
return ctx.Response.WriteAsync(helloWorld);
}, LoggerFactory))
{
var result = await testServer.HttpClient.GetAsync(expectedPath);
Assert.Equal(helloWorld, await result.Content.ReadAsStringAsync());
Assert.Equal(expectedPath, path);
}
}
}
}