Avoid throwing the same exception instances in parallel (#2859)
This commit is contained in:
parent
6dc55a0462
commit
89f4850883
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue