private Dictionary <string, StringValues> ReadHeaders() { int totalSize = 0; var accumulator = new KeyMultValuesPair(); var line = _stream.ReadLine(HeadersLengthLimit - totalSize); while (!string.IsNullOrEmpty(line)) { if (HeadersLengthLimit - totalSize < line.Length) { throw new InvalidDataException($"Multipart headers length limit {HeadersLengthLimit} exceeded."); } totalSize += line.Length; int splitIndex = line.IndexOf(':'); if (splitIndex <= 0) { throw new InvalidDataException($"Invalid header line: {line}"); } var name = line.Substring(0, splitIndex); var value = line.Substring(splitIndex + 1, line.Length - splitIndex - 1).Trim(); accumulator.Append(name, value); if (accumulator.KeyCount > HeadersCountLimit) { throw new InvalidDataException($"Multipart headers count limit {HeadersCountLimit} exceeded."); } line = _stream.ReadLine(HeadersLengthLimit - totalSize); } return(accumulator.GetResults()); }
public override int Read(byte[] buffer, int offset, int count) { if (_finished) { return(0); } PositionInnerStream(); if (!_innerStream.EnsureBuffered(_boundary.FinalBoundaryLength)) { throw new IOException("Unexpected end of Stream, the content may have already been read by another component. "); } var bufferedData = _innerStream.BufferedData; // scan for a boundary match, full or partial. int read; if (SubMatch(bufferedData, _boundary.BoundaryBytes, out var matchOffset, out var matchCount)) { // We found a possible match, return any data before it. if (matchOffset > bufferedData.Offset) { read = _innerStream.Read(buffer, offset, Math.Min(count, matchOffset - bufferedData.Offset)); return(UpdatePosition(read)); } var length = _boundary.BoundaryBytes.Length; Debug.Assert(matchCount == length); // "The boundary may be followed by zero or more characters of // linear whitespace. It is then terminated by either another CRLF" // or -- for the final boundary. var boundary = _bytePool.Rent(length); read = _innerStream.Read(boundary, 0, length); _bytePool.Return(boundary); Debug.Assert(read == length); // It should have all been buffered var remainder = _innerStream.ReadLine(lengthLimit: 100); // Whitespace may exceed the buffer. remainder = remainder.Trim(); if (string.Equals("--", remainder, StringComparison.Ordinal)) { FinalBoundaryFound = true; } Debug.Assert(FinalBoundaryFound || string.Equals(string.Empty, remainder, StringComparison.Ordinal), "Un-expected data found on the boundary line: " + remainder); _finished = true; return(0); } // No possible boundary match within the buffered data, return the data from the buffer. read = _innerStream.Read(buffer, offset, Math.Min(count, bufferedData.Count)); return(UpdatePosition(read)); }