Avoid throwing the same exception instances in parallel (#2859)

This commit is contained in:
Stephen Halter 2018-08-28 10:56:46 -07:00 committed by GitHub
parent 6dc55a0462
commit 89f4850883
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 40 additions and 45 deletions

View File

@ -1212,7 +1212,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
var ex = new InvalidOperationException(CoreStrings.FormatHeaderNotAllowedOnResponse("Transfer-Encoding", StatusCode));
if (!appCompleted)
{
// Back out of header creation surface exeception in user code
// Back out of header creation surface exception in user code
_requestProcessingStatus = RequestProcessingStatus.AppStarted;
throw ex;
}

View File

@ -27,11 +27,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
public static async Task<bool> AbortAllConnectionsAsync(this ConnectionManager connectionManager)
{
var abortTasks = new List<Task>();
var canceledException = new ConnectionAbortedException(CoreStrings.ConnectionAbortedDuringServerShutdown);
connectionManager.Walk(connection =>
{
connection.TransportConnection.Abort(canceledException);
connection.TransportConnection.Abort(new ConnectionAbortedException(CoreStrings.ConnectionAbortedDuringServerShutdown));
abortTasks.Add(connection.ExecutionTask);
});

View File

@ -10,8 +10,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
{
public class Streams
{
private static readonly ThrowingWriteOnlyStream _throwingResponseStream
= new ThrowingWriteOnlyStream(new InvalidOperationException(CoreStrings.ResponseStreamWasUpgraded));
private static readonly ThrowingWasUpgradedWriteOnlyStream _throwingResponseStream
= new ThrowingWasUpgradedWriteOnlyStream();
private readonly HttpResponseStream _response;
private readonly HttpRequestStream _request;
private readonly WrappingStream _upgradeableResponse;

View File

@ -8,15 +8,8 @@ using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
{
public class ThrowingWriteOnlyStream : WriteOnlyStream
public class ThrowingWasUpgradedWriteOnlyStream : WriteOnlyStream
{
private readonly Exception _exception;
public ThrowingWriteOnlyStream(Exception exception)
{
_exception = exception;
}
public override bool CanSeek => false;
public override long Length => throw new NotSupportedException();
@ -28,13 +21,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
}
public override void Write(byte[] buffer, int offset, int count)
=> throw _exception;
=> throw new InvalidOperationException(CoreStrings.ResponseStreamWasUpgraded);
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
=> throw _exception;
=> throw new InvalidOperationException(CoreStrings.ResponseStreamWasUpgraded);
public override void Flush()
=> throw _exception;
=> throw new InvalidOperationException(CoreStrings.ResponseStreamWasUpgraded);
public override long Seek(long offset, SeekOrigin origin)
=> throw new NotSupportedException();

View File

@ -88,6 +88,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal
}
else
{
// This is unexpected.
Log.ConnectionError(ConnectionId, ex);
inputError = ex;
outputError = ex;
}
@ -240,6 +243,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal
}
else
{
// This is unexpected.
Log.ConnectionError(ConnectionId, uvError);
return new IOException(uvError.Message, uvError);
}

View File

@ -0,0 +1,28 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
using Xunit;
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
{
public class ThrowingWasUpgradedWriteOnlyStreamTests
{
[Fact]
public async Task ThrowsOnWrite()
{
var stream = new ThrowingWasUpgradedWriteOnlyStream();
Assert.True(stream.CanWrite);
Assert.False(stream.CanRead);
Assert.False(stream.CanSeek);
Assert.False(stream.CanTimeout);
Assert.Equal(CoreStrings.ResponseStreamWasUpgraded, Assert.Throws<InvalidOperationException>(() => stream.Write(new byte[1], 0, 1)).Message);
Assert.Equal(CoreStrings.ResponseStreamWasUpgraded, (await Assert.ThrowsAsync<InvalidOperationException>(() => stream.WriteAsync(new byte[1], 0, 1))).Message);
Assert.Equal(CoreStrings.ResponseStreamWasUpgraded, Assert.Throws<InvalidOperationException>(() => stream.Flush()).Message);
Assert.Equal(CoreStrings.ResponseStreamWasUpgraded, (await Assert.ThrowsAsync<InvalidOperationException>(() => stream.FlushAsync())).Message);
}
}
}

View File

@ -1,29 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
using Xunit;
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
{
public class ThrowingWriteOnlyStreamTests
{
[Fact]
public async Task ThrowsOnWrite()
{
var ex = new Exception("my error");
var stream = new ThrowingWriteOnlyStream(ex);
Assert.True(stream.CanWrite);
Assert.False(stream.CanRead);
Assert.False(stream.CanSeek);
Assert.False(stream.CanTimeout);
Assert.Same(ex, Assert.Throws<Exception>(() => stream.Write(new byte[1], 0, 1)));
Assert.Same(ex, await Assert.ThrowsAsync<Exception>(() => stream.WriteAsync(new byte[1], 0, 1)));
Assert.Same(ex, Assert.Throws<Exception>(() => stream.Flush()));
Assert.Same(ex, await Assert.ThrowsAsync<Exception>(() => stream.FlushAsync()));
}
}
}