Stop streams on finish
Can't use dispose (or close) as can be disposed too early by user code Resolves #263
This commit is contained in:
parent
8c0a1701cd
commit
f60f6c92ca
|
|
@ -204,8 +204,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
{
|
||||
MessageBody = MessageBody.For(HttpVersion, _requestHeaders, this);
|
||||
_keepAlive = MessageBody.RequestKeepAlive;
|
||||
RequestBody = new FrameRequestStream(MessageBody);
|
||||
ResponseBody = new FrameResponseStream(this);
|
||||
var requestBody = new FrameRequestStream(MessageBody);
|
||||
RequestBody = requestBody;
|
||||
var responseBody = new FrameResponseStream(this);
|
||||
ResponseBody = responseBody;
|
||||
DuplexStream = new FrameDuplexStream(RequestBody, ResponseBody);
|
||||
|
||||
var httpContext = HttpContextFactory.Create(this);
|
||||
|
|
@ -236,6 +238,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
|
||||
// Finish reading the request body in case the app did not.
|
||||
await MessageBody.Consume();
|
||||
|
||||
requestBody.StopAcceptingReads();
|
||||
responseBody.StopAcceptingWrites();
|
||||
}
|
||||
|
||||
terminated = !_keepAlive;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
public class FrameRequestStream : Stream
|
||||
{
|
||||
private readonly MessageBody _body;
|
||||
private bool _stopped;
|
||||
|
||||
public FrameRequestStream(MessageBody body)
|
||||
{
|
||||
|
|
@ -50,12 +51,22 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (_stopped)
|
||||
{
|
||||
throw new ObjectDisposedException("RequestStream has been disposed");
|
||||
}
|
||||
|
||||
return ReadAsync(buffer, offset, count).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
#if NET451
|
||||
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
|
||||
{
|
||||
if (_stopped)
|
||||
{
|
||||
throw new ObjectDisposedException("RequestStream has been disposed");
|
||||
}
|
||||
|
||||
var task = ReadAsync(buffer, offset, count, CancellationToken.None, state);
|
||||
if (callback != null)
|
||||
{
|
||||
|
|
@ -71,6 +82,11 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
|
||||
private Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken, object state)
|
||||
{
|
||||
if (_stopped)
|
||||
{
|
||||
throw new ObjectDisposedException("RequestStream has been disposed");
|
||||
}
|
||||
|
||||
var tcs = new TaskCompletionSource<int>(state);
|
||||
var task = _body.ReadAsync(new ArraySegment<byte>(buffer, offset, count), cancellationToken);
|
||||
task.ContinueWith((task2, state2) =>
|
||||
|
|
@ -102,5 +118,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void StopAcceptingReads()
|
||||
{
|
||||
_stopped = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
class FrameResponseStream : Stream
|
||||
{
|
||||
private readonly FrameContext _context;
|
||||
private bool _stopped;
|
||||
|
||||
public FrameResponseStream(FrameContext context)
|
||||
{
|
||||
|
|
@ -35,11 +36,21 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
|
||||
public override void Flush()
|
||||
{
|
||||
if (_stopped)
|
||||
{
|
||||
throw new ObjectDisposedException("ResponseStream has been disposed");
|
||||
}
|
||||
|
||||
_context.FrameControl.Flush();
|
||||
}
|
||||
|
||||
public override Task FlushAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
if (_stopped)
|
||||
{
|
||||
throw new ObjectDisposedException("ResponseStream has been disposed");
|
||||
}
|
||||
|
||||
return _context.FrameControl.FlushAsync(cancellationToken);
|
||||
}
|
||||
|
||||
|
|
@ -60,12 +71,27 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (_stopped)
|
||||
{
|
||||
throw new ObjectDisposedException("ResponseStream has been disposed");
|
||||
}
|
||||
|
||||
_context.FrameControl.Write(new ArraySegment<byte>(buffer, offset, count));
|
||||
}
|
||||
|
||||
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
{
|
||||
if (_stopped)
|
||||
{
|
||||
throw new ObjectDisposedException("ResponseStream has been disposed");
|
||||
}
|
||||
|
||||
return _context.FrameControl.WriteAsync(new ArraySegment<byte>(buffer, offset, count), cancellationToken);
|
||||
}
|
||||
|
||||
public void StopAcceptingWrites()
|
||||
{
|
||||
_stopped = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue