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 void Remove(StringCI key) { if (ContainsKey(key)) { _keys.Remove(key); _entries.Remove(key); } }
public bool ContainsKey(StringCI key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } return(_entries.ContainsKey(key)); }
public string GetFirst(StringCI key) { if (!_entries.ContainsKey(key) || _entries[key].Count == 0) { throw new InvalidOperationException($"Key does not exist {key}"); } return(_entries[key][0]); }
public IReadOnlyList <string> Get(StringCI key, bool getAsCopy) { if (!_entries.ContainsKey(key)) { throw new InvalidOperationException($"Key does not exist {key}"); } if (getAsCopy) { return(_entries[key].ToList()); } return(_entries[key]); }
public void Add(StringCI key, string value) { if (value == null) { throw new ArgumentNullException(nameof(value)); } if (ContainsKey(key)) { _entries[key].Add(value); } else { _entries[key] = new List <string>(); _entries[key].Add(value); _keys.Add(key); } }
public string this[StringCI key] { get { var values = Get(key, false); if (values.Count == 0) { throw new IndexOutOfRangeException(nameof(key)); } return(values[0]); } set { if (ContainsKey(key)) { Remove(key); } Add(key, value); } }
/// <summary> /// Based on the request header and keep-alive service state, /// should we keep the current connection alive? /// </summary> bool ShoudKeepAlive() { if (false == _keepAliveService.CanRegister(_connection)) { return(false); } // https://tools.ietf.org/html/rfc7230#section-6 // If the "close" connection option is present, the connection will // not persist after the current response; else, if (_request.Header.ContainsKey(HttpKeys.Connection) && StringCI.Compare(_request.Header[HttpKeys.Connection], HttpKeys.CloseValue)) { return(false); } // If the received protocol is HTTP/1.1 (or later), the connection // will persist after the current response; else, if (_request.Header.Protocol == HttpProtocol.Http11) { return(true); } // If the received protocol is HTTP / 1.0, the "keep-alive" connection // option is present, the recipient is not a proxy, and the recipient // wishes to honor the HTTP/ 1.0 "keep-alive" mechanism, the // connection will persist after the current response; otherwise, if (_request.Header.Protocol == HttpProtocol.Http10 && _request.Header.ContainsKey(HttpKeys.Connection) && StringCI.Compare(_request.Header[HttpKeys.Connection], HttpKeys.KeepAliveValue)) { return(true); } // Else, the connection will close after the current response. return(false); }
public virtual void Remove(StringCI key) { _entries.Remove(key); InvalidCachedPlainText(); }
public virtual void Add(StringCI key, string value) { _entries.Add(key, value); InvalidCachedPlainText(); }
public IReadOnlyList <string> Get(StringCI key, bool getAsCopy) => _entries.Get(key, getAsCopy);
public string GetFirst(StringCI key) => _entries.GetFirst(key);
public bool ContainsKey(StringCI key) => _entries.ContainsKey(key);