public async Task ExecuteAsync() { try { // Read the request header, minimum required prior processing the request; await _request.WaitForHttpHeaderAsync(); _logger.Debug($"{_request.Header.Method} {_request.Header.Uri}"); // Got the header. // Very likely that we just woke up from a keep-alive sleep, // Abort the watch dog to avoid being killed. if (_keepAliveService.IsRegistered(_connection)) { _keepAliveService.Deregister(_connection); } // Process the request-response SetDefaultResponseHeaders(); await ProcessRequestResponseAsync(); // Before continuing to the next HTTP session in the connection loop, // the response header + body of this message must be completely written // (or abort the connection), // otherwise it causes unexpected behaviour for the other HTTP client. await _response.Body.CompleteAsync(); // If we promised the client to keep alive, do it. if (!StringCI.Compare( _response.Header[HttpKeys.Connection], HttpKeys.CloseValue)) { _keepAliveService.Register(_connection); } } catch (HttpBadRequestException ex) { // Caused by malformed HTTP request message // sent by the client; // We'll return with an 400 BadRequest _logger.Warn(ex.Message); await TryRespondErrorAsync( 400, $"<h1>Bad Request</h1><br />{ex.ToString()}"); } catch (TcpException) { throw; } catch (Exception ex) { // Unexpected error caused by us, // We'll return with an internal error _logger.Error(ex); await TryRespondErrorAsync( 500, $"<h1>Internal Server Error</h1><br />{ex.ToString()}"); // Let the connection loop handle this exception, // probably by closing the connection. throw; } }
public async Task ExecuteAsync() { var debugKeepAliveCount = 0; // HTTP connection loop: // We can have multiple HTTP request-responses for each // TCP connection, we'll keep accepting HTTP requests // out of the underlying connection until it is no longer kept alive. try { do { if (debugKeepAliveCount > 0) { _logger.Debug($"Connection kept alive {debugKeepAliveCount} time(s)"); } // Create new http session var httpSession = _httpSessionFactory.Create(); try { // Execute it await httpSession.ExecuteAsync(); } finally { _httpSessionFactory.Destroy(httpSession); debugKeepAliveCount++; } } // Continue, as long as the connection remains in // the keep-alive service. while(_keepAliveService.IsRegistered(_connection)); } finally { EnsureSessionIsRemovedFromKeepAliveService(); } }