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);
        }
Example #4
0
        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());
        }
Example #5
0
        public void CursorIsCorrectAtEnd()
        {
            var reader = new ReadableBufferReader(Factory.CreateWithContent(new byte[] { 1, 2 }));

            reader.Take();
            reader.Take();
            Assert.True(reader.End);
        }
Example #6
0
        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());
        }
Example #7
0
        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 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);
        }
Example #9
0
            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);
            }
Example #10
0
        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());
        }
Example #12
0
        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());
        }
Example #13
0
            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());
            }
Example #14
0
        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());
        }
Example #15
0
        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());
        }
Example #16
0
        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());
        }
Example #18
0
        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());
        }
Example #19
0
        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());
            }
        }
Example #22
0
        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());
            }
        }
Example #23
0
        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());
            }
        }
Example #24
0
        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());
            }
        }
Example #25
0
        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);
        }
Example #27
0
        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;
                }
            }
        }
        public void WorkesWithEmptyBuffer()
        {
            var reader = new ReadableBufferReader(ReadableBuffer.Create(new byte[] { 0 }, 0, 0));

            Assert.Equal(-1, reader.Peek());
            Assert.Equal(-1, reader.Take());
        }