diff --git a/Core/GenHTTP.Core/Infrastructure/Endpoints/EndPoint.cs b/Core/GenHTTP.Core/Infrastructure/Endpoints/EndPoint.cs index b0e50cad..cf24d1c4 100644 --- a/Core/GenHTTP.Core/Infrastructure/Endpoints/EndPoint.cs +++ b/Core/GenHTTP.Core/Infrastructure/Endpoints/EndPoint.cs @@ -63,8 +63,7 @@ protected EndPoint(IServer server, IPEndPoint endPoint, NetworkConfiguration con throw new BindingException($"Failed to bind to {endPoint}.", e); } - - Task = Task.Run(() => Listen()); + Task = Task.Factory.StartNew(() => Listen(), CancellationToken.None, TaskCreationOptions.DenyChildAttach | TaskCreationOptions.LongRunning, TaskScheduler.Default); } #endregion @@ -77,7 +76,7 @@ private async Task Listen() { do { - Handle(await Socket.AcceptAsync()); + Handle(await Socket.AcceptAsync().ConfigureAwait(false)); } while (!shuttingDown); } @@ -92,15 +91,17 @@ private async Task Listen() private void Handle(Socket client) { - Task.Factory.StartNew(state => Accept((Socket)state), client, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); + Task.Factory.StartNew(state => Accept((Socket)state), client, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default) + .ConfigureAwait(false); } protected abstract Task Accept(Socket client); - protected Task Handle(Socket client, Stream inputStream) + protected async Task Handle(Socket client, Stream inputStream) { inputStream.ReadTimeout = (int)Configuration.RequestReadTimeout.TotalMilliseconds; - return new ClientHandler(client, inputStream, Server, this, Configuration).Run(); + + await new ClientHandler(client, inputStream, Server, this, Configuration).Run().ConfigureAwait(false); } #endregion diff --git a/Core/GenHTTP.Core/Infrastructure/Endpoints/SecureEndPoint.cs b/Core/GenHTTP.Core/Infrastructure/Endpoints/SecureEndPoint.cs index f8b6906a..009bb9ef 100644 --- a/Core/GenHTTP.Core/Infrastructure/Endpoints/SecureEndPoint.cs +++ b/Core/GenHTTP.Core/Infrastructure/Endpoints/SecureEndPoint.cs @@ -51,11 +51,11 @@ internal SecureEndPoint(IServer server, IPEndPoint endPoint, SecurityConfigurati protected override async Task Accept(Socket client) { - var stream = await TryAuthenticate(client); + var stream = await TryAuthenticate(client).ConfigureAwait(false); if (stream != null) { - await Handle(client, stream); + await Handle(client, stream).ConfigureAwait(false); } else { @@ -77,7 +77,7 @@ protected override async Task Accept(Socket client) { var stream = new SslStream(new NetworkStream(client), false); - await stream.AuthenticateAsServerAsync(AuthenticationOptions, CancellationToken.None); + await stream.AuthenticateAsServerAsync(AuthenticationOptions, CancellationToken.None).ConfigureAwait(false); return stream; } diff --git a/Core/GenHTTP.Core/Protocol/ClientHandler.cs b/Core/GenHTTP.Core/Protocol/ClientHandler.cs index ed059ac8..5d67888b 100644 --- a/Core/GenHTTP.Core/Protocol/ClientHandler.cs +++ b/Core/GenHTTP.Core/Protocol/ClientHandler.cs @@ -55,7 +55,7 @@ internal async Task Run() { try { - await HandlePipe(PipeReader.Create(Stream, READER_OPTIONS)); + await HandlePipe(PipeReader.Create(Stream, READER_OPTIONS)).ConfigureAwait(false); ; } catch (Exception e) { @@ -92,7 +92,7 @@ private async Task HandlePipe(PipeReader reader) RequestBuilder? request; - while ((request = await parser.TryParseAsync(buffer)) != null) + while ((request = await parser.TryParseAsync(buffer).ConfigureAwait(false)) != null) { if (!await HandleRequest(request)) { @@ -102,7 +102,7 @@ private async Task HandlePipe(PipeReader reader) } finally { - await reader.CompleteAsync(); + await reader.CompleteAsync().ConfigureAwait(false); } } @@ -110,34 +110,32 @@ private async ValueTask HandleRequest(RequestBuilder builder) { var address = ((IPEndPoint)Connection.RemoteEndPoint).Address; - using (var request = builder.Connection(Server, EndPoint, address).Build()) + using var request = builder.Connection(Server, EndPoint, address).Build(); + + if (KeepAlive == null) { - if (KeepAlive == null) - { - KeepAlive = request["Connection"]?.Equals("Keep-Alive", StringComparison.InvariantCultureIgnoreCase) ?? false; - } - - bool keepAlive = (bool)KeepAlive; + KeepAlive = request["Connection"]?.Equals("Keep-Alive", StringComparison.InvariantCultureIgnoreCase) ?? false; + } - var responseHandler = new ResponseHandler(Server, Stream, Configuration); - var requestHandler = new RequestHandler(Server); + bool keepAlive = (bool)KeepAlive; - using (var response = requestHandler.Handle(request, out Exception? error)) - { - var success = await responseHandler.Handle(request, response, keepAlive, error); + var responseHandler = new ResponseHandler(Server, Stream, Configuration); + var requestHandler = new RequestHandler(Server); - if (!success || !keepAlive) - { - Connection.LingerState = LINGER_OPTION; - Connection.Disconnect(false); - Connection.Close(); + using var response = requestHandler.Handle(request, out Exception? error); + + var success = await responseHandler.Handle(request, response, keepAlive, error).ConfigureAwait(false); - return false; - } + if (!success || !keepAlive) + { + Connection.LingerState = LINGER_OPTION; + Connection.Disconnect(false); + Connection.Close(); - return true; - } + return false; } + + return true; } #endregion diff --git a/Core/GenHTTP.Core/Protocol/RequestBuffer.cs b/Core/GenHTTP.Core/Protocol/RequestBuffer.cs index d03cff0c..28c8a9b1 100644 --- a/Core/GenHTTP.Core/Protocol/RequestBuffer.cs +++ b/Core/GenHTTP.Core/Protocol/RequestBuffer.cs @@ -44,7 +44,7 @@ internal RequestBuffer(PipeReader reader, NetworkConfiguration configuration) try { - Data = (await Reader.ReadAsync(cancellation.Token)).Buffer; + Data = (await Reader.ReadAsync(cancellation.Token).ConfigureAwait(false)).Buffer; } catch (OperationCanceledException) { diff --git a/Core/GenHTTP.Core/Protocol/RequestContentParser.cs b/Core/GenHTTP.Core/Protocol/RequestContentParser.cs index 1dd6489f..ebb87c3e 100644 --- a/Core/GenHTTP.Core/Protocol/RequestContentParser.cs +++ b/Core/GenHTTP.Core/Protocol/RequestContentParser.cs @@ -39,7 +39,7 @@ internal async Task GetBody(RequestBuffer buffer) while (toFetch > 0) { - await buffer.Read(); + await buffer.Read().ConfigureAwait(false); var toRead = Math.Min(buffer.Data.Length, Math.Min(Configuration.TransferBufferSize, toFetch)); @@ -49,7 +49,7 @@ internal async Task GetBody(RequestBuffer buffer) while (data.TryGet(ref position, out var memory)) { - await body.WriteAsync(memory); + await body.WriteAsync(memory).ConfigureAwait(false); } buffer.Advance(toRead); diff --git a/Core/GenHTTP.Core/Protocol/RequestParser.cs b/Core/GenHTTP.Core/Protocol/RequestParser.cs index 1bdaa97b..4fda2ec3 100644 --- a/Core/GenHTTP.Core/Protocol/RequestParser.cs +++ b/Core/GenHTTP.Core/Protocol/RequestParser.cs @@ -36,7 +36,7 @@ internal RequestParser(NetworkConfiguration configuration) { string? method, path, protocol; - if ((method = await TryReadToken(buffer, ' ')) != null) + if ((method = await TryReadToken(buffer, ' ').ConfigureAwait(false)) != null) { Request.Type(method); } @@ -45,7 +45,7 @@ internal RequestParser(NetworkConfiguration configuration) return null; } - if ((path = await TryReadToken(buffer, ' ')) != null) + if ((path = await TryReadToken(buffer, ' ').ConfigureAwait(false)) != null) { Request.Path(path); } @@ -54,7 +54,7 @@ internal RequestParser(NetworkConfiguration configuration) return null; } - if ((protocol = await TryReadToken(buffer, '\r', 1, 5)) != null) + if ((protocol = await TryReadToken(buffer, '\r', 1, 5).ConfigureAwait(false)) != null) { Request.Protocol(protocol); } @@ -63,9 +63,9 @@ internal RequestParser(NetworkConfiguration configuration) return null; } - while (await TryReadHeader(buffer, Request)) { /* nop */ } + while (await TryReadHeader(buffer, Request).ConfigureAwait(false)) { /* nop */ } - if (await TryReadToken(buffer, '\r', 1) == null) + if ((await TryReadToken(buffer, '\r', 1).ConfigureAwait(false)) == null) { return null; } @@ -78,7 +78,7 @@ internal RequestParser(NetworkConfiguration configuration) { var parser = new RequestContentParser(length, Configuration); - Request.Content(await parser.GetBody(buffer)); + Request.Content(await parser.GetBody(buffer).ConfigureAwait(false)); } } else @@ -97,9 +97,9 @@ private async ValueTask TryReadHeader(RequestBuffer buffer, RequestBuilder { string? key, value; - if ((key = await TryReadToken(buffer, ':', 1)) != null) + if ((key = await TryReadToken(buffer, ':', 1).ConfigureAwait(false)) != null) { - if ((value = await TryReadToken(buffer, '\r', 1)) != null) + if ((value = await TryReadToken(buffer, '\r', 1).ConfigureAwait(false)) != null) { request.Header(key, value); return true; @@ -115,7 +115,7 @@ private async ValueTask TryReadHeader(RequestBuffer buffer, RequestBuilder if (position == null) { - if (await buffer.Read(true) == null) + if ((await buffer.Read(true).ConfigureAwait(false)) == null) { return null; } diff --git a/Core/GenHTTP.Core/Protocol/ResponseHandler.cs b/Core/GenHTTP.Core/Protocol/ResponseHandler.cs index bfb43f7f..998e0812 100644 --- a/Core/GenHTTP.Core/Protocol/ResponseHandler.cs +++ b/Core/GenHTTP.Core/Protocol/ResponseHandler.cs @@ -1,7 +1,6 @@ using System; using System.Buffers; using System.IO; -using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; @@ -15,8 +14,6 @@ namespace GenHTTP.Core.Protocol internal class ResponseHandler { - private static readonly Encoding HEADER_ENCODING = Encoding.GetEncoding("ISO-8859-1"); - private static readonly string NL = "\r\n"; private static readonly ArrayPool POOL = ArrayPool.Shared; @@ -48,15 +45,15 @@ internal async ValueTask Handle(IRequest request, IResponse response, bool { try { - await WriteStatus(request, response); + await WriteStatus(request, response).ConfigureAwait(false); - await WriteHeader(response, keepAlive); + await WriteHeader(response, keepAlive).ConfigureAwait(false); - await Write(NL); + await Write(NL).ConfigureAwait(false); if (ShouldSendBody(request, response)) { - await WriteBody(response); + await WriteBody(response).ConfigureAwait(false); } Server.Companion?.OnRequestHandled(request, response, error); @@ -85,68 +82,68 @@ private async ValueTask WriteStatus(IRequest request, IResponse response) { var version = (request.ProtocolType == HttpProtocol.Http_1_0) ? "1.0" : "1.1"; - await Write("HTTP/"); - await Write(version); + await Write("HTTP/").ConfigureAwait(false); + await Write(version).ConfigureAwait(false); - await Write(" "); + await Write(" ").ConfigureAwait(false); - await Write(response.Status.RawStatus.ToString()); + await Write(response.Status.RawStatus.ToString()).ConfigureAwait(false); - await Write(" "); + await Write(" ").ConfigureAwait(false); - await Write(response.Status.Phrase); + await Write(response.Status.Phrase).ConfigureAwait(false); - await Write(NL); + await Write(NL).ConfigureAwait(false); } private async ValueTask WriteHeader(IResponse response, bool keepAlive) { - await Write("Server: GenHTTP/"); - await Write(Server.Version); - await Write(NL); + await Write("Server: GenHTTP/").ConfigureAwait(false); + await Write(Server.Version).ConfigureAwait(false); + await Write(NL).ConfigureAwait(false); - await WriteHeaderLine("Date", DateHeader.Value); + await WriteHeaderLine("Date", DateHeader.Value).ConfigureAwait(false); - await WriteHeaderLine("Connection", (keepAlive) ? "Keep-Alive" : "Close"); + await WriteHeaderLine("Connection", (keepAlive) ? "Keep-Alive" : "Close").ConfigureAwait(false); if (!(response.ContentType is null)) { - await WriteHeaderLine("Content-Type", response.ContentType.Value.RawType); + await WriteHeaderLine("Content-Type", response.ContentType.Value.RawType).ConfigureAwait(false); } if (response.ContentEncoding != null) { - await WriteHeaderLine("Content-Encoding", response.ContentEncoding!); + await WriteHeaderLine("Content-Encoding", response.ContentEncoding!).ConfigureAwait(false); } if (response.ContentLength != null) { - await WriteHeaderLine("Content-Length", response.ContentLength.ToString()); + await WriteHeaderLine("Content-Length", response.ContentLength.ToString()).ConfigureAwait(false); } if (response.Modified != null) { - await WriteHeaderLine("Last-Modified", (DateTime)response.Modified); + await WriteHeaderLine("Last-Modified", (DateTime)response.Modified).ConfigureAwait(false); } if (response.Expires != null) { - await WriteHeaderLine("Expires", (DateTime)response.Expires); + await WriteHeaderLine("Expires", (DateTime)response.Expires).ConfigureAwait(false); } if ((response.Content != null) && (response.ContentLength == null)) { - await WriteHeaderLine("Transfer-Encoding", "chunked"); + await WriteHeaderLine("Transfer-Encoding", "chunked").ConfigureAwait(false); } foreach (var header in response.Headers) { - await WriteHeaderLine(header.Key, header.Value); + await WriteHeaderLine(header.Key, header.Value).ConfigureAwait(false); } foreach (var cookie in response.Cookies) { - await WriteCookie(cookie.Value); + await WriteCookie(cookie.Value).ConfigureAwait(false); } } @@ -158,13 +155,13 @@ private async ValueTask WriteBody(IResponse response) { using var chunked = new ChunkedStream(OutputStream); - await response.Content.Write(chunked, Configuration.TransferBufferSize); + await response.Content.Write(chunked, Configuration.TransferBufferSize).ConfigureAwait(false); chunked.Finish(); } else { - await response.Content.Write(OutputStream, Configuration.TransferBufferSize); + await response.Content.Write(OutputStream, Configuration.TransferBufferSize).ConfigureAwait(false); } } } @@ -175,10 +172,10 @@ private async ValueTask WriteBody(IResponse response) private async ValueTask WriteHeaderLine(string key, string value) { - await Write(key); - await Write(": "); - await Write(value); - await Write(NL); + await Write(key).ConfigureAwait(false); + await Write(": ").ConfigureAwait(false); + await Write(value).ConfigureAwait(false); + await Write(NL).ConfigureAwait(false); } private ValueTask WriteHeaderLine(string key, DateTime value) @@ -188,34 +185,32 @@ private ValueTask WriteHeaderLine(string key, DateTime value) private async ValueTask WriteCookie(Cookie cookie) { - await Write("Set-Cookie: "); + await Write("Set-Cookie: ").ConfigureAwait(false); - await Write(cookie.Name); - await Write("="); - await Write(cookie.Value); + await Write(cookie.Name).ConfigureAwait(false); + await Write("=").ConfigureAwait(false); + await Write(cookie.Value).ConfigureAwait(false); if (cookie.MaxAge != null) { - await Write("; Max-Age="); - await Write(cookie.MaxAge.Value.ToString()); + await Write("; Max-Age=").ConfigureAwait(false); + await Write(cookie.MaxAge.Value.ToString()).ConfigureAwait(false); } - await Write("; Path=/"); + await Write("; Path=/").ConfigureAwait(false); - await Write(NL); + await Write(NL).ConfigureAwait(false); } private async ValueTask Write(string text) { - var count = HEADER_ENCODING.GetByteCount(text); - - var buffer = POOL.Rent(count); + var buffer = POOL.Rent(text.Length); try { - HEADER_ENCODING.GetBytes(text, 0, text.Length, buffer, 0); + Encoding.ASCII.GetBytes(text, 0, text.Length, buffer, 0); - await OutputStream.WriteAsync(buffer.AsMemory(0, count)); + await OutputStream.WriteAsync(buffer.AsMemory(0, text.Length)).ConfigureAwait(false); } finally {