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 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; }
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); } }
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; } }
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(); } }