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;
|
_requestProcessingStopping = true;
|
||||||
_requestAborted = true;
|
_requestAborted = true;
|
||||||
|
|
||||||
_requestBody?.StopAcceptingReads();
|
_requestBody?.Abort();
|
||||||
_responseBody?.StopAcceptingWrites();
|
_responseBody?.Abort();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
private readonly MessageBody _body;
|
private readonly MessageBody _body;
|
||||||
private bool _stopped;
|
private bool _stopped;
|
||||||
|
private bool _aborted;
|
||||||
|
|
||||||
public FrameRequestStream(MessageBody body)
|
public FrameRequestStream(MessageBody body)
|
||||||
{
|
{
|
||||||
|
|
@ -55,6 +56,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
throw new ObjectDisposedException(nameof(FrameRequestStream));
|
throw new ObjectDisposedException(nameof(FrameRequestStream));
|
||||||
}
|
}
|
||||||
|
if (_aborted)
|
||||||
|
{
|
||||||
|
throw new IOException("The request has been aborted.");
|
||||||
|
}
|
||||||
|
|
||||||
return ReadAsync(buffer, offset, count).GetAwaiter().GetResult();
|
return ReadAsync(buffer, offset, count).GetAwaiter().GetResult();
|
||||||
}
|
}
|
||||||
|
|
@ -66,6 +71,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
throw new ObjectDisposedException(nameof(FrameRequestStream));
|
throw new ObjectDisposedException(nameof(FrameRequestStream));
|
||||||
}
|
}
|
||||||
|
if (_aborted)
|
||||||
|
{
|
||||||
|
throw new IOException("The request has been aborted.");
|
||||||
|
}
|
||||||
|
|
||||||
var task = ReadAsync(buffer, offset, count, CancellationToken.None, state);
|
var task = ReadAsync(buffer, offset, count, CancellationToken.None, state);
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
|
|
@ -86,6 +95,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
throw new ObjectDisposedException(nameof(FrameRequestStream));
|
throw new ObjectDisposedException(nameof(FrameRequestStream));
|
||||||
}
|
}
|
||||||
|
if (_aborted)
|
||||||
|
{
|
||||||
|
throw new IOException("The request has been aborted.");
|
||||||
|
}
|
||||||
|
|
||||||
var tcs = new TaskCompletionSource<int>(state);
|
var tcs = new TaskCompletionSource<int>(state);
|
||||||
var task = _body.ReadAsync(new ArraySegment<byte>(buffer, offset, count), cancellationToken);
|
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)
|
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);
|
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
|
// As exampled in EngineTests.ZeroContentLengthNotSetAutomaticallyForCertainStatusCodes
|
||||||
_stopped = true;
|
_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 readonly FrameContext _context;
|
||||||
private bool _stopped;
|
private bool _stopped;
|
||||||
|
private bool _aborted;
|
||||||
|
|
||||||
public FrameResponseStream(FrameContext context)
|
public FrameResponseStream(FrameContext context)
|
||||||
{
|
{
|
||||||
|
|
@ -40,6 +41,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
throw new ObjectDisposedException(nameof(FrameResponseStream));
|
throw new ObjectDisposedException(nameof(FrameResponseStream));
|
||||||
}
|
}
|
||||||
|
if (_aborted)
|
||||||
|
{
|
||||||
|
throw new IOException("The request has been aborted.");
|
||||||
|
}
|
||||||
|
|
||||||
_context.FrameControl.Flush();
|
_context.FrameControl.Flush();
|
||||||
}
|
}
|
||||||
|
|
@ -50,6 +55,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
throw new ObjectDisposedException(nameof(FrameResponseStream));
|
throw new ObjectDisposedException(nameof(FrameResponseStream));
|
||||||
}
|
}
|
||||||
|
if (_aborted)
|
||||||
|
{
|
||||||
|
throw new IOException("The request has been aborted.");
|
||||||
|
}
|
||||||
|
|
||||||
return _context.FrameControl.FlushAsync(cancellationToken);
|
return _context.FrameControl.FlushAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
@ -75,6 +84,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
throw new ObjectDisposedException(nameof(FrameResponseStream));
|
throw new ObjectDisposedException(nameof(FrameResponseStream));
|
||||||
}
|
}
|
||||||
|
if (_aborted)
|
||||||
|
{
|
||||||
|
throw new IOException("The request has been aborted.");
|
||||||
|
}
|
||||||
|
|
||||||
_context.FrameControl.Write(new ArraySegment<byte>(buffer, offset, count));
|
_context.FrameControl.Write(new ArraySegment<byte>(buffer, offset, count));
|
||||||
}
|
}
|
||||||
|
|
@ -85,6 +98,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
throw new ObjectDisposedException(nameof(FrameResponseStream));
|
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);
|
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
|
// As exampled in EngineTests.ZeroContentLengthNotSetAutomaticallyForCertainStatusCodes
|
||||||
_stopped = true;
|
_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)
|
public void Write(ArraySegment<byte> data, Action<Exception, object> callback, object state)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue