Throw IOExceptions instead of ODEs after a request is aborted
This commit is contained in:
parent
062caf16be
commit
874bd29ce1
|
|
@ -183,8 +183,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
_requestProcessingStopping = true;
|
||||
_requestAborted = true;
|
||||
|
||||
_requestBody?.StopAcceptingReads();
|
||||
_responseBody?.StopAcceptingWrites();
|
||||
_requestBody?.Abort();
|
||||
_responseBody?.Abort();
|
||||
|
||||
try
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
{
|
||||
private readonly MessageBody _body;
|
||||
private bool _stopped;
|
||||
private bool _aborted;
|
||||
|
||||
public FrameRequestStream(MessageBody body)
|
||||
{
|
||||
|
|
@ -55,6 +56,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
{
|
||||
throw new ObjectDisposedException(nameof(FrameRequestStream));
|
||||
}
|
||||
if (_aborted)
|
||||
{
|
||||
throw new IOException("The request has been aborted.");
|
||||
}
|
||||
|
||||
return ReadAsync(buffer, offset, count).GetAwaiter().GetResult();
|
||||
}
|
||||
|
|
@ -66,6 +71,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
{
|
||||
throw new ObjectDisposedException(nameof(FrameRequestStream));
|
||||
}
|
||||
if (_aborted)
|
||||
{
|
||||
throw new IOException("The request has been aborted.");
|
||||
}
|
||||
|
||||
var task = ReadAsync(buffer, offset, count, CancellationToken.None, state);
|
||||
if (callback != null)
|
||||
|
|
@ -86,6 +95,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
{
|
||||
throw new ObjectDisposedException(nameof(FrameRequestStream));
|
||||
}
|
||||
if (_aborted)
|
||||
{
|
||||
throw new IOException("The request has been aborted.");
|
||||
}
|
||||
|
||||
var tcs = new TaskCompletionSource<int>(state);
|
||||
var task = _body.ReadAsync(new ArraySegment<byte>(buffer, offset, count), cancellationToken);
|
||||
|
|
@ -111,6 +124,15 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
|
||||
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
{
|
||||
if (_stopped)
|
||||
{
|
||||
throw new ObjectDisposedException(nameof(FrameRequestStream));
|
||||
}
|
||||
if (_aborted)
|
||||
{
|
||||
throw new IOException("The request has been aborted.");
|
||||
}
|
||||
|
||||
return _body.ReadAsync(new ArraySegment<byte>(buffer, offset, count), cancellationToken);
|
||||
}
|
||||
|
||||
|
|
@ -125,5 +147,12 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
// As exampled in EngineTests.ZeroContentLengthNotSetAutomaticallyForCertainStatusCodes
|
||||
_stopped = true;
|
||||
}
|
||||
|
||||
public void Abort()
|
||||
{
|
||||
// We don't want to throw an ODE until the app func actually completes.
|
||||
// If the request is aborted, we throw an IOException instead.
|
||||
_aborted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
{
|
||||
private readonly FrameContext _context;
|
||||
private bool _stopped;
|
||||
private bool _aborted;
|
||||
|
||||
public FrameResponseStream(FrameContext context)
|
||||
{
|
||||
|
|
@ -40,6 +41,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
{
|
||||
throw new ObjectDisposedException(nameof(FrameResponseStream));
|
||||
}
|
||||
if (_aborted)
|
||||
{
|
||||
throw new IOException("The request has been aborted.");
|
||||
}
|
||||
|
||||
_context.FrameControl.Flush();
|
||||
}
|
||||
|
|
@ -50,6 +55,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
{
|
||||
throw new ObjectDisposedException(nameof(FrameResponseStream));
|
||||
}
|
||||
if (_aborted)
|
||||
{
|
||||
throw new IOException("The request has been aborted.");
|
||||
}
|
||||
|
||||
return _context.FrameControl.FlushAsync(cancellationToken);
|
||||
}
|
||||
|
|
@ -75,6 +84,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
{
|
||||
throw new ObjectDisposedException(nameof(FrameResponseStream));
|
||||
}
|
||||
if (_aborted)
|
||||
{
|
||||
throw new IOException("The request has been aborted.");
|
||||
}
|
||||
|
||||
_context.FrameControl.Write(new ArraySegment<byte>(buffer, offset, count));
|
||||
}
|
||||
|
|
@ -85,6 +98,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
{
|
||||
throw new ObjectDisposedException(nameof(FrameResponseStream));
|
||||
}
|
||||
if (_aborted)
|
||||
{
|
||||
throw new IOException("The request has been aborted.");
|
||||
}
|
||||
|
||||
return _context.FrameControl.WriteAsync(new ArraySegment<byte>(buffer, offset, count), cancellationToken);
|
||||
}
|
||||
|
|
@ -95,5 +112,12 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
// As exampled in EngineTests.ZeroContentLengthNotSetAutomaticallyForCertainStatusCodes
|
||||
_stopped = true;
|
||||
}
|
||||
|
||||
public void Abort()
|
||||
{
|
||||
// We don't want to throw an ODE until the app func actually completes.
|
||||
// If the request is aborted, we throw an IOException instead.
|
||||
_aborted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,10 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
|||
{
|
||||
}
|
||||
|
||||
public void Abort()
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(ArraySegment<byte> data, Action<Exception, object> callback, object state)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue