public async Task <MultipartSection> ReadNextSectionAsync(CancellationToken cancellationToken = new CancellationToken()) { // Drain the prior section. await _currentStream.ConsumeAsync(cancellationToken); // If we're at the end return null if (_currentStream.FinalBoundaryFound) { // There may be trailer data after the last boundary. await _stream.ConsumeAsync(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 }); }
public MultipartReader(string boundary, Stream stream, int bufferSize) { if (boundary == null) { throw new ArgumentNullException(nameof(boundary)); } if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (bufferSize < boundary.Length + 8) // Size of the boundary + leading and trailing CRLF + leading and trailing '--' markers. { throw new ArgumentOutOfRangeException(nameof(bufferSize), bufferSize, "Insufficient buffer space, the buffer must be larger than the boundary: " + boundary); } _stream = new BufferedReadStream(stream, bufferSize); _boundary = new MultipartBoundary(boundary, false); // This stream will drain any preamble data and remove the first boundary marker. // TODO: HeadersLengthLimit can't be modified until after the constructor. _currentStream = new MultipartReaderStream(_stream, _boundary) { LengthLimit = HeadersLengthLimit }; }