/// <summary> /// Reads the next <see cref="MultipartSection"/>. /// </summary> /// <param name="cancellationToken">The token to monitor for cancellation requests. /// The default value is <see cref="CancellationToken.None"/>.</param> /// <returns></returns> public async Task <MultipartSection?> ReadNextSectionAsync(CancellationToken cancellationToken = new CancellationToken()) { // Drain the prior section. await _currentStream.DrainAsync(cancellationToken); // If we're at the end return null if (_currentStream.FinalBoundaryFound) { // There may be trailer data after the last boundary. await _stream.DrainAsync(HeadersLengthLimit, cancellationToken); return(null); } var headers = await ReadHeadersAsync(cancellationToken); _boundary.ExpectLeadingCrlf = true; _currentStream = new MultipartReaderStream(_stream, _boundary) { LengthLimit = BodyLengthLimit }; long?baseStreamOffset = _stream.CanSeek ? (long?)_stream.Position : null; return(new MultipartSection() { Headers = headers, Body = _currentStream, BaseStreamOffset = baseStreamOffset }); }