コード例 #1
0
        /// <summary>
        /// Initializes a new instance of <see cref="MultipartReader"/>.
        /// </summary>
        /// <param name="boundary">The multipart boundary.</param>
        /// <param name="stream">The <see cref="Stream"/> containing multipart data.</param>
        /// <param name="bufferSize">The minimum buffer size to use.</param>
        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
            };
        }
コード例 #2
0
        /// <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
            });
        }