Ejemplo n.º 1
0
    static bool FullRequestRb()
    {
        ReadableBuffer buffer        = ReadableBuffer.Create(s_plaintextTechEmpowerRequestBytes);
        var            parser        = new HttpParser();
        var            request       = new Request();
        int            consumedBytes = 0;
        ReadCursor     examined;
        ReadCursor     consumed = buffer.Start;
        bool           success  = true;

        foreach (var iteration in Benchmark.Iterations)
        {
            using (iteration.StartMeasurement()) {
                for (int i = 0; i < Benchmark.InnerIterationCount; i++)
                {
                    success = success && parser.ParseRequestLine(request, buffer, out consumed, out examined);
                    success = success && parser.ParseHeaders(request, buffer.Slice(consumed), out consumed, out examined, out consumedBytes);

                    success = success && parser.ParseRequestLine(request, buffer, out consumed, out examined);
                    success = success && parser.ParseHeaders(request, buffer.Slice(consumed), out consumed, out examined, out consumedBytes);

                    success = success && parser.ParseRequestLine(request, buffer, out consumed, out examined);
                    success = success && parser.ParseHeaders(request, buffer.Slice(consumed), out consumed, out examined, out consumedBytes);

                    success = success && parser.ParseRequestLine(request, buffer, out consumed, out examined);
                    success = success && parser.ParseHeaders(request, buffer.Slice(consumed), out consumed, out examined, out consumedBytes);

                    success = success && parser.ParseRequestLine(request, buffer, out consumed, out examined);
                    success = success && parser.ParseHeaders(request, buffer.Slice(consumed), out consumed, out examined, out consumedBytes);
                }
            }
        }

        return(success);
    }
Ejemplo n.º 2
0
    static bool FullRequestRob()
    {
        var  buffer        = new ReadOnlyBytes(s_plaintextTechEmpowerRequestBytes);
        var  parser        = new HttpParser();
        var  request       = new RequestStruct();
        int  consumedBytes = 0;
        bool success       = true;

        foreach (var iteration in Benchmark.Iterations)
        {
            using (iteration.StartMeasurement()) {
                for (int i = 0; i < Benchmark.InnerIterationCount; i++)
                {
                    success = success && parser.ParseRequestLine(ref request, buffer, out consumedBytes);
                    success = success && parser.ParseHeaders(ref request, buffer.Slice(consumedBytes), out consumedBytes);
                    success = success && parser.ParseRequestLine(ref request, buffer, out consumedBytes);
                    success = success && parser.ParseHeaders(ref request, buffer.Slice(consumedBytes), out consumedBytes);
                    success = success && parser.ParseRequestLine(ref request, buffer, out consumedBytes);
                    success = success && parser.ParseHeaders(ref request, buffer.Slice(consumedBytes), out consumedBytes);
                    success = success && parser.ParseRequestLine(ref request, buffer, out consumedBytes);
                    success = success && parser.ParseHeaders(ref request, buffer.Slice(consumedBytes), out consumedBytes);
                    success = success && parser.ParseRequestLine(ref request, buffer, out consumedBytes);
                    success = success && parser.ParseHeaders(ref request, buffer.Slice(consumedBytes), out consumedBytes);
                }
            }
        }

        return(success);
    }
Ejemplo n.º 3
0
    static bool HeadersRobCursors()
    {
        var      buffer   = new ReadOnlyBytes(s_plaintextTechEmpowerHeadersBytes);
        var      parser   = new HttpParser();
        var      request  = new Request();
        Position consumed = default;
        Position examined;
        int      consumedBytes;
        bool     success = true;

        foreach (var iteration in Benchmark.Iterations)
        {
            using (iteration.StartMeasurement())
            {
                for (int i = 0; i < Benchmark.InnerIterationCount; i++)
                {
                    success = success && parser.ParseHeaders(ref request, buffer, out consumed, out examined, out consumedBytes);
                    success = success && parser.ParseHeaders(ref request, buffer, out consumed, out examined, out consumedBytes);
                    success = success && parser.ParseHeaders(ref request, buffer, out consumed, out examined, out consumedBytes);
                    success = success && parser.ParseHeaders(ref request, buffer, out consumed, out examined, out consumedBytes);
                    success = success && parser.ParseHeaders(ref request, buffer, out consumed, out examined, out consumedBytes);
                    success = success && parser.ParseHeaders(ref request, buffer, out consumed, out examined, out consumedBytes);
                    success = success && parser.ParseHeaders(ref request, buffer, out consumed, out examined, out consumedBytes);
                    success = success && parser.ParseHeaders(ref request, buffer, out consumed, out examined, out consumedBytes);
                    success = success && parser.ParseHeaders(ref request, buffer, out consumed, out examined, out consumedBytes);
                    success = success && parser.ParseHeaders(ref request, buffer, out consumed, out examined, out consumedBytes);
                }
            }
        }

        return(success);
    }
Ejemplo n.º 4
0
        public static HttpRequestMessage Run(string requestString)
        {
            if (string.IsNullOrWhiteSpace(requestString))
            {
                throw new ArgumentNullException(nameof(requestString));
            }

            byte[] requestRaw = Encoding.UTF8.GetBytes(requestString);
            ReadOnlySequence <byte>    buffer = new ReadOnlySequence <byte>(requestRaw);
            HttpParser <RawHttpParser> parser = new HttpParser <RawHttpParser>();
            RawHttpParser app = new RawHttpParser();

            parser.ParseRequestLine(app, buffer, out var consumed, out var examined);
            buffer = buffer.Slice(consumed);
            parser.ParseHeaders(app, buffer, out consumed, out examined, out var b);
            buffer = buffer.Slice(consumed);
            string body    = Encoding.UTF8.GetString(buffer.ToArray());
            var    message = app.Get();

            if (string.IsNullOrWhiteSpace(body) == false)
            {
                message.Content = new StringContent(body, Encoding.UTF8);
            }

            foreach (var pair in app.ContentHeaders)
            {
                if (message.Content.Headers.Contains(pair.Key))
                {
                    message.Content.Headers.Remove(pair.Key);
                }
                message.Content.Headers.Add(pair.Key, pair.Value);
            }

            return(message);
        }
Ejemplo n.º 5
0
        public void TechEmpowerRob()
        {
            var parser  = new HttpParser();
            var request = new Request();
            ReadOnlySequence <byte> buffer = new ReadOnlySequence <byte>(_plaintextTechEmpowerRequestBytes);

            Assert.True(parser.ParseRequestLine(ref request, buffer, out var consumed));
            Assert.Equal(25, consumed);

            Assert.True(parser.ParseHeaders(ref request, buffer.Slice(consumed), out consumed));
            Assert.Equal(139, consumed);

            // request line
            Assert.Equal(Http.Method.Get, request.Method);
            Assert.Equal(Http.Version.Http11, request.Version);
            Assert.Equal("/plaintext", request.Path);

            // headers
            Assert.Equal(3, request.Headers.Count);
            Assert.True(request.Headers.ContainsKey("Host"));
            Assert.True(request.Headers.ContainsKey("Accept"));
            Assert.True(request.Headers.ContainsKey("Connection"));
            Assert.Equal("localhost", request.Headers["Host"]);
            Assert.Equal("text/plain,text/html;q=0.9,application/xhtml+xml;q=0.9,application/xml;q=0.8,*/*;q=0.7", request.Headers["Accept"]);
            Assert.Equal("keep-alive", request.Headers["Connection"]);
        }
Ejemplo n.º 6
0
        public static HttpHandler ParseHttpRequest(string request)
        {
            Validator.RequireNotNull(request);

            //Hack to change linux newlines into windows newlines
            request = request.Replace("\n", Environment.NewLine, false, CultureInfo.InvariantCulture);

            //Add a newline at the bottom too
            request += Environment.NewLine;

            HttpHandler handler = new HttpHandler();

            ReadOnlySequence <byte>  buffer = new ReadOnlySequence <byte>(Encoding.UTF8.GetBytes(request));
            HttpParser <HttpHandler> parser = new HttpParser <HttpHandler>();

            parser.ParseRequestLine(handler, buffer, out SequencePosition consumed, out _);
            buffer = buffer.Slice(consumed);

            parser.ParseHeaders(handler, buffer, out consumed, out _, out _);
            buffer = buffer.Slice(consumed);

            handler.Body = buffer.ToArray();

            return(handler);
        }
Ejemplo n.º 7
0
        protected virtual void ProcessRequest(TcpConnection socket)
        {
            Log.LogVerbose("Processing Request");

            using (BufferSequence rootBuffer = new BufferSequence(RequestBufferSize)) {
                BufferSequence requestBuffer = rootBuffer;
                int            totalWritten  = 0;
                while (true)
                {
                    Span <byte> requestSpan = requestBuffer.Free;

                    int requestBytesRead = socket.Receive(requestSpan);
                    if (requestBytesRead == 0)
                    {
                        socket.Close();
                        return;
                    }

                    requestBuffer.Advance(requestBytesRead);
                    totalWritten += requestBytesRead;
                    if (requestBytesRead == requestSpan.Length)
                    {
                        requestBuffer = requestBuffer.Append(RequestBufferSize);
                    }
                    else
                    {
                        break;
                    }
                }

                var requestBytes = new ReadOnlyBuffer <byte>(rootBuffer, 0, requestBuffer, requestBuffer.Memory.Length);

                var request = new HttpRequest();
                if (!s_parser.ParseRequestLine(ref request, requestBytes, out int consumed))
                {
                    throw new Exception();
                }
                requestBytes = requestBytes.Slice(consumed);
                if (!s_parser.ParseHeaders(ref request, requestBytes, out consumed))
                {
                    throw new Exception();
                }

                var requestBody = requestBytes.Slice(consumed);

                Log.LogRequest(request, requestBody);

                using (var response = new TcpConnectionFormatter(socket, ResponseBufferSize)) {
                    WriteResponse(ref request, requestBody, response);
                }

                socket.Close();
            }

            if (Log.IsVerbose)
            {
                Log.LogMessage(Log.Level.Verbose, "Request Processed and Response Sent", DateTime.UtcNow.Ticks);
            }
        }
Ejemplo n.º 8
0
        public void ParseHeadersConsumesBytesCorrectlyAtEnd()
        {
            var parser = new HttpParser();

            const string headerLine     = "Header: value\r\n\r";
            var          buffer         = new ReadOnlySequence <byte>(Encoding.ASCII.GetBytes(headerLine));
            var          requestHandler = new RequestHandler();

            Assert.False(parser.ParseHeaders(requestHandler, buffer, out var consumed));

            Assert.Equal(headerLine.Length - 1, consumed);

            var buffer2 = new ReadOnlySequence <byte>(Encoding.ASCII.GetBytes("\r\n"));

            Assert.True(parser.ParseHeaders(requestHandler, buffer2, out consumed));

            Assert.Equal(2, consumed);
        }
Ejemplo n.º 9
0
        public void ParseHeadersReturnsFalseWhenGivenIncompleteHeaders(string rawHeaders)
        {
            var parser = new HttpParser();

            var buffer         = new ReadOnlySequence <byte>(Encoding.ASCII.GetBytes(rawHeaders));
            var requestHandler = new RequestHandler();

            Assert.False(parser.ParseHeaders(requestHandler, buffer, out var consumed));
        }
    public static void Main()
    {
        const string newLine = "\r\n";

        string requestString =
            "POST /resource/?query_id=0 HTTP/1.1" + newLine +
            "Host: localhost" + newLine +
            "User-Agent: custom" + newLine +
            "Accept: */*" + newLine +
            "Connection: close" + newLine +
            "Content-Length: 20" + newLine +
            "Content-Type: application/json" + newLine +

            "key1=value&key2=value2&key3=value3";

        byte[] requestRaw = Encoding.UTF8.GetBytes(requestString);
        ReadOnlySequence <byte> buffer = new ReadOnlySequence <byte>(requestRaw);

        HttpParser <Program> parser = new HttpParser <Program>();
        Program app = new Program();

        Console.WriteLine("Start line:");

        parser.ParseRequestLine(app, buffer, out var consumed, out var examined);
        buffer = buffer.Slice(consumed);

        Console.WriteLine("\r\nHeaders:");

        parser.ParseHeaders(app, buffer, out consumed, out examined, out var b);
        buffer = buffer.Slice(consumed);

        Console.WriteLine("\r\nBody:");

        string body = Encoding.UTF8.GetString(buffer.ToArray());

        string[] kvpArray = body.Split('&').ToArray();

        Dictionary <string, string> bodyKvps = new Dictionary <string, string>();

        #region Deserialize JSON body
        //Dictionary<string, int> bodyObject = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, int>>(body);
        #endregion

        foreach (var item in kvpArray)
        {
            string[] kvp   = item.Split('=').ToArray();
            string   key   = kvp[0];
            string   value = kvp[1];
            bodyKvps[key] = value;
            Console.WriteLine($"key: {key}, value: {value}");
        }

        Console.ReadKey();
    }
Ejemplo n.º 11
0
        public void ParseHeadersDoesNotConsumeIncompleteHeader(string rawHeaders)
        {
            var parser = new HttpParser();

            var buffer         = new ReadOnlySequence <byte>(Encoding.ASCII.GetBytes(rawHeaders));
            var requestHandler = new RequestHandler();

            parser.ParseHeaders(requestHandler, buffer, out var consumed);

            Assert.Equal(0, consumed);
        }
Ejemplo n.º 12
0
        public void ParseHeadersThrowsOnInvalidRequestHeadersRb(string rawHeaders, string expectedExceptionMessage)
        {
            var parser         = new HttpParser();
            var buffer         = new ReadOnlyBuffer <byte>(Encoding.ASCII.GetBytes(rawHeaders));
            var requestHandler = new RequestHandler();

            var exception = Assert.Throws <BadHttpRequestException>(() =>
                                                                    parser.ParseHeaders(requestHandler, buffer, out var consumed, out var examined, out var consumedBytes));

            //Assert.Equal(expectedExceptionMessage, exception.Message);
            //Assert.Equal(StatusCodes.Status400BadRequest, exception.StatusCode);
        }
    public Dictionary <string, string> Parse(string requestString)
    {
        result = new Dictionary <string, string>();

        byte[] requestRaw = Encoding.UTF8.GetBytes(requestString);
        ReadOnlySequence <byte> buffer = new ReadOnlySequence <byte>(requestRaw);
        HttpParser <Program>    parser = new HttpParser <Program>();

        parser.ParseRequestLine(this, buffer, out var consumed, out var examined);
        buffer = buffer.Slice(consumed);

        parser.ParseHeaders(this, buffer, out consumed, out examined, out var b);
        buffer = buffer.Slice(consumed);
    }
Ejemplo n.º 14
0
        private void VerifyRawHeaders(string rawHeaders, IEnumerable <string> expectedHeaderNames, IEnumerable <string> expectedHeaderValues)
        {
            Assert.True(expectedHeaderNames.Count() == expectedHeaderValues.Count(), $"{nameof(expectedHeaderNames)} and {nameof(expectedHeaderValues)} sizes must match");

            var parser = new HttpParser();
            var buffer = new ReadOnlyBuffer <byte>(Encoding.ASCII.GetBytes(rawHeaders));

            var requestHandler = new RequestHandler();

            parser.ParseHeaders(requestHandler, buffer, out var consumed, out var examined, out var consumedBytes);

            var parsedHeaders = requestHandler.Headers.ToArray();

            Assert.Equal(expectedHeaderNames.Count(), parsedHeaders.Length);
            Assert.Equal(expectedHeaderNames, parsedHeaders.Select(t => t.Key));
            Assert.Equal(expectedHeaderValues, parsedHeaders.Select(t => t.Value));
            Assert.True(buffer.Slice(consumed).IsEmpty);
            Assert.True(buffer.Slice(examined).IsEmpty);
        }
Ejemplo n.º 15
0
        public async Task CanReadAndWriteFromSocketFeatureInConnectionMiddleware()
        {
            var builder = TransportSelector.GetHostBuilder()
                          .ConfigureWebHost(webHostBuilder =>
            {
                webHostBuilder
                .UseKestrel(options =>
                {
                    options.ListenAnyIP(0, lo =>
                    {
                        lo.Use(next =>
                        {
                            return(async connection =>
                            {
                                var socket = connection.Features.Get <IConnectionSocketFeature>().Socket;
                                Assert.NotNull(socket);

                                var buffer = new byte[4096];

                                var read = await socket.ReceiveAsync(buffer, SocketFlags.None);

                                static void ParseHttp(ReadOnlySequence <byte> data)
                                {
                                    var parser = new HttpParser <ParserHandler>();
                                    var handler = new ParserHandler();

                                    var reader = new SequenceReader <byte>(data);

                                    // Assume we can parse the HTTP request in a single buffer
                                    Assert.True(parser.ParseRequestLine(handler, ref reader));
                                    Assert.True(parser.ParseHeaders(handler, ref reader));

                                    Assert.Equal(KestrelHttpMethod.Get, handler.HttpMethod);
                                    Assert.Equal(KestrelHttpVersion.Http11, handler.HttpVersion);
                                }

                                ParseHttp(new ReadOnlySequence <byte>(buffer[0..read]));

                                await socket.SendAsync(Encoding.UTF8.GetBytes("HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n"), SocketFlags.None);
                            });
                        });
                    });
Ejemplo n.º 16
0
        //[Fact]
        //public void ExceptionDetailNotIncludedWhenLogLevelInformationNotEnabled()
        //{
        //    var mockTrace = new HttpParser();
        //    mockTrace
        //        .Setup(trace => trace.IsEnabled(LogLevel.Information))
        //        .Returns(false);

        //    var parser = new HttpParser();

        //    // Invalid request line
        //    var buffer = ReadableBuffer.Create(Encoding.ASCII.GetBytes("GET % HTTP/1.1\r\n"));
        //    var requestHandler = new RequestHandler();

        //    var exception = Assert.Throws<BadHttpRequestException>(() =>
        //        parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined));

        //    Assert.Equal("Invalid request line: ''", exception.Message);
        //    Assert.Equal(StatusCodes.Status400BadRequest, (exception as BadHttpRequestException).StatusCode);

        //    // Unrecognized HTTP version
        //    buffer = ReadableBuffer.Create(Encoding.ASCII.GetBytes("GET / HTTP/1.2\r\n"));

        //    exception = Assert.Throws<BadHttpRequestException>(() =>
        //        parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined));

        //    Assert.Equal("Unrecognized HTTP version: ''", exception.Message);
        //    Assert.Equal(StatusCodes.Status505HttpVersionNotsupported, (exception as BadHttpRequestException).StatusCode);

        //    // Invalid request header
        //    buffer = ReadableBuffer.Create(Encoding.ASCII.GetBytes("Header: value\n\r\n"));

        //    exception = Assert.Throws<BadHttpRequestException>(() =>
        //        parser.ParseHeaders(requestHandler, buffer, out var consumed, out var examined, out var consumedBytes));

        //    Assert.Equal("Invalid request header: ''", exception.Message);
        //    Assert.Equal(StatusCodes.Status400BadRequest, exception.StatusCode);
        //}

        private void VerifyHeader(
            string headerName,
            string rawHeaderValue,
            string expectedHeaderValue)
        {
            var parser = new HttpParser();
            var buffer = new ReadOnlyBuffer <byte>(Encoding.ASCII.GetBytes($"{headerName}:{rawHeaderValue}\r\n"));

            var requestHandler = new RequestHandler();

            parser.ParseHeaders(requestHandler, buffer, out var consumed, out var examined, out var consumedBytes);

            var pairs = requestHandler.Headers.ToArray();

            Assert.Equal(1, pairs.Length);
            Assert.Equal(headerName, pairs[0].Key);
            Assert.Equal(expectedHeaderValue, pairs[0].Value);
            Assert.True(buffer.Slice(consumed).IsEmpty);
            Assert.True(buffer.Slice(examined).IsEmpty);
        }
Ejemplo n.º 17
0
        public void HttpParserSegmentedRob(string requestText)
        {
            var parser = new HttpParser();

            for (int pivot = 26; pivot < requestText.Length; pivot++)
            {
                var front = requestText.Substring(0, pivot);
                var back  = requestText.Substring(pivot);

                var frontBytes = Encoding.ASCII.GetBytes(front);
                var endBytes   = Encoding.ASCII.GetBytes(back);

                var(first, last) = BufferList.Create(frontBytes, endBytes);
                var buffer = new ReadOnlySequence <byte>(first, 0, last, last.Memory.Length);

                var request = new Request();

                try {
                    Assert.True(parser.ParseRequestLine(ref request, buffer, out var consumed));
                    Assert.Equal(25, consumed);

                    var unconsumed = buffer.Slice(consumed);
                    Assert.True(parser.ParseHeaders(ref request, unconsumed, out consumed));
                    Assert.Equal(8, consumed);
                }
                catch {
                    throw;
                }

                // request line
                Assert.Equal(Http.Method.Get, request.Method);
                Assert.Equal(Http.Version.Http11, request.Version);
                Assert.Equal("/plaintext", request.Path);

                // headers
                Assert.Equal(1, request.Headers.Count);
                Assert.True(request.Headers.ContainsKey("N"));
                Assert.Equal("V", request.Headers["N"]);
            }
        }
            private void ParseHttpRequest(ReadableBuffer inputBuffer, out ReadCursor consumed, out ReadCursor examined)
            {
                consumed = inputBuffer.Start;
                examined = inputBuffer.End;

                if (_state == State.StartLine)
                {
                    if (_parser.ParseRequestLine(this, inputBuffer, out consumed, out examined))
                    {
                        _state      = State.Headers;
                        inputBuffer = inputBuffer.Slice(consumed);
                    }
                }

                if (_state == State.Headers)
                {
                    if (_parser.ParseHeaders(this, inputBuffer, out consumed, out examined, out int consumedBytes))
                    {
                        _state = State.Body;
                    }
                }
            }
Ejemplo n.º 19
0
            private void ParseHttpRequest(HttpParser <HttpConnectionContext <THandlerInner> > parser, ReadableBuffer inputBuffer, out ReadCursor consumed, out ReadCursor examined)
            {
                consumed = inputBuffer.Start;
                examined = inputBuffer.End;

                if (_state == State.StartLine)
                {
                    if (parser.ParseRequestLine(this, inputBuffer, out consumed, out examined))
                    {
                        _state      = State.Headers;
                        inputBuffer = inputBuffer.Slice(consumed);
                    }
                }

                if (_state == State.Headers)
                {
                    if (parser.ParseHeaders(this, inputBuffer, out consumed, out examined, out int consumedBytes))
                    {
                        _state = State.Body;
                    }
                }
            }
Ejemplo n.º 20
0
        public void HttpParserBasicsRob(string requestText)
        {
            var parser  = new HttpParser();
            var request = new Request();
            ReadOnlySequence <byte> buffer = new ReadOnlySequence <byte>(Encoding.ASCII.GetBytes(requestText));

            Assert.True(parser.ParseRequestLine(ref request, buffer, out var consumed));
            Assert.Equal(25, consumed);

            Assert.True(parser.ParseHeaders(ref request, buffer.Slice(consumed), out consumed));
            Assert.Equal(8, consumed);

            // request line
            Assert.Equal(Http.Method.Get, request.Method);
            Assert.Equal(Http.Version.Http11, request.Version);
            Assert.Equal("/plaintext", request.Path);

            // headers
            Assert.Equal(1, request.Headers.Count);
            Assert.True(request.Headers.ContainsKey("N"));
            Assert.Equal("V", request.Headers["N"]);
        }