1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System.Diagnostics;
6 using System.IO;
7 using System.Threading;
8 using System.Threading.Tasks;
9 
10 namespace System.Net.Http
11 {
12     internal sealed partial class HttpConnection : IDisposable
13     {
14         private sealed class HttpConnectionContent : HttpContent
15         {
16             private readonly CancellationToken _cancellationToken;
17             private HttpContentReadStream _stream;
18 
HttpConnectionContent(CancellationToken cancellationToken)19             public HttpConnectionContent(CancellationToken cancellationToken)
20             {
21                 _cancellationToken = cancellationToken;
22             }
23 
SetStream(HttpContentReadStream stream)24             public void SetStream(HttpContentReadStream stream)
25             {
26                 Debug.Assert(stream != null);
27                 Debug.Assert(stream.CanRead);
28 
29                 _stream = stream;
30             }
31 
ConsumeStream()32             private HttpContentReadStream ConsumeStream()
33             {
34                 if (_stream == null)
35                 {
36                     throw new InvalidOperationException(SR.net_http_content_stream_already_read);
37                 }
38 
39                 HttpContentReadStream stream = _stream;
40                 _stream = null;
41                 return stream;
42             }
43 
SerializeToStreamAsync(Stream stream, TransportContext context)44             protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context)
45             {
46                 Debug.Assert(stream != null);
47 
48                 using (HttpContentReadStream contentStream = ConsumeStream())
49                 {
50                     const int BufferSize = 8192;
51                     await contentStream.CopyToAsync(stream, BufferSize, _cancellationToken).ConfigureAwait(false);
52                 }
53             }
54 
TryComputeLength(out long length)55             protected internal override bool TryComputeLength(out long length)
56             {
57                 length = 0;
58                 return false;
59             }
60 
CreateContentReadStreamAsync()61             protected override Task<Stream> CreateContentReadStreamAsync() =>
62                 Task.FromResult<Stream>(ConsumeStream());
63 
TryCreateContentReadStream()64             internal override Stream TryCreateContentReadStream() =>
65                 ConsumeStream();
66 
Dispose(bool disposing)67             protected override void Dispose(bool disposing)
68             {
69                 if (disposing)
70                 {
71                     if (_stream != null)
72                     {
73                         _stream.Dispose();
74                         _stream = null;
75                     }
76                 }
77 
78                 base.Dispose(disposing);
79             }
80         }
81     }
82 }
83