async Task EnsureChunkHeaderWasReadAsync( CancellationToken cancellationToken) { while (_currentChunkHeader == null) { cancellationToken.ThrowIfCancellationRequested(); // Read var bytesRead = await _requestStream.ReadAsync(_readBuffer, 0, _readBuffer.Length); HttpPrematureFinishException.ThrowIfZero(bytesRead); // Append the data we just read to the header builder. // If header is built after this call, we are done here. int contentStartIndex; if (_chunkHeaderBuilder.AppendBuffer(_readBuffer, 0, bytesRead, out contentStartIndex)) { // Set current chunk metadata _currentChunkHeader = _chunkHeaderBuilder.Result; _currentChunkRemainingBytes = _chunkHeaderBuilder.Result.Length; // If we read some bytes from the body, rollback those read. _requestStream.TryRollbackFromIndex( _readBuffer, srcLength: bytesRead, startIndex: contentStartIndex); } } }
/// <summary> /// Called when current chunk has no more data to read, /// we'll do some cleaning here. /// </summary> async Task CompleteReadingCurrentChunkAsync() { // A chunk always nend with a new line character, // let's skip it. var bytesRead = await _requestStream.ReadAsync(_readBuffer, 0, _readBuffer.Length); HttpPrematureFinishException.ThrowIfZero(bytesRead); if (false == _lineBuilder.AppendBuffer(_readBuffer, 0, bytesRead, out int nextLineStartIndex)) { throw new HttpBadRequestException( "Chunk body must end with an empty line" ); } _lineBuilder.Reset(); _requestStream.TryRollbackFromIndex(_readBuffer, bytesRead, nextLineStartIndex); // Prepare to read the next header _chunkHeaderBuilder.Reset(); // Clear the header, so next ReadAsync() operation // will attempt to read the next header _currentChunkHeader = null; }
public bool AppendBuffer( byte[] buffer, int start, int count, out int contentStartIndex) { Validation.RequireValidBuffer(buffer, start, count); RequireNullResult(); // Early exit if there is no new line in the appended buffer; contentStartIndex = default(int); int nextLineStartIndex; if (false == _lineBuilder.AppendBuffer(buffer, start, count, out nextLineStartIndex)) { return(false); } // New line found in the supplied buffer! // The chunk header ends here contentStartIndex = nextLineStartIndex; _result = BuildResult(_lineBuilder.Result); return(true); }
public void Reset() { _lineBuilder.Reset(); _result = null; }