Await dispose for inner stream before disposing SslStream. (#11819)

This commit is contained in:
Justin Kotalik 2019-07-09 08:20:10 -07:00 коммит произвёл GitHub
Родитель 59d636f6bd
Коммит 401a90633b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 19 добавлений и 3 удалений

Просмотреть файл

@ -234,8 +234,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal
// Disposing the stream will dispose the sslDuplexPipe
await using (sslStream)
await using (sslDuplexPipe)
{
await _next(context);
// Dispose the inner stream (SslDuplexPipe) before disposing the SslStream
// as the duplex pipe can hit an ODE as it still may be writing.
}
}
finally

Просмотреть файл

@ -17,6 +17,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
{
private readonly Pipe _output;
private Task _outputTask;
private bool _disposed;
private readonly object _disposeLock = new object();
public DuplexPipeStreamAdapter(IDuplexPipe duplexPipe, Func<Stream, TStream> createStream) :
this(duplexPipe, new StreamPipeReaderOptions(leaveOpen: true), new StreamPipeWriterOptions(leaveOpen: true), createStream)
@ -63,17 +65,28 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
}
}
public override async ValueTask DisposeAsync()
public override ValueTask DisposeAsync()
{
lock (_disposeLock)
{
if (_disposed)
{
return default;
}
_disposed = true;
}
Input.Complete();
_output.Writer.Complete();
if (_outputTask != null)
if (_outputTask == null || _outputTask.IsCompletedSuccessfully)
{
// Wait for the output task to complete, this ensures that we've copied
// the application data to the underlying stream
await _outputTask;
return default;
}
return new ValueTask(_outputTask);
}
private async Task WriteOutputAsync()