| File: System\Net\Http\SocketsHttpHandler\HttpConnectionResponseContent.cs | Web Access |
| Project: src\runtime\src\libraries\System.Net.Http\src\System.Net.Http.csproj (System.Net.Http) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; using System.IO; using System.Threading; using System.Threading.Tasks; namespace System.Net.Http { internal sealed class HttpConnectionResponseContent : HttpContent { private Stream? _stream; private bool _consumedStream; // separate from _stream so that Dispose can drain _stream public void SetStream(Stream stream) { Debug.Assert(stream != null); Debug.Assert(stream.CanRead); Debug.Assert(!_consumedStream); _stream = stream; } private Stream ConsumeStream() { if (_consumedStream || _stream == null) { throw new InvalidOperationException(SR.net_http_content_stream_already_read); } _consumedStream = true; return _stream; } protected override void SerializeToStream(Stream stream, TransportContext? context, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(stream); using (Stream contentStream = ConsumeStream()) { const int BufferSize = 8192; contentStream.CopyTo(stream, BufferSize); } } protected sealed override Task SerializeToStreamAsync(Stream stream, TransportContext? context) => SerializeToStreamAsync(stream, context, CancellationToken.None); protected sealed override Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(stream); return Impl(stream, cancellationToken); async Task Impl(Stream stream, CancellationToken cancellationToken) { using (Stream contentStream = ConsumeStream()) { const int BufferSize = 8192; await contentStream.CopyToAsync(stream, BufferSize, cancellationToken).ConfigureAwait(false); } } } protected internal sealed override bool TryComputeLength(out long length) { length = 0; return false; } protected sealed override Stream CreateContentReadStream(CancellationToken cancellationToken) => ConsumeStream(); protected sealed override Task<Stream> CreateContentReadStreamAsync() => Task.FromResult<Stream>(ConsumeStream()); internal sealed override Stream TryCreateContentReadStream() => ConsumeStream(); internal override bool AllowDuplex => false; protected sealed override void Dispose(bool disposing) { if (disposing) { if (_stream != null) { _stream.Dispose(); _stream = null; } } base.Dispose(disposing); } } }