private static void TechEmpowerJsonNoIO(int numberOfRequests, int concurrentConnections) { foreach (var iteration in Benchmark.Iterations) { using (iteration.StartMeasurement()) { RawInMemoryHttpServer.Run(numberOfRequests, concurrentConnections, s_genericRequest, (request, response) => { var formatter = new OutputFormatter <WritableBuffer>(response, EncodingData.InvariantUtf8); formatter.Append("HTTP/1.1 200 OK"); formatter.Append("\r\nContent-Length: 25"); formatter.Append("\r\nContent-Type: application/json"); formatter.Format("\r\nDate: {0:R}", DateTime.UtcNow); formatter.Append("Server: System.IO.Pipelines"); formatter.Append("\r\n\r\n"); // write body var writer = new JsonWriter <OutputFormatter <WritableBuffer> >(formatter); writer.WriteObjectStart(); writer.WriteAttribute("message", "Hello, World!"); writer.WriteObjectEnd(); }); } } }
private static void TechEmpowerHelloWorldNoIO(int numberOfRequests, int concurrentConnections) { foreach (var iteration in Benchmark.Iterations) { using (iteration.StartMeasurement()) { RawInMemoryHttpServer.Run(numberOfRequests, concurrentConnections, s_genericRequest, (request, response) => { var formatter = new OutputFormatter <WritableBuffer>(response, EncodingData.InvariantUtf8); formatter.Append("HTTP/1.1 200 OK"); formatter.Append("\r\nContent-Length: 13"); formatter.Append("\r\nContent-Type: text/plain"); formatter.Format("\r\nDate: {0:R}", DateTime.UtcNow); formatter.Append("Server: System.IO.Pipelines"); formatter.Append("\r\n\r\n"); // write body formatter.Append("Hello, World!"); }); } } }
public static void Run() { var ip = IPAddress.Any; int port = 5000; var thread = new UvThread(); var listener = new UvTcpListener(thread, new IPEndPoint(ip, port)); listener.OnConnection(async connection => { var httpParser = new HttpRequestParser(); while (true) { // Wait for data var result = await connection.Input.ReadAsync(); var input = result.Buffer; var consumed = input.Start; var examined = input.Start; try { if (input.IsEmpty && result.IsCompleted) { // No more data break; } // Parse the input http request var parseResult = httpParser.ParseRequest(input, out consumed, out examined); switch (parseResult) { case HttpRequestParser.ParseResult.Incomplete: if (result.IsCompleted) { // Didn't get the whole request and the connection ended throw new EndOfStreamException(); } // Need more data continue; case HttpRequestParser.ParseResult.Complete: break; case HttpRequestParser.ParseResult.BadRequest: throw new Exception(); default: break; } // Writing directly to pooled buffers var output = connection.Output.Alloc(); var formatter = new OutputFormatter <WritableBuffer>(output, TextEncoder.Utf8); formatter.Append("HTTP/1.1 200 OK"); formatter.Append("\r\nContent-Length: 13"); formatter.Append("\r\nContent-Type: text/plain"); formatter.Append("\r\n\r\n"); formatter.Append("Hello, World!"); await output.FlushAsync(); httpParser.Reset(); } finally { // Consume the input connection.Input.Advance(consumed, examined); } } }); listener.StartAsync().GetAwaiter().GetResult(); Console.WriteLine($"Listening on {ip} on port {port}"); var wh = new ManualResetEventSlim(); Console.CancelKeyPress += (sender, e) => { wh.Set(); }; wh.Wait(); listener.Dispose(); thread.Dispose(); }
public static async Task HandleConnection(IPipeConnection connection, ILoggerFactory loggerFactory) { var logger = loggerFactory?.CreateLogger <ServerLoop>(); var httpParser = new HttpRequestParser(loggerFactory); var connectionId = Guid.NewGuid(); using (var lScope = logger.BeginScope("Connection started", connectionId)) { while (true) { // Wait for data var result = await connection.Input.ReadAsync(); var input = result.Buffer; logger?.LogTrace("Http data received"); try { if (input.IsEmpty && result.IsCompleted) { logger?.LogTrace("No more data on the connection"); // No more data break; } // Parse the input http request var parseResult = httpParser.ParseRequest(ref input); switch (parseResult) { case HttpRequestParser.ParseResult.Incomplete: logger?.LogTrace("Incomplete parsed"); if (result.IsCompleted) { // Didn't get the whole request and the connection ended throw new EndOfStreamException(); } // Need more data continue; case HttpRequestParser.ParseResult.Complete: logger?.LogTrace("Parsing completed"); break; case HttpRequestParser.ParseResult.BadRequest: logger?.LogTrace("Parsing bad request"); throw new Exception(); default: break; } //// Writing directly to pooled buffers //var output = connection.Output.Alloc(); //var formatter = new OutputFormatter<WritableBuffer>(output, EncodingData.InvariantUtf8); //formatter.Append("HTTP/1.1 200 OK"); //formatter.Append("\r\nContent-Length: 13"); //formatter.Append("\r\nContent-Type: text/plain"); //formatter.Append("\r\n\r\n"); //formatter.Append("Hello, World!"); //await output.FlushAsync(); logger?.LogTrace("Http method is {method}", httpParser.Method); if (httpParser.Method.Length == 3 && httpParser.Method.StartsWith(_getMethod)) { var path = httpParser.Path.GetUtf8String(); logger?.LogTrace("Path is {path}", path); var cacheItem = _cache.GetCacheItem(path); if (cacheItem != null) { var output = connection.Output.Alloc(); var formatter = new OutputFormatter <WritableBuffer>(output, EncodingData.InvariantUtf8); formatter.Append("HTTP/1.1 200 OK"); formatter.Append("\r\nContent-Length: "); formatter.Append(cacheItem.Content.Length); formatter.Append("\r\nContent-Type: "); output.Write(cacheItem.ContentType); formatter.Append("\r\n\r\n"); output.Write(cacheItem.Content); logger?.LogTrace("Returning 200 ok {path}", path); await output.FlushAsync(); } else { var output = connection.Output.Alloc(); var formatter = new OutputFormatter <WritableBuffer>(output, EncodingData.InvariantUtf8); formatter.Append("HTTP/1.1 404 NOT FOUND"); formatter.Append("\r\nContent-Length: 0"); formatter.Append("\r\n\r\n"); logger?.LogTrace("Returning 404 not found {path}", path); await output.FlushAsync(); } } else { var output = connection.Output.Alloc(); var formatter = new OutputFormatter <WritableBuffer>(output, EncodingData.InvariantUtf8); formatter.Append("HTTP/1.1 404 NOT FOUND"); formatter.Append("\r\nContent-Length: 0"); formatter.Append("\r\n\r\n"); await output.FlushAsync().GetAwaiter(); } if (httpParser.RequestHeaders["Connection"] == "close") { connection.Output.Complete(); } httpParser.Reset(); } finally { // Consume the input connection.Input.Advance(input.Start, input.End); } } } }
protected async Task ProcessConnection(IPipeConnection connection) { var httpParser = new HttpRequestParser(); while (true) { // Wait for data var result = await connection.Input.ReadAsync(); var input = result.Buffer; var consumed = input.Start; var examined = input.Start; try { if (input.IsEmpty && result.IsCompleted) { // No more data break; } // Parse the input http request var parseResult = httpParser.ParseRequest(input, out consumed, out examined); switch (parseResult) { case HttpRequestParser.ParseResult.Incomplete: if (result.IsCompleted) { // Didn't get the whole request and the connection ended throw new EndOfStreamException(); } // Need more data continue; case HttpRequestParser.ParseResult.Complete: break; case HttpRequestParser.ParseResult.BadRequest: throw new Exception(); default: break; } // Writing directly to pooled buffers var output = connection.Output.Alloc(); var formatter = new OutputFormatter <WritableBufferOutput>(output.AsOutput(), SymbolTable.InvariantUtf8); formatter.Append("HTTP/1.1 200 OK"); formatter.Append("\r\nContent-Length: 13"); formatter.Append("\r\nContent-Type: text/plain"); formatter.Append("\r\n\r\n"); formatter.Append("Hello, World!"); await output.FlushAsync(); httpParser.Reset(); } finally { // Consume the input connection.Input.Advance(consumed, examined); } } }
public static async Task HandleConnection(IPipelineConnection connection) { var httpParser = new HttpRequestParser(); while (true) { // Wait for data var result = await connection.Input.ReadAsync(); var input = result.Buffer; Console.WriteLine("Http data received"); try { if (input.IsEmpty && result.IsCompleted) { // No more data break; } // Parse the input http request var parseResult = httpParser.ParseRequest(ref input); switch (parseResult) { case HttpRequestParser.ParseResult.Incomplete: Console.WriteLine("Incomplete parsed"); if (result.IsCompleted) { // Didn't get the whole request and the connection ended throw new EndOfStreamException(); } // Need more data continue; case HttpRequestParser.ParseResult.Complete: Console.WriteLine("Parsing completed"); break; case HttpRequestParser.ParseResult.BadRequest: Console.WriteLine("Parsing bad request"); throw new Exception(); default: break; } //// Writing directly to pooled buffers //var output = connection.Output.Alloc(); //var formatter = new OutputFormatter<WritableBuffer>(output, EncodingData.InvariantUtf8); //formatter.Append("HTTP/1.1 200 OK"); //formatter.Append("\r\nContent-Length: 13"); //formatter.Append("\r\nContent-Type: text/plain"); //formatter.Append("\r\n\r\n"); //formatter.Append("Hello, World!"); //await output.FlushAsync(); if (httpParser.Method.Length == 3 && httpParser.Method.StartsWith(_getMethod)) { var path = httpParser.Path.GetUtf8String(); var cacheItem = _cache.GetCacheItem(path); if (cacheItem != null) { var output = connection.Output.Alloc(); var formatter = new OutputFormatter <WritableBuffer>(output, EncodingData.InvariantUtf8); formatter.Append("HTTP/1.1 200 OK"); formatter.Append("\r\nContent-Length: "); formatter.Append(cacheItem.Content.Length); formatter.Append("\r\nContent-Type: "); output.Write(cacheItem.ContentType); formatter.Append("\r\n\r\n"); output.Write(cacheItem.Content); Console.WriteLine($"{path}-HTTP / 1.1 200 OK"); await output.FlushAsync(); } else { var output = connection.Output.Alloc(); var formatter = new OutputFormatter <WritableBuffer>(output, EncodingData.InvariantUtf8); formatter.Append("HTTP/1.1 404 NOT FOUND"); formatter.Append("\r\nContent-Length: 0"); formatter.Append("\r\n\r\n"); Console.WriteLine($"{path}-HTTP / 1.1 404 NOT FOUND"); await output.FlushAsync(); } } else { var output = connection.Output.Alloc(); var formatter = new OutputFormatter <WritableBuffer>(output, EncodingData.InvariantUtf8); formatter.Append("HTTP/1.1 404 NOT FOUND"); formatter.Append("\r\nContent-Length: 0"); formatter.Append("\r\n\r\n"); await output.FlushAsync(); } if (httpParser.RequestHeaders["Connection"] == "close") { connection.Output.Complete(); } httpParser.Reset(); } finally { // Consume the input connection.Input.Advance(input.Start, input.End); } } }
public static void Run() { var ip = IPAddress.Any; int port = 5000; var thread = new UvThread(); var listener = new UvTcpListener(thread, new IPEndPoint(ip, port)); listener.OnConnection(async connection => { var httpParser = new HttpRequestParser(); while (true) { // Wait for data var result = await connection.Input.ReadAsync(); var input = result.Buffer; try { if (input.IsEmpty && result.IsCompleted) { // No more data break; } // Parse the input http request var parseResult = httpParser.ParseRequest(ref input); switch (parseResult) { case HttpRequestParser.ParseResult.Incomplete: if (result.IsCompleted) { // Didn't get the whole request and the connection ended throw new EndOfStreamException(); } // Need more data continue; case HttpRequestParser.ParseResult.Complete: break; case HttpRequestParser.ParseResult.BadRequest: throw new Exception(); default: break; } // Writing directly to pooled buffers var output = connection.Output.Alloc(); var formatter = new OutputFormatter<WritableBuffer>(output, EncodingData.InvariantUtf8); formatter.Append("HTTP/1.1 200 OK"); formatter.Append("\r\nContent-Length: 13"); formatter.Append("\r\nContent-Type: text/plain"); formatter.Append("\r\n\r\n"); formatter.Append("Hello, World!"); await output.FlushAsync(); httpParser.Reset(); } finally { // Consume the input connection.Input.Advance(input.Start, input.End); } } }); listener.StartAsync().GetAwaiter().GetResult(); Console.WriteLine($"Listening on {ip} on port {port}"); var wh = new ManualResetEventSlim(); Console.CancelKeyPress += (sender, e) => { wh.Set(); }; wh.Wait(); listener.Dispose(); thread.Dispose(); }