< Summary

Information
Class: System.Net.Http.MultipartContent
Assembly: System.Net.Http
File(s): D:\runner\runtime\src\libraries\System.Net.Http\src\System\Net\Http\MultipartContent.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 375
Coverable lines: 375
Total lines: 669
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 112
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

D:\runner\runtime\src\libraries\System.Net.Http\src\System\Net\Http\MultipartContent.cs

#LineLine coverage
 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
 4using System.Buffers;
 5using System.Collections.Generic;
 6using System.Diagnostics;
 7using System.IO;
 8using System.Net.Http.Headers;
 9using System.Text;
 10using System.Threading;
 11using System.Threading.Tasks;
 12
 13namespace System.Net.Http
 14{
 15    public class MultipartContent : HttpContent, IEnumerable<HttpContent>
 16    {
 17        #region Fields
 18
 19        private const string CrLf = "\r\n";
 20
 21        private const int CrLfLength = 2;
 22        private const int DashDashLength = 2;
 23        private const int ColonSpaceLength = 2;
 24        private const int CommaSpaceLength = 2;
 25
 026        private static readonly SearchValues<char> s_allowedBoundaryChars =
 027            SearchValues.Create(" '()+,-./0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz");
 28
 29        private readonly List<HttpContent> _nestedContent;
 30        private readonly string _boundary;
 31
 32        #endregion Fields
 33
 34        #region Construction
 35
 36        public MultipartContent()
 037            : this("mixed", GetDefaultBoundary())
 038        { }
 39
 40        public MultipartContent(string subtype)
 041            : this(subtype, GetDefaultBoundary())
 042        { }
 43
 044        public MultipartContent(string subtype, string boundary)
 045        {
 046            ArgumentException.ThrowIfNullOrWhiteSpace(subtype);
 047            ValidateBoundary(boundary);
 48
 049            _boundary = boundary;
 50
 051            string quotedBoundary = boundary;
 052            if (!quotedBoundary.StartsWith('\"'))
 053            {
 054                quotedBoundary = "\"" + quotedBoundary + "\"";
 055            }
 56
 057            MediaTypeHeaderValue contentType = new MediaTypeHeaderValue("multipart/" + subtype);
 058            contentType.Parameters.Add(new NameValueHeaderValue(nameof(boundary), quotedBoundary));
 059            Headers.ContentType = contentType;
 60
 061            _nestedContent = new List<HttpContent>();
 062        }
 63
 64        private static void ValidateBoundary(string boundary)
 065        {
 66            // NameValueHeaderValue is too restrictive for boundary.
 67            // Instead validate it ourselves and then quote it.
 068            ArgumentException.ThrowIfNullOrWhiteSpace(boundary);
 69
 70            // RFC 2046 Section 5.1.1
 71            // boundary := 0*69<bchars> bcharsnospace
 72            // bchars := bcharsnospace / " "
 73            // bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" / "+" / "_" / "," / "-" / "." / "/" / ":" / "=" / "?"
 074            if (boundary.Length > 70)
 075            {
 076                throw new ArgumentOutOfRangeException(nameof(boundary), boundary,
 077                    SR.Format(System.Globalization.CultureInfo.InvariantCulture, SR.net_http_content_field_too_long, 70)
 78            }
 79            // Cannot end with space.
 080            if (boundary.EndsWith(' '))
 081            {
 082                throw new ArgumentException(SR.Format(System.Globalization.CultureInfo.InvariantCulture, SR.net_http_hea
 83            }
 84
 085            if (boundary.AsSpan().ContainsAnyExcept(s_allowedBoundaryChars))
 086            {
 087                throw new ArgumentException(SR.Format(System.Globalization.CultureInfo.InvariantCulture, SR.net_http_hea
 88            }
 089        }
 90
 91        private static string GetDefaultBoundary()
 092        {
 093            return Guid.NewGuid().ToString();
 094        }
 95
 96        public virtual void Add(HttpContent content)
 097        {
 098            ArgumentNullException.ThrowIfNull(content);
 99
 0100            _nestedContent.Add(content);
 0101        }
 102
 103        #endregion Construction
 104
 105        #region Dispose
 106
 107        protected override void Dispose(bool disposing)
 0108        {
 0109            if (disposing)
 0110            {
 0111                foreach (HttpContent content in _nestedContent)
 0112                {
 0113                    content.Dispose();
 0114                }
 0115                _nestedContent.Clear();
 0116            }
 0117            base.Dispose(disposing);
 0118        }
 119
 120        #endregion Dispose
 121
 122        #region IEnumerable<HttpContent> Members
 123
 124        public IEnumerator<HttpContent> GetEnumerator()
 0125        {
 0126            return _nestedContent.GetEnumerator();
 0127        }
 128
 129        #endregion
 130
 131        #region IEnumerable Members
 132
 133        Collections.IEnumerator Collections.IEnumerable.GetEnumerator()
 0134        {
 0135            return _nestedContent.GetEnumerator();
 0136        }
 137
 138        #endregion
 139
 140        #region Serialization
 141
 142        /// <summary>
 143        /// Gets or sets a callback that returns the <see cref="Encoding"/> to decode the value for the specified respon
 144        /// or <see langword="null"/> to use the default behavior.
 145        /// </summary>
 0146        public HeaderEncodingSelector<HttpContent>? HeaderEncodingSelector { get; set; }
 147
 148        // for-each content
 149        //   write "--" + boundary
 150        //   for-each content header
 151        //     write header: header-value
 152        //   write content.CopyTo[Async]
 153        // write "--" + boundary + "--"
 154        // Can't be canceled directly by the user.  If the overall request is canceled
 155        // then the stream will be closed an exception thrown.
 156        protected override void SerializeToStream(Stream stream, TransportContext? context, CancellationToken cancellati
 0157        {
 0158            Debug.Assert(stream != null);
 159            try
 0160            {
 161                // Write start boundary.
 0162                WriteToStream(stream, "--" + _boundary + CrLf);
 163
 164                // Write each nested content.
 0165                for (int contentIndex = 0; contentIndex < _nestedContent.Count; contentIndex++)
 0166                {
 167                    // Write divider, headers, and content.
 0168                    HttpContent content = _nestedContent[contentIndex];
 0169                    SerializeHeadersToStream(stream, content, writeDivider: contentIndex != 0);
 0170                    content.CopyTo(stream, context, cancellationToken);
 0171                }
 172
 173                // Write footer boundary.
 0174                WriteToStream(stream, CrLf + "--" + _boundary + "--" + CrLf);
 0175            }
 0176            catch (Exception ex)
 0177            {
 0178                if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(this, ex);
 0179                throw;
 180            }
 0181        }
 182
 183        // for-each content
 184        //   write "--" + boundary
 185        //   for-each content header
 186        //     write header: header-value
 187        //   write content.CopyTo[Async]
 188        // write "--" + boundary + "--"
 189        // Can't be canceled directly by the user.  If the overall request is canceled
 190        // then the stream will be closed an exception thrown.
 191        protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context) =>
 0192            SerializeToStreamAsyncCore(stream, context, default);
 193
 194        protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cance
 195            // Only skip the original protected virtual SerializeToStreamAsync if this
 196            // isn't a derived type that may have overridden the behavior.
 0197            GetType() == typeof(MultipartContent) ? SerializeToStreamAsyncCore(stream, context, cancellationToken) :
 0198            base.SerializeToStreamAsync(stream, context, cancellationToken);
 199
 200        private protected async Task SerializeToStreamAsyncCore(Stream stream, TransportContext? context, CancellationTo
 0201        {
 0202            Debug.Assert(stream != null);
 203            try
 0204            {
 205                // Write start boundary.
 0206                await EncodeStringToStreamAsync(stream, "--" + _boundary + CrLf, cancellationToken).ConfigureAwait(false
 207
 208                // Write each nested content.
 0209                var output = new MemoryStream();
 0210                for (int contentIndex = 0; contentIndex < _nestedContent.Count; contentIndex++)
 0211                {
 212                    // Write divider, headers, and content.
 0213                    HttpContent content = _nestedContent[contentIndex];
 214
 0215                    output.SetLength(0);
 0216                    SerializeHeadersToStream(output, content, writeDivider: contentIndex != 0);
 0217                    output.Position = 0;
 0218                    await output.CopyToAsync(stream, cancellationToken).ConfigureAwait(false);
 219
 0220                    await content.CopyToAsync(stream, context, cancellationToken).ConfigureAwait(false);
 0221                }
 222
 223                // Write footer boundary.
 0224                await EncodeStringToStreamAsync(stream, CrLf + "--" + _boundary + "--" + CrLf, cancellationToken).Config
 0225            }
 0226            catch (Exception ex)
 0227            {
 0228                if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(this, ex);
 0229                throw;
 230            }
 0231        }
 232
 233        protected override Stream CreateContentReadStream(CancellationToken cancellationToken)
 0234        {
 0235            ValueTask<Stream> task = CreateContentReadStreamAsyncCore(async: false, cancellationToken);
 0236            Debug.Assert(task.IsCompleted);
 0237            return task.GetAwaiter().GetResult();
 0238        }
 239
 240        protected override Task<Stream> CreateContentReadStreamAsync() =>
 0241            CreateContentReadStreamAsyncCore(async: true, CancellationToken.None).AsTask();
 242
 243        protected override Task<Stream> CreateContentReadStreamAsync(CancellationToken cancellationToken) =>
 244            // Only skip the original protected virtual CreateContentReadStreamAsync if this
 245            // isn't a derived type that may have overridden the behavior.
 0246            GetType() == typeof(MultipartContent) ? CreateContentReadStreamAsyncCore(async: true, cancellationToken).AsT
 0247            base.CreateContentReadStreamAsync(cancellationToken);
 248
 249        private async ValueTask<Stream> CreateContentReadStreamAsyncCore(bool async, CancellationToken cancellationToken
 0250        {
 251            try
 0252            {
 0253                var streams = new Stream[2 + (_nestedContent.Count * 2)];
 0254                int streamIndex = 0;
 255
 256                // Start boundary.
 0257                streams[streamIndex++] = EncodeStringToNewStream("--" + _boundary + CrLf);
 258
 259                // Each nested content.
 0260                for (int contentIndex = 0; contentIndex < _nestedContent.Count; contentIndex++)
 0261                {
 0262                    cancellationToken.ThrowIfCancellationRequested();
 263
 0264                    HttpContent nestedContent = _nestedContent[contentIndex];
 0265                    streams[streamIndex++] = EncodeHeadersToNewStream(nestedContent, writeDivider: contentIndex != 0);
 266
 267                    Stream readStream;
 0268                    if (async)
 0269                    {
 0270                        readStream = nestedContent.TryReadAsStream() ?? await nestedContent.ReadAsStreamAsync(cancellati
 0271                    }
 272                    else
 0273                    {
 0274                        readStream = nestedContent.ReadAsStream(cancellationToken);
 0275                    }
 276                    // Cannot be null, at least an empty stream is necessary.
 0277                    readStream ??= new MemoryStream();
 278
 0279                    if (!readStream.CanSeek)
 0280                    {
 281                        // Seekability impacts whether HttpClientHandlers are able to rewind. To maintain compat
 282                        // and to allow such use cases when a nested stream isn't seekable (which should be rare),
 283                        // we fall back to the base behavior. We don't dispose of the streams already obtained
 284                        // as we don't necessarily own them yet.
 285
 286#pragma warning disable CA2016
 287                        // Do not pass a cancellationToken to base.CreateContentReadStreamAsync() as it would trigger an
 0288                        return async ? await base.CreateContentReadStreamAsync().ConfigureAwait(false) : base.CreateCont
 289#pragma warning restore CA2016
 290                    }
 0291                    streams[streamIndex++] = readStream;
 0292                }
 293
 294                // Footer boundary.
 0295                streams[streamIndex] = EncodeStringToNewStream(CrLf + "--" + _boundary + "--" + CrLf);
 296
 0297                return new ContentReadStream(streams);
 298            }
 0299            catch (Exception ex)
 0300            {
 0301                if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(this, ex);
 0302                throw;
 303            }
 0304        }
 305
 306        private void SerializeHeadersToStream(Stream stream, HttpContent content, bool writeDivider)
 0307        {
 308            // Add divider.
 0309            if (writeDivider) // Write divider for all but the first content.
 0310            {
 0311                WriteToStream(stream, CrLf + "--"); // const strings
 0312                WriteToStream(stream, _boundary);
 0313                WriteToStream(stream, CrLf);
 0314            }
 315
 316            // Add headers.
 0317            foreach (KeyValuePair<string, HeaderStringValues> headerPair in content.Headers.NonValidated)
 0318            {
 0319                Encoding headerValueEncoding = HeaderEncodingSelector?.Invoke(headerPair.Key, content) ?? HttpRuleParser
 320
 0321                WriteToStream(stream, headerPair.Key);
 0322                WriteToStream(stream, ": ");
 0323                string delim = string.Empty;
 0324                foreach (string value in headerPair.Value)
 0325                {
 0326                    WriteToStream(stream, delim);
 0327                    WriteToStream(stream, value, headerValueEncoding);
 0328                    delim = ", ";
 0329                }
 0330                WriteToStream(stream, CrLf);
 0331            }
 332
 333            // Extra CRLF to end headers (even if there are no headers).
 0334            WriteToStream(stream, CrLf);
 0335        }
 336
 337        private static ValueTask EncodeStringToStreamAsync(Stream stream, string input, CancellationToken cancellationTo
 0338        {
 0339            byte[] buffer = HttpRuleParser.DefaultHttpEncoding.GetBytes(input);
 0340            return stream.WriteAsync(new ReadOnlyMemory<byte>(buffer), cancellationToken);
 0341        }
 342
 343        private static MemoryStream EncodeStringToNewStream(string input)
 0344        {
 0345            return new MemoryStream(HttpRuleParser.DefaultHttpEncoding.GetBytes(input), writable: false);
 0346        }
 347
 348        private MemoryStream EncodeHeadersToNewStream(HttpContent content, bool writeDivider)
 0349        {
 0350            var stream = new MemoryStream();
 0351            SerializeHeadersToStream(stream, content, writeDivider);
 0352            stream.Position = 0;
 0353            return stream;
 0354        }
 355
 0356        internal override bool AllowDuplex => false;
 357
 358        protected internal override bool TryComputeLength(out long length)
 0359        {
 360            // Start Boundary.
 0361            long currentLength = DashDashLength + _boundary.Length + CrLfLength;
 362
 0363            if (_nestedContent.Count > 1)
 0364            {
 365                // Internal boundaries
 0366                currentLength += (_nestedContent.Count - 1) * (CrLfLength + DashDashLength + _boundary.Length + CrLfLeng
 0367            }
 368
 0369            foreach (HttpContent content in _nestedContent)
 0370            {
 371                // Headers.
 0372                foreach (KeyValuePair<string, HeaderStringValues> headerPair in content.Headers.NonValidated)
 0373                {
 0374                    currentLength += headerPair.Key.Length + ColonSpaceLength;
 375
 0376                    Encoding headerValueEncoding = HeaderEncodingSelector?.Invoke(headerPair.Key, content) ?? HttpRulePa
 377
 0378                    int valueCount = 0;
 0379                    foreach (string value in headerPair.Value)
 0380                    {
 0381                        currentLength += headerValueEncoding.GetByteCount(value);
 0382                        valueCount++;
 0383                    }
 384
 0385                    if (valueCount > 1)
 0386                    {
 0387                        currentLength += (valueCount - 1) * CommaSpaceLength;
 0388                    }
 389
 0390                    currentLength += CrLfLength;
 0391                }
 392
 0393                currentLength += CrLfLength;
 394
 395                // Content.
 0396                if (!content.TryComputeLength(out long tempContentLength))
 0397                {
 0398                    length = 0;
 0399                    return false;
 400                }
 0401                currentLength += tempContentLength;
 0402            }
 403
 404            // Terminating boundary.
 0405            currentLength += CrLfLength + DashDashLength + _boundary.Length + DashDashLength + CrLfLength;
 406
 0407            length = currentLength;
 0408            return true;
 0409        }
 410
 411        private sealed class ContentReadStream : Stream
 412        {
 413            private readonly Stream[] _streams;
 414            private readonly long _length;
 415
 416            private int _next;
 417            private Stream? _current;
 418            private long _position;
 419
 0420            internal ContentReadStream(Stream[] streams)
 0421            {
 0422                Debug.Assert(streams != null);
 0423                _streams = streams;
 0424                foreach (Stream stream in streams)
 0425                {
 0426                    _length += stream.Length;
 0427                }
 0428            }
 429
 430            protected override void Dispose(bool disposing)
 0431            {
 0432                if (disposing)
 0433                {
 0434                    foreach (Stream s in _streams)
 0435                    {
 0436                        s.Dispose();
 0437                    }
 0438                }
 0439            }
 440
 441            public override async ValueTask DisposeAsync()
 0442            {
 0443                foreach (Stream s in _streams)
 0444                {
 0445                    await s.DisposeAsync().ConfigureAwait(false);
 0446                }
 0447            }
 448
 0449            public override bool CanRead => true;
 0450            public override bool CanSeek => true;
 0451            public override bool CanWrite => false;
 452
 453            public override int Read(byte[] buffer, int offset, int count)
 0454            {
 0455                ValidateBufferArguments(buffer, offset, count);
 0456                if (count == 0)
 0457                {
 0458                    return 0;
 459                }
 460
 0461                while (true)
 0462                {
 0463                    if (_current != null)
 0464                    {
 0465                        int bytesRead = _current.Read(buffer, offset, count);
 0466                        if (bytesRead != 0)
 0467                        {
 0468                            _position += bytesRead;
 0469                            return bytesRead;
 470                        }
 471
 0472                        _current = null;
 0473                    }
 474
 0475                    if (_next >= _streams.Length)
 0476                    {
 0477                        return 0;
 478                    }
 479
 0480                    _current = _streams[_next++];
 0481                }
 0482            }
 483
 484            public override int ReadByte()
 0485            {
 0486                byte b = 0;
 0487                return Read(new Span<byte>(ref b)) == 1 ? b : -1;
 0488            }
 489
 490            public override int Read(Span<byte> buffer)
 0491            {
 0492                if (buffer.Length == 0)
 0493                {
 0494                    return 0;
 495                }
 496
 0497                while (true)
 0498                {
 0499                    if (_current != null)
 0500                    {
 0501                        int bytesRead = _current.Read(buffer);
 0502                        if (bytesRead != 0)
 0503                        {
 0504                            _position += bytesRead;
 0505                            return bytesRead;
 506                        }
 507
 0508                        _current = null;
 0509                    }
 510
 0511                    if (_next >= _streams.Length)
 0512                    {
 0513                        return 0;
 514                    }
 515
 0516                    _current = _streams[_next++];
 0517                }
 0518            }
 519
 520            public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToke
 0521            {
 0522                ValidateBufferArguments(buffer, offset, count);
 0523                return ReadAsyncPrivate(new Memory<byte>(buffer, offset, count), cancellationToken).AsTask();
 0524            }
 525
 526            public override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default)
 0527                ReadAsyncPrivate(buffer, cancellationToken);
 528
 529            public override IAsyncResult BeginRead(byte[] array, int offset, int count, AsyncCallback? asyncCallback, ob
 0530                TaskToAsyncResult.Begin(ReadAsync(array, offset, count, CancellationToken.None), asyncCallback, asyncSta
 531
 532            public override int EndRead(IAsyncResult asyncResult) =>
 0533                TaskToAsyncResult.End<int>(asyncResult);
 534
 535            public async ValueTask<int> ReadAsyncPrivate(Memory<byte> buffer, CancellationToken cancellationToken)
 0536            {
 0537                if (buffer.Length == 0)
 0538                {
 0539                    return 0;
 540                }
 541
 0542                while (true)
 0543                {
 0544                    if (_current != null)
 0545                    {
 0546                        int bytesRead = await _current.ReadAsync(buffer, cancellationToken).ConfigureAwait(false);
 0547                        if (bytesRead != 0)
 0548                        {
 0549                            _position += bytesRead;
 0550                            return bytesRead;
 551                        }
 552
 0553                        _current = null;
 0554                    }
 555
 0556                    if (_next >= _streams.Length)
 0557                    {
 0558                        return 0;
 559                    }
 560
 0561                    _current = _streams[_next++];
 0562                }
 0563            }
 564
 565            public override long Position
 566            {
 0567                get { return _position; }
 568                set
 0569                {
 0570                    ArgumentOutOfRangeException.ThrowIfNegative(value);
 571
 0572                    long previousStreamsLength = 0;
 0573                    for (int i = 0; i < _streams.Length; i++)
 0574                    {
 0575                        Stream curStream = _streams[i];
 0576                        long curLength = curStream.Length;
 577
 0578                        if (value < previousStreamsLength + curLength)
 0579                        {
 0580                            _current = curStream;
 0581                            i++;
 0582                            _next = i;
 583
 0584                            curStream.Position = value - previousStreamsLength;
 0585                            for (; i < _streams.Length; i++)
 0586                            {
 0587                                _streams[i].Position = 0;
 0588                            }
 589
 0590                            _position = value;
 0591                            return;
 592                        }
 593
 0594                        previousStreamsLength += curLength;
 0595                    }
 596
 0597                    _current = null;
 0598                    _next = _streams.Length;
 0599                    _position = value;
 0600                }
 601            }
 602
 603            public override long Seek(long offset, SeekOrigin origin)
 0604            {
 0605                switch (origin)
 606                {
 607                    case SeekOrigin.Begin:
 0608                        Position = offset;
 0609                        break;
 610
 611                    case SeekOrigin.Current:
 0612                        Position += offset;
 0613                        break;
 614
 615                    case SeekOrigin.End:
 0616                        Position = _length + offset;
 0617                        break;
 618
 619                    default:
 0620                        throw new ArgumentOutOfRangeException(nameof(origin));
 621                }
 622
 0623                return Position;
 0624            }
 625
 0626            public override long Length => _length;
 627
 0628            public override void Flush() { }
 0629            public override Task FlushAsync(CancellationToken cancellationToken) => Task.CompletedTask;
 630
 0631            public override void SetLength(long value) { throw new NotSupportedException(); }
 0632            public override void Write(byte[] buffer, int offset, int count) { throw new NotSupportedException(); }
 0633            public override void Write(ReadOnlySpan<byte> buffer) { throw new NotSupportedException(); }
 0634            public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) {
 0635            public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = defa
 636        }
 637
 638
 639        private static void WriteToStream(Stream stream, string content) =>
 0640            WriteToStream(stream, content, HttpRuleParser.DefaultHttpEncoding);
 641
 642        private static void WriteToStream(Stream stream, string content, Encoding encoding)
 0643        {
 644            const int StackallocThreshold = 1024;
 645
 0646            int maxLength = encoding.GetMaxByteCount(content.Length);
 647
 0648            byte[]? rentedBuffer = null;
 0649            Span<byte> buffer = maxLength <= StackallocThreshold
 0650                ? stackalloc byte[StackallocThreshold]
 0651                : (rentedBuffer = ArrayPool<byte>.Shared.Rent(maxLength));
 652
 653            try
 0654            {
 0655                int written = encoding.GetBytes(content, buffer);
 0656                stream.Write(buffer.Slice(0, written));
 0657            }
 658            finally
 0659            {
 0660                if (rentedBuffer != null)
 0661                {
 0662                    ArrayPool<byte>.Shared.Return(rentedBuffer);
 0663                }
 0664            }
 0665        }
 666
 667        #endregion Serialization
 668    }
 669}

Methods/Properties

.cctor()
.ctor()
.ctor(System.String)
.ctor(System.String,System.String)
ValidateBoundary(System.String)
GetDefaultBoundary()
Add(System.Net.Http.HttpContent)
Dispose(System.Boolean)
GetEnumerator()
System.Collections.IEnumerable.GetEnumerator()
HeaderEncodingSelector()
SerializeToStream(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken)
SerializeToStreamAsync(System.IO.Stream,System.Net.TransportContext)
SerializeToStreamAsync(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken)
SerializeToStreamAsyncCore()
CreateContentReadStream(System.Threading.CancellationToken)
CreateContentReadStreamAsync()
CreateContentReadStreamAsync(System.Threading.CancellationToken)
CreateContentReadStreamAsyncCore()
SerializeHeadersToStream(System.IO.Stream,System.Net.Http.HttpContent,System.Boolean)
EncodeStringToStreamAsync(System.IO.Stream,System.String,System.Threading.CancellationToken)
EncodeStringToNewStream(System.String)
EncodeHeadersToNewStream(System.Net.Http.HttpContent,System.Boolean)
AllowDuplex()
TryComputeLength(System.Int64&)
.ctor(System.IO.Stream[])
Dispose(System.Boolean)
DisposeAsync()
CanRead()
CanSeek()
CanWrite()
Read(System.Byte[],System.Int32,System.Int32)
ReadByte()
Read(System.Span`1<System.Byte>)
ReadAsync(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken)
ReadAsync(System.Memory`1<System.Byte>,System.Threading.CancellationToken)
BeginRead(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object)
EndRead(System.IAsyncResult)
ReadAsyncPrivate()
Position()
Position(System.Int64)
Seek(System.Int64,System.IO.SeekOrigin)
Length()
Flush()
FlushAsync(System.Threading.CancellationToken)
SetLength(System.Int64)
Write(System.Byte[],System.Int32,System.Int32)
Write(System.ReadOnlySpan`1<System.Byte>)
WriteAsync(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken)
WriteAsync(System.ReadOnlyMemory`1<System.Byte>,System.Threading.CancellationToken)
WriteToStream(System.IO.Stream,System.String)
WriteToStream(System.IO.Stream,System.String,System.Text.Encoding)