private Task EndResponse() { if (!HasStarted) { WriteBeginResponseHeaders(); } if (_autoChunk) { WriteEndResponse(); return(_outputFormatter.FlushAsync()); } return(Task.CompletedTask); }
public Task HandleAsync(Line message) { // Echo back to the caller _formatter.Append(message.Data); return(_formatter.FlushAsync()); }
public async Task ProcessAllRequests() { Reset(); while (true) { var buffer = await _input.ReadAsync(); try { if (buffer.IsEmpty && _input.Reading.IsCompleted) { // We're done with this connection return; } Console.WriteLine($"Read: {buffer.Length} bytes"); Console.WriteLine(BitConverter.ToString(buffer.ToArray())); Console.WriteLine(buffer.GetAsciiString()); var result = _parser.ParseRequest(ref buffer); Console.WriteLine($"Result: {result}"); switch (result) { case HttpRequestParser.ParseResult.Incomplete: if (_input.Reading.IsCompleted) { // Didn't get the whole request and the connection ended throw new EndOfStreamException(); } // Need more data continue; case HttpRequestParser.ParseResult.Complete: // Done break; case HttpRequestParser.ParseResult.BadRequest: // TODO: Don't throw here; throw new Exception(); default: break; } } catch (Exception) { StatusCode = 400; await EndResponse(); return; } finally { _input.Advance(buffer.Start, buffer.End); } var context = _application.CreateContext(this); try { if (!_isHttp2 && RequestHeaders.ContainsKey("Upgrade") && TryUpgradeToHttp2()) { _outputFormatter.Write(_http2SwitchBytes); _isHttp2 = true; /* The first HTTP/2 frame sent by the server MUST be a server connection preface (Section 3.5) consisting of a SETTINGS frame (Section 6.5). */ _outputFormatter.Write(_emptySettingsFrame); await _outputFormatter.FlushAsync(); } await _application.ProcessRequestAsync(context); } catch (Exception ex) { StatusCode = 500; _application.DisposeContext(context, ex); } finally { await EndResponse(); } if (!KeepAlive) { break; } Reset(); } }