public void PeekReturnsMinuOneByteInTheEnd() { var reader = new ReadableBufferReader(ReadableBuffer.Create(new byte[] { 1, 2 }, 0, 2)); Assert.Equal(1, reader.Take()); Assert.Equal(2, reader.Take()); Assert.Equal(-1, reader.Peek()); }
public void TakeReturnsByteAndMoves() { var reader = new ReadableBufferReader(ReadableBuffer.Create(new byte[] { 1, 2 }, 0, 2)); Assert.Equal(1, reader.Take()); Assert.Equal(2, reader.Take()); Assert.Equal(-1, reader.Take()); }
public void CursorIsCorrectWithEmptyLastBlock() { var last = new BufferSegment(); last.SetMemory(new OwnedArray <byte>(new byte[4]), 0, 4); var first = new BufferSegment(); first.SetMemory(new OwnedArray <byte>(new byte[2] { 1, 2 }), 0, 2); first.SetNext(last); var start = new ReadCursor(first); var end = new ReadCursor(last); var reader = new ReadableBufferReader(start, end); reader.Take(); reader.Take(); reader.Take(); Assert.Same(last, reader.Cursor.Segment); Assert.Equal(0, reader.Cursor.Index); Assert.True(reader.End); }
public void PeekReturnsMinuOneByteInTheEnd() { var reader = new ReadableBufferReader(Factory.CreateWithContent(new byte[] { 1, 2 })); Assert.Equal(1, reader.Take()); Assert.Equal(2, reader.Take()); Assert.Equal(-1, reader.Peek()); }
public void CursorIsCorrectAtEnd() { var reader = new ReadableBufferReader(Factory.CreateWithContent(new byte[] { 1, 2 })); reader.Take(); reader.Take(); Assert.True(reader.End); }
public void CursorIsCorrectAtEnd() { var reader = new ReadableBufferReader(ReadableBuffer.Create(new byte[] { 1, 2 }, 0, 2)); reader.Take(); reader.Take(); Assert.True(reader.End); Assert.True(reader.Cursor.IsEnd); }
private void ParseChunkedPrefix(ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined) { consumed = buffer.Start; examined = buffer.Start; var reader = new ReadableBufferReader(buffer); var ch1 = reader.Take(); var ch2 = reader.Take(); if (ch1 == -1 || ch2 == -1) { examined = reader.Cursor; return; } var chunkSize = CalculateChunkSize(ch1, 0); ch1 = ch2; while (reader.ConsumedBytes < MaxChunkPrefixBytes) { if (ch1 == ';') { consumed = reader.Cursor; examined = reader.Cursor; AddAndCheckConsumedBytes(reader.ConsumedBytes); _inputLength = chunkSize; _mode = Mode.Extension; return; } ch2 = reader.Take(); if (ch2 == -1) { examined = reader.Cursor; return; } if (ch1 == '\r' && ch2 == '\n') { consumed = reader.Cursor; examined = reader.Cursor; AddAndCheckConsumedBytes(reader.ConsumedBytes); _inputLength = chunkSize; _mode = chunkSize > 0 ? Mode.Data : Mode.Trailer; return; } chunkSize = CalculateChunkSize(ch1, chunkSize); ch1 = ch2; } // At this point, 10 bytes have been consumed which is enough to parse the max value "7FFFFFFF\r\n". _context.ThrowRequestRejected(RequestRejectionReason.BadChunkSizeData); }
public void TakeTraversesSegments() { var buffer = Factory.CreateWithContent(new byte[] { 1, 2, 3 }); var reader = new ReadableBufferReader(buffer); Assert.Equal(1, reader.Take()); Assert.Equal(2, reader.Take()); Assert.Equal(3, reader.Take()); Assert.Equal(-1, reader.Take()); }
public void TakeTraversesSegments() { var buffer = BufferUtilities.CreateBuffer(new[] { new byte[] { 1 }, new byte[] { 2 }, new byte[] { 3 } }); var reader = new ReadableBufferReader(buffer); Assert.Equal(1, reader.Take()); Assert.Equal(2, reader.Take()); Assert.Equal(3, reader.Take()); Assert.Equal(-1, reader.Take()); }
public void PeekWorkesWithEmptySegments() { var buffer = BufferUtilities.CreateBuffer(new[] { new byte[] { }, new byte[] { 1 } }); var reader = new ReadableBufferReader(buffer); Assert.Equal(1, reader.Peek()); Assert.Equal(1, reader.Take()); Assert.Equal(-1, reader.Peek()); Assert.Equal(-1, reader.Take()); }
public void TakeReturnsByteAndMoves() { var reader = new ReadableBufferReader(Factory.CreateWithContent(new byte[] { 1, 2 })); Assert.Equal(0, reader.Index); Assert.Equal(1, reader.Span[reader.Index]); Assert.Equal(1, reader.Take()); Assert.Equal(1, reader.Index); Assert.Equal(2, reader.Span[reader.Index]); Assert.Equal(2, reader.Take()); Assert.Equal(-1, reader.Take()); }
public void PeekWorkesWithEmptySegments() { var buffer = Factory.CreateWithContent(new byte[] { 1 }); var reader = new ReadableBufferReader(buffer); Assert.Equal(0, reader.Index); Assert.Equal(1, reader.Span.Length); Assert.Equal(1, reader.Peek()); Assert.Equal(1, reader.Take()); Assert.Equal(-1, reader.Peek()); Assert.Equal(-1, reader.Take()); }
public void PeekTraversesSegments() { var buffer = Factory.CreateWithContent(new byte[] { 1, 2 }); var reader = new ReadableBufferReader(buffer); Assert.Equal(1, reader.Span[reader.Index]); Assert.Equal(1, reader.Take()); Assert.Equal(2, reader.Span[reader.Index]); Assert.Equal(2, reader.Peek()); Assert.Equal(2, reader.Take()); Assert.Equal(-1, reader.Peek()); Assert.Equal(-1, reader.Take()); }
public void WorkesWithEmptyBuffer() { var reader = new ReadableBufferReader(ReadableBuffer.Create(new byte[] { 0 }, 0, 0)); Assert.Equal(-1, reader.Peek()); Assert.Equal(-1, reader.Take()); }
public void PeekTraversesSegments() { var buffer = BufferUtilities.CreateBuffer(new[] { new byte[] { 1 }, new byte[] { 2 } }); var reader = new ReadableBufferReader(buffer); Assert.Equal(0, reader.Index); Assert.Equal(1, reader.Span.Length); Assert.Equal(1, reader.Span[0]); Assert.Equal(1, reader.Take()); Assert.Equal(0, reader.Index); Assert.Equal(1, reader.Span.Length); Assert.Equal(2, reader.Span[0]); Assert.Equal(2, reader.Peek()); Assert.Equal(2, reader.Take()); Assert.Equal(-1, reader.Peek()); Assert.Equal(-1, reader.Take()); }
public void WorkesWithEmptyBuffer() { var reader = new ReadableBufferReader(Factory.CreateWithContent(new byte[] { })); Assert.Equal(0, reader.Index); Assert.Equal(0, reader.Span.Length); Assert.Equal(-1, reader.Peek()); Assert.Equal(-1, reader.Take()); }
public void SkipTraversesSegments() { var buffer = Factory.CreateWithContent(new byte[] { 1, 2, 3 }); var reader = new ReadableBufferReader(buffer); reader.Skip(2); Assert.Equal(3, reader.Span[reader.Index]); Assert.Equal(3, reader.Take()); }
public void SkipTraversesSegments() { var buffer = BufferUtilities.CreateBuffer(new[] { new byte[] { 1 }, new byte[] { 2 }, new byte[] { 3 } }); var reader = new ReadableBufferReader(buffer); reader.Skip(2); Assert.Equal(0, reader.Index); Assert.Equal(3, reader.Span[reader.Index]); Assert.Equal(3, reader.Take()); }
public async Task PeekTraversesSegments() { using (var factory = new PipelineFactory()) { var readerWriter = factory.Create(); var w = readerWriter.Alloc(); w.Append(ReadableBuffer.Create(new byte[] { 1 }, 0, 1)); w.Append(ReadableBuffer.Create(new byte[] { 2 }, 0, 1)); await w.FlushAsync(); var result = await readerWriter.ReadAsync(); var buffer = result.Buffer; var reader = new ReadableBufferReader(buffer); Assert.Equal(1, reader.Take()); Assert.Equal(2, reader.Peek()); Assert.Equal(2, reader.Take()); Assert.Equal(-1, reader.Peek()); Assert.Equal(-1, reader.Take()); } }
public async Task PeekWorkesWithEmptySegments() { using (var channelFactory = new ChannelFactory()) { var channel = channelFactory.CreateChannel(); var w = channel.Alloc(); w.Append(ReadableBuffer.Create(new byte[] { 0 }, 0, 0)); w.Append(ReadableBuffer.Create(new byte[] { 1 }, 0, 1)); await w.FlushAsync(); var result = await channel.ReadAsync(); var buffer = result.Buffer; var reader = new ReadableBufferReader(buffer); Assert.Equal(1, reader.Peek()); Assert.Equal(1, reader.Take()); Assert.Equal(-1, reader.Peek()); Assert.Equal(-1, reader.Take()); } }
public async Task TakeTraversesSegments() { using (var channelFactory = new ChannelFactory()) { var channel = channelFactory.CreateChannel(); var w = channel.Alloc(); w.Append(ReadableBuffer.Create(new byte[] { 1 }, 0, 1)); w.Append(ReadableBuffer.Create(new byte[] { 2 }, 0, 1)); w.Append(ReadableBuffer.Create(new byte[] { 3 }, 0, 1)); await w.FlushAsync(); var result = await channel.ReadAsync(); var buffer = result.Buffer; var reader = new ReadableBufferReader(buffer); Assert.Equal(1, reader.Take()); Assert.Equal(2, reader.Take()); Assert.Equal(3, reader.Take()); Assert.Equal(-1, reader.Take()); } }
public async Task PeekTraversesSegments() { using (var factory = new PipeFactory()) { var readerWriter = factory.Create(); var w = readerWriter.Writer.Alloc(); w.Append(ReadableBuffer.Create(new byte[] { 1 }, 0, 1)); w.Append(ReadableBuffer.Create(new byte[] { 2 }, 0, 1)); await w.FlushAsync(); var result = await readerWriter.Reader.ReadAsync(); var buffer = result.Buffer; var reader = new ReadableBufferReader(buffer); Assert.Equal(1, reader.Take()); Assert.Equal(2, reader.Peek()); Assert.Equal(2, reader.Take()); Assert.Equal(-1, reader.Peek()); Assert.Equal(-1, reader.Take()); } }
public void ReturnsCorrectCursor(int takes, bool end) { var readableBuffer = Factory.CreateWithContent(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); var reader = new ReadableBufferReader(readableBuffer); for (int i = 0; i < takes; i++) { reader.Take(); } var expected = end ? new byte[] {} : readableBuffer.Slice(takes).ToArray(); Assert.Equal(expected, readableBuffer.Slice(reader.Cursor).ToArray()); }
public void ReturnsCorrectCursor(int takes, int slice) { var readableBuffer = ReadableBuffer.Create(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, 0, 10); var reader = new ReadableBufferReader(readableBuffer); for (int i = 0; i < takes; i++) { reader.Take(); } var expected = slice == int.MaxValue ? readableBuffer.End : readableBuffer.Slice(slice).Start; Assert.Equal(expected, reader.Cursor); }
public unsafe bool ParseHeaders <T>(T handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes) where T : IHttpHeadersHandler { consumed = buffer.Start; examined = buffer.End; consumedBytes = 0; var bufferEnd = buffer.End; var reader = new ReadableBufferReader(buffer); var start = default(ReadableBufferReader); var done = false; try { while (!reader.End) { var span = reader.Span; var remaining = span.Length - reader.Index; fixed(byte *pBuffer = &span.DangerousGetPinnableReference()) { while (remaining > 0) { var index = reader.Index; int ch1; int ch2; // Fast path, we're still looking at the same span if (remaining >= 2) { ch1 = pBuffer[index]; ch2 = pBuffer[index + 1]; } else { // Store the reader before we look ahead 2 bytes (probably straddling // spans) start = reader; // Possibly split across spans ch1 = reader.Take(); ch2 = reader.Take(); } if (ch1 == ByteCR) { // Check for final CRLF. if (ch2 == -1) { // Reset the reader so we don't consume anything reader = start; return(false); } else if (ch2 == ByteLF) { // If we got 2 bytes from the span directly so skip ahead 2 so that // the reader's state matches what we expect if (index == reader.Index) { reader.Skip(2); } done = true; return(true); } // Headers don't end in CRLF line. RejectRequest(RequestRejectionReason.InvalidRequestHeadersNoCRLF); } // We moved the reader so look ahead 2 bytes so reset both the reader // and the index if (index != reader.Index) { reader = start; index = reader.Index; } var endIndex = new ReadOnlySpan <byte>(pBuffer + index, remaining).IndexOf(ByteLF); var length = 0; if (endIndex != -1) { length = endIndex + 1; var pHeader = pBuffer + index; TakeSingleHeader(pHeader, length, handler); } else { var current = reader.Cursor; // Split buffers if (ReadCursorOperations.Seek(current, bufferEnd, out var lineEnd, ByteLF) == -1) { // Not there return(false); } // Make sure LF is included in lineEnd lineEnd = buffer.Move(lineEnd, 1); var headerSpan = buffer.Slice(current, lineEnd).ToSpan(); length = headerSpan.Length; fixed(byte *pHeader = &headerSpan.DangerousGetPinnableReference()) { TakeSingleHeader(pHeader, length, handler); } // We're going to the next span after this since we know we crossed spans here // so mark the remaining as equal to the headerSpan so that we end up at 0 // on the next iteration remaining = length; } // Skip the reader forward past the header line reader.Skip(length); remaining -= length; } } } return(false); } finally { consumed = reader.Cursor; consumedBytes = reader.ConsumedBytes; if (done) { examined = consumed; } } }