public HttpServerSocketDelegate(IHttpServerTransaction transaction, IHttpServerTransactionDelegate transactionDelegate)
 {
     this.transaction = transaction;
     this.transactionDelegate = transactionDelegate;
     transactionTransform = new ParserToTransactionTransform(transaction, transactionDelegate);
     parser = new HttpParser(new ParserDelegate(transactionTransform));
 }
Beispiel #2
0
 public void OnBody(HttpParser parser, ArraySegment<byte> data)
 {
     if (_headersComplete && data != null && data.Count > 0 && _onRequestBodyReceivedHandler != null)
     {
         _request.ReceivedLength += data.Count;
         _onRequestBodyReceivedHandler(data);
     }
 }
Beispiel #3
0
 public void OnHeaderValue(HttpParser parser, string value)
 {
     string existingValue = _request.Headers[_headerName];
     if (string.IsNullOrWhiteSpace(existingValue))
         _request.Headers[_headerName] = value;
     else
         _request.Headers[_headerName] = existingValue + "," + value;
 }
Beispiel #4
0
 public void OnBody(HttpParser parser, ArraySegment<byte> data)
 {
     Debug.WriteLine("OnBody");
     // XXX can we defer this check to the parser?
     if (data.Count > 0)
     {
         del.OnRequestBody(data);
     }
 }
Beispiel #5
0
 public HttpRequestParser(Action<HttpRequest> onRequestBeginHandler, Action<ArraySegment<byte>> onRequestBodyReceivedHandler, Action onRequestEndHandler, Action<string> onFragmentReceivedHandler, Action<Exception> onParserException, bool secure)
 {
     _parser = new HttpParser(this);
     _secure = secure;
     _onRequestBeginHandler = onRequestBeginHandler;
     _onRequestBodyReceivedHandler = onRequestBodyReceivedHandler;
     _onRequestEndHandler = onRequestEndHandler;
     _onParserException = onParserException;
 }
Beispiel #6
0
 public void OnQueryString(HttpParser parser, string queryString)
 {
     var kv = HttpUtility.ParseQueryString(queryString);
     
     foreach(var k in kv.AllKeys)
     {
         Console.WriteLine("{0}:{1}", k, kv[k]);
         data[k] = kv[k];
     }
 }
Beispiel #7
0
        public void OnHeaderName(HttpParser parser, string name)
        {
            if (headers == null)
                headers = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);

            if (!string.IsNullOrEmpty(headerValue))
                CommitHeader();

            headerName = name;
        }
        public async Task OnMessageBegin(HttpParser parser)
        {
            //Console.WriteLine("OnMessageBegin");
            
            // TODO: this used to work, but i removed the StringBuffers. so work around maybe
            // defer creation of buffers until message is created so 
            // NullRef will be thrown if OnMessageBegin is not called.

            headers = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
            body = new List<ArraySegment<byte>>();
        }
        public async Task<MiddlemanRequest> ParseAsync(InboundConnection conn, Stream stream)
        {
            var del = new ParseDelegate();
            var parser = new HttpParser(del);

            int read;
            var readTotal = 0;
            var buffer = new byte[8192];

            Log.Debug("{0}: RequestParser starting", conn.RemoteEndPoint);

            var requestString = "";

            while (stream != null && (read = await stream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false)) > 0)
            {
                requestString += Encoding.ASCII.GetString(buffer.Where(x => x != 0).ToArray(), 0, read);
                readTotal += read;

                if (parser.Execute(new ArraySegment<byte>(buffer, 0, read)) != read)
                    throw new FormatException("Parse error in request");

                if (del.HeaderComplete)
                    break;
            }

            conn.MustClose = del.Request.Headers.AllKeys.Any(h => h.Equals("Connection", StringComparison.InvariantCultureIgnoreCase) && del.Request.Headers[h].Equals("Close", StringComparison.InvariantCultureIgnoreCase));

            Log.Debug("{0}: RequestParser read enough ({1} bytes)", conn.RemoteEndPoint, readTotal);
            Log.Info("ORIGINAL REQUEST: " + Environment.NewLine + requestString + Environment.NewLine);

            if (readTotal == 0)
                return null;

            if (!del.HeaderComplete)
                throw new FormatException("Parse error in request");

            var request = del.Request;

            request.ProtocolVersion = new Version(parser.MajorVersion, parser.MinorVersion);
            conn.RequestVersion = request.ProtocolVersion;

            var cl = request.ContentLength;

            if (cl > 0 && stream != null)
            {
                request.RequestBody = del.RequestBodyStart.Count > 0
                    ? new MaxReadStream(new StartAvailableStream(del.RequestBodyStart, stream), cl)
                    : new MaxReadStream(stream, cl);
            }

            return request;
        }
Beispiel #10
0
        public void OnHeadersEnd(HttpParser parser)
        {
            string upgradeType;

            _headersComplete = true;
            _request.Version = new Version(parser.MajorVersion, parser.MinorVersion);
            _request.KeepAlive = parser.ShouldKeepAlive;
            _request.Upgrade = _request.Headers.TryGetValue("upgrade", out upgradeType);
            _request.UpgradeType = upgradeType;
            _request.Secure = _secure;

            if (_onRequestBeginHandler != null)
                _onRequestBeginHandler(_request);
        }
        public async Task<SwitchboardRequest> ParseAsync(InboundConnection conn, Stream stream)
        {
            var del = new ParseDelegate();
            var parser = new HttpParser(del);

            int read;
            int readTotal = 0;
            byte[] buffer = new byte[8192];

            Debug.WriteLine(string.Format("{0}: RequestParser starting", conn.RemoteEndPoint));

            while ((read = await stream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false)) > 0)
            {
                readTotal += read;

                if (parser.Execute(new ArraySegment<byte>(buffer, 0, read)) != read)
                    throw new FormatException("Parse error in request");

                if (del.headerComplete)
                    break;
            }

            Debug.WriteLine(string.Format("{0}: RequestParser read enough ({1} bytes)", conn.RemoteEndPoint, readTotal));

            if (readTotal == 0)
                return null;

            if (!del.headerComplete)
                throw new FormatException("Parse error in request");

            var request = del.request;

            request.ProtocolVersion = new Version(parser.MajorVersion, parser.MinorVersion);

            int cl = request.ContentLength;

            if (cl > 0)
            {
                if (del.requestBodyStart.Count > 0)
                {
                    request.RequestBody = new MaxReadStream(new StartAvailableStream(del.requestBodyStart, stream), cl);
                }
                else
                {
                    request.RequestBody = new MaxReadStream(stream, cl);
                }
            }

            return request;
        }
Beispiel #12
0
        public void RequestsWithDigits()
        {
            foreach (var request in TestRequest.Requests.Where(r => r.Name.StartsWith("digits in "))) {
                var handler = new Handler();
                var parser = new HttpParser(handler);
                Console.WriteLine("----- Testing request: '" + request.Name + "' -----");

                var parsed = parser.Execute(new ArraySegment<byte>(request.Raw));

                if (parsed != request.Raw.Length)
                    Assert.Fail("Error while parsing.");

                AssertRequest(new TestRequest[] { request }, handler.Requests.ToArray(), parser);
            }
        }
Beispiel #13
0
        public void OnHeadersEnd(HttpParser parser)
        {
            Debug.WriteLine("OnHeadersEnd");

            if (!string.IsNullOrEmpty(headerValue))
                CommitHeader();

            var request = new HttpRequestHeaders()
                {
                    // TODO path, query, fragment?
                    Method = method,
                    Uri = requestUri,
                    Headers = headers,
                    Version = new Version(parser.MajorVersion, parser.MinorVersion)
                };

            del.OnRequestBegan(request, parser.ShouldKeepAlive);
        }
Beispiel #14
0
        static void AssertRequest(TestRequest[] expected, TestRequest[] actual, HttpParser machine)
        {
            for (int i = 0; i < expected.Length; i++)
            {

                Assert.IsTrue(i <= actual.Length - 1, "Expected more requests than received");

                var expectedRequest = expected[i];
                var actualRequest = actual[i];
                //Console.WriteLine("Asserting request " + expectedRequest.Name);
                Assert.AreEqual(expectedRequest.Method, actualRequest.Method, "Unexpected method.");
                Assert.AreEqual(expectedRequest.RequestUri, actualRequest.RequestUri, "Unexpected request URI.");
                Assert.AreEqual(expectedRequest.VersionMajor, actualRequest.VersionMajor, "Unexpected major version.");
                Assert.AreEqual(expectedRequest.VersionMinor, actualRequest.VersionMinor, "Unexpected minor version.");
                Assert.AreEqual(expectedRequest.RequestPath, actualRequest.RequestPath, "Unexpected request path.");
                Assert.AreEqual(expectedRequest.QueryString, actualRequest.QueryString, "Unexpected query string.");
                Assert.AreEqual(expectedRequest.Fragment, actualRequest.Fragment, "Unexpected fragment.");
                //Assert.AreEqual(expected.RequestPath, test.RequestPath, "Unexpected path.");

                Assert.IsTrue(actualRequest.OnHeadersEndCalled, "OnHeadersEnd was not called.");
                Assert.AreEqual(expectedRequest.ShouldKeepAlive, actualRequest.ShouldKeepAlive, "Wrong value for ShouldKeepAlive");

                foreach (var pair in expectedRequest.Headers)
                {
                    Assert.IsTrue(actualRequest.Headers.ContainsKey(pair.Key), "Actual headers did not contain key '" + pair.Key + "'");
                    Assert.AreEqual(pair.Value, actualRequest.Headers[pair.Key], "Actual headers had wrong value for key '" + pair.Key + "'");
                }

                foreach (var pair in actualRequest.Headers)
                {
                    Assert.IsTrue(expectedRequest.Headers.ContainsKey(pair.Key), "Unexpected header named '" + pair.Key + "'");
                }

                if (expectedRequest.Body != null)
                {
                    var expectedBody = Encoding.UTF8.GetString(expectedRequest.Body);
                    Assert.IsNotNull(actualRequest.Body, "Expected non-null request body");
                    var actualBody = Encoding.UTF8.GetString(actualRequest.Body);
                    Assert.AreEqual(expectedBody, actualBody, "Body differs");
                }
                else
                    Assert.IsNull(actualRequest.Body);
            }
        }
		public async Task OnMessageEnd(HttpParser parser)
        {
            //Console.WriteLine("OnMessageEnd");

            Assert.AreEqual(shouldKeepAlive, parser.ShouldKeepAlive, 
                "Differing values for parser.ShouldKeepAlive between OnHeadersEnd and OnMessageEnd");
                
            TestRequest request = new TestRequest();
            request.VersionMajor = versionMajor;
            request.VersionMinor = versionMinor;
            request.ShouldKeepAlive = shouldKeepAlive;

            request.Method = method;
            request.RequestUri = requestUri;
            request.RequestPath = path;
            request.QueryString = queryString;
            request.Fragment = fragment;
            request.Headers = headers;
            request.OnHeadersEndCalled = onHeadersEndCalled;

            // aggregate body chunks into one big chunk
            var length = body.Aggregate(0, (s, b) => s + b.Count);
            if (length > 0)
            {
                request.Body = new byte[length];
                int where = 0;
                foreach (var buf in body)
                {
                    Buffer.BlockCopy(buf.Array, buf.Offset, request.Body, where, buf.Count);
                    where += buf.Count;
                }
            }
            // add it to the list of requests recieved.
            Requests.Add(request);

            // reset our internal state
            versionMajor = versionMinor = -1;
            method = requestUri = queryString = fragment = headerName = headerValue = null;
            headers = null;
            body = null;
            shouldKeepAlive = false;
            onHeadersEndCalled = false;
        }
Beispiel #16
0
        public void SingleChunk()
        {
            // read each request as a single block and parse

            foreach (var request in TestRequest.Requests)
            {
                var handler = new Handler();
                var parser = new HttpParser(handler);
                Console.WriteLine("----- Testing request: '" + request.Name + "' -----");

                var parsed = parser.Execute(new ArraySegment<byte>(request.Raw));

                if (parsed != request.Raw.Length)
                    Assert.Fail("Error while parsing.");

                parser.Execute(default(ArraySegment<byte>));

                AssertRequest(new TestRequest[] { request }, handler.Requests.ToArray(), parser);
            }
        }
Beispiel #17
0
 public void OnMethod(HttpParser parser, string str)
 {
     //Console.WriteLine("OnMethod: '" + str + "'");
     method = str;
 }
Beispiel #18
0
 public void OnResponseCode(HttpMachine.HttpParser parser, int statusCode, string statusReason)
 {
     HttpResponse.StatusCode     = statusCode;
     HttpResponse.ResponseReason = statusReason;
 }
Beispiel #19
0
        public void OnHeaderValue(HttpParser parser, string str)
        {
            //Console.WriteLine("OnHeaderValue:  '" + str + "'");

            if (string.IsNullOrEmpty(headerName))
                throw new Exception("Got header value without name.");

            headerValue = str;
        }
Beispiel #20
0
        public void OnHeaderName(HttpParser parser, string str)
        {
            //Console.WriteLine("OnHeaderName:  '" + str + "'");

            if (!string.IsNullOrEmpty(headerValue))
                CommitHeader();

            headerName = str;
        }
Beispiel #21
0
        public void OnHeadersEnd(HttpParser parser)
        {
            //Console.WriteLine("OnHeadersEnd");
            onHeadersEndCalled = true;

            if (!string.IsNullOrEmpty(headerValue))
                CommitHeader();

            versionMajor = parser.MajorVersion;
            versionMinor = parser.MinorVersion;
            shouldKeepAlive = parser.ShouldKeepAlive;
        }
Beispiel #22
0
 public void OnBody(HttpParser parser, ArraySegment<byte> data)
 {
     //var str = Encoding.ASCII.GetString(data.Array, data.Offset, data.Count);
     //Console.WriteLine("OnBody:  '" + str + "'");
     body.Add(data);
 }
Beispiel #23
0
 public void OnFragment(HttpParser parser, string str)
 {
     //Console.WriteLine("OnFragment:  '" + str + "'");
     fragment = str;
 }
Beispiel #24
0
 public void OnBody(HttpMachine.HttpParser parser, ArraySegment <byte> data)
 {
     HttpResponse.Body.Write(data.Array, 0, data.Array.Length);
 }
Beispiel #25
0
 public void OnMessageEnd(HttpMachine.HttpParser parser)
 {
     HttpResponse.IsEndOfRequest = true;
 }
Beispiel #26
0
 public void OnRequestUri(HttpParser parser, string str)
 {
     //Console.WriteLine("OnRequestUri:  '" + str + "'");
     requestUri = str;
 }
Beispiel #27
0
 public void OnPath(HttpParser parser, string str)
 {
     //Console.WriteLine("OnPath:  '" + str + "'");
     path = str;
 }
Beispiel #28
0
 public void OnMethod(HttpParser parser, string method)
 {
     this.request.method = method;
 }
Beispiel #29
0
 public void OnQueryString(HttpParser parser, string str)
 {
     //Console.WriteLine("OnQueryString:  '" + str + "'");
     queryString = str;
 }
Beispiel #30
0
 public void OnRequestUri(HttpParser parser, string requestUri)
 {
     this.request.uri = requestUri;
 }
 public void OnResponseCode(HttpParser parser, int code, string reason)
 {
     statusCode = code;
     statusReason = reason;
 }
Beispiel #32
0
        static void ThreeChunkScan(IEnumerable<TestRequest> requests)
        {
            // read each sequence of requests as three blocks, with the breaks in every possible combination.

            // one buffer to rule them all
            var raw = new byte[requests.Aggregate(0, (s, b) => s + b.Raw.Length)];
            int where = 0;
            foreach (var r in requests)
            {
                Buffer.BlockCopy(r.Raw, 0, raw, where, r.Raw.Length);
                where += r.Raw.Length;
            }

            int totalOperations = (raw.Length - 1) * (raw.Length - 2) / 2;
            int operationsCompleted = 0;
            byte[] buffer1 = new byte[80 * 1024];
            byte[] buffer2 = new byte[80 * 1024];
            byte[] buffer3 = new byte[80 * 1024];
            int buffer1Length = 0, buffer2Length = 0, buffer3Length = 0;

            Console.WriteLine("----- Testing requests: " +
                requests.Aggregate("", (s, r) => s + "; " + r.Name).TrimStart(';', ' ') +
                " (" + totalOperations + " ops) -----");

            int lastI = 0;
            int lastJ = 0;

            try
            {
                for (int j = 2; j < raw.Length; j++)
                    for (int i = 1; i < j; i++)
                    {
                        lastI = i; lastJ = j;
                        //Console.WriteLine();
                        if (operationsCompleted % 1000 == 0)
                            Console.WriteLine("  " + (100.0 * ((float)operationsCompleted / (float)totalOperations)));

                        operationsCompleted++;
                        //Console.WriteLine(operationsCompleted + " / " + totalOperations);

                        var handler = new Handler();
                        var parser = new HttpParser(handler);

                        buffer1Length = i;
                        Buffer.BlockCopy(raw, 0, buffer1, 0, buffer1Length);
                        buffer2Length = j - i;
                        Buffer.BlockCopy(raw, i, buffer2, 0, buffer2Length);
                        buffer3Length = raw.Length - j;
                        Buffer.BlockCopy(raw, j, buffer3, 0, buffer3Length);

                        //Console.WriteLine("Parsing buffer 1.");
                        Assert.AreEqual(buffer1Length, parser.Execute(new ArraySegment<byte>(buffer1, 0, buffer1Length)), "Error parsing buffer 1.");

                        //Console.WriteLine("Parsing buffer 2.");
                        Assert.AreEqual(buffer2Length, parser.Execute(new ArraySegment<byte>(buffer2, 0, buffer2Length)), "Error parsing buffer 2.");

                        //Console.WriteLine("Parsing buffer 3.");
                        Assert.AreEqual(buffer3Length, parser.Execute(new ArraySegment<byte>(buffer3, 0, buffer3Length)), "Error parsing buffer 3.");

                        //Console.WriteLine("Parsing EOF");
                        Assert.AreEqual(parser.Execute(default(ArraySegment<byte>)), 0, "Error parsing EOF chunk.");

                        AssertRequest(requests.ToArray(), handler.Requests.ToArray(), parser);
                    }
            }
            catch
            {
                Console.WriteLine("Problem while parsing chunks:");
                Console.WriteLine("---");
                Console.WriteLine(Encoding.UTF8.GetString(buffer1, 0, buffer1Length));
                Console.WriteLine("---");
                Console.WriteLine(Encoding.UTF8.GetString(buffer2, 0, buffer2Length));
                Console.WriteLine("---");
                Console.WriteLine(Encoding.UTF8.GetString(buffer3, 0, buffer3Length));
                Console.WriteLine("---");
                Console.WriteLine("Failed on i = " + lastI + " j = " + lastJ);
                throw;
            }
        }
Beispiel #33
0
 public void OnQueryString(HttpParser parser, string queryString)
 {
     this.request.query = queryString;
 }
Beispiel #34
0
 public void OnMessageBegin(HttpMachine.HttpParser parser)
 {
 }