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(); } }
private void OnBytesRead(IOStream stream, byte [] data, int offset, int count) { ByteBuffer bytes = new ByteBuffer(data, offset, count); try { parser.Execute(parser_settings, bytes); } catch (Exception e) { Console.WriteLine("Exception while parsing"); Console.WriteLine(e); } if (finished_reading && parser.Upgrade) { // // Well, this is a bit of a hack. Ideally, maybe there should be a putback list // on the socket so we can put these bytes back into the stream and the upgrade // protocol handler can read them out as if they were just reading normally. // if (bytes.Position < bytes.Length) { byte [] upgrade_head = new byte [bytes.Length - bytes.Position]; Array.Copy(bytes.Bytes, bytes.Position, upgrade_head, 0, upgrade_head.Length); SetProperty("UPGRADE_HEAD", upgrade_head); } // This is delayed until here with upgrade connnections. OnFinishedReading(parser); } }
public virtual bool OnData(ISocket socket, ArraySegment <byte> data, Action continuation) { try { //Since HTTP connection is used by server to send HTTP requests (Player status updates) //back to Ios client, the HTTP connections will also receive HTTP responses from the client. //This is a quick and dirty hack to ignore these response messages. bool skipParse = false; if (data.Count == 38) { if (Encoding.UTF8.GetString(data.Array, 0, 38) == "HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n") { skipParse = true; } } var parsed = parser.Execute(data); if (parsed != data.Count && !skipParse) { Trace.Write("Error while parsing request."); throw new Exception("Error while parsing request."); } // raises request events on transaction delegate return(transactionTransform.Commit(continuation)); } catch (Exception e) { OnError(socket, e); OnClose(socket); throw; } }
public void ExecuteCallbacks() { const string request = "HTTP/1.1 200 OK\r\n" + "Date: Fri, 31 Dec 1999 23:59:59 GMT\r\n" + "Content-Type: text/plain\r\n" + "Content-Length: 42\r\n" + "some-footer: some-value\r\n" + "another-footer: another-value\r\n" + "\r\n" + "abcdefghijklmnopqrstuvwxyz1234567890abcdef"; var requestBytes = Encoding.UTF8.GetBytes(request); var eventHandler = new EventHttpParserHandler(); using (var parser = new HttpParser(HttpParserType.Both, eventHandler)) { var buffer = new ArraySegment <byte>(requestBytes); parser.Execute(buffer); CollectionAssert.AreEqual(new [] { "OnMessageBegin", "OK", "OnHeadersComplete", "OnBody", "abcdefghijklmnopqrstuvwxyz1234567890abcdef", "OnMessageComplete" }, eventHandler.Events); } }
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); }
private void OnData(TcpSocket socket, ArraySegment <byte> data) { int received = _parser.Execute(data.Array, data.Offset, data.Count); if (_parser.Errno == HttpParserError.PAUSED) { if (data.Count > received) { _pausedData = new ArraySegment <byte>(data.Array, data.Offset + received, data.Count - received); } if (_parser.Upgrade) { _socket.OnConnected -= OnSocketConnected; _socket.OnDisconnected -= OnSocketDisconnected; _socket.OnData -= OnData; _server.HandleUpgrade(_msg, _socket, _pausedData); } else { _server.HandleRequest(_msg, this); } } else if (_parser.Errno != HttpParserError.OK) { Close(); } }
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); }
public void update(byte[] buffer, int len) { int parsedLength = parser_.Execute(new ArraySegment <byte>(buffer, 0, len)); if (parsedLength != len) { string s = "Error parsing http message, last input was: \n" + Encoding.UTF8.GetString(buffer) + "\n" + "Input was " + len + " bytes, only consumed " + parsedLength; throw new Exception(s); } }
private void OnBytesRead(IOStream stream, byte [] data, int offset, int count) { ByteBuffer bytes = new ByteBuffer(data, offset, count); try { parser.Execute(parser_settings, bytes); } catch (Exception e) { Console.WriteLine("Exception while parsing"); Console.WriteLine(e); Socket.Close(); } }
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); } }
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); } }
public void HttpParserBench() { var data = Encoding.ASCII.GetBytes(request_str); var data_len = data.Length; for (int i = 0; i < 500000; i++) { var parser = new HttpParser(HttpParserType.REQUEST); parser.on_message_begin = on_info; parser.on_headers_complete = on_info; parser.on_message_complete = on_info; parser.on_header_field = on_data; parser.on_header_value = on_data; parser.on_url = on_data; parser.on_status = on_data; parser.on_body = on_data; var parsed = parser.Execute(data, 0, data_len); Assert.AreEqual(data_len, parsed); } }
public bool OnData(ISocket socket, ArraySegment <byte> data, Action continuation) { try { var parsed = parser.Execute(data); if (parsed != data.Count) { Trace.Write("Error while parsing request."); throw new Exception("Error while parsing request."); } // raises request events on transaction delegate return(transactionTransform.Commit(continuation)); } catch (Exception e) { OnError(socket, e); OnClose(socket); throw; } }
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."); 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; } }
public void Parse(ArraySegment <byte> buffer) { _parser.Execute(buffer); _parser.Execute(default(ArraySegment <byte>)); }