Пример #1
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);
            }
        }
Пример #2
0
        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;
        }
        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;
        }
Пример #4
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);
            }
        }
Пример #5
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;
            }
        }
Пример #6
0
        private void NewTcpClient(object obj)
        {
            var client      = obj as TcpClient;
            var stream      = client.GetStream();
            var handler     = new ParserHandler();
            var requ        = new Request();
            var context     = new Context();
            var response    = new Response();

            var parser      = new HttpParser(handler);
            handler.setData(requ);
            int bytesRead = 0 ;
            var buffer = new byte[1024 /* or whatever you like */];

            try
            {

                while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    if (bytesRead == parser.Execute(new ArraySegment<byte>(buffer, 0, bytesRead)))
                        break;
                }
                // ensure you get the last callbacks.
                parser.Execute(default(ArraySegment<byte>));

                logger.InfoFormat("[{0}] URI : {1}", requ.method,requ.uri);
                var svc = this.router.route(requ.uri);
                switch (requ.method)
                {
                   case "GET" :
                     svc._get(context, requ, response);
                     break;

                    case "POST":
                        svc._post(context, requ, response);
                        break;
                }
                response.send(stream);
            }
            catch (Exception ex)
            {
                logger.ErrorFormat("exception: {0} ", ex.Message);
            }
            finally
            {
                stream.Close();
                client.Close();

            }
        }