public async Task ProcessAllRequests() { Reset(); while (true) { var buffer = await _input.ReadAsync(); var consumed = buffer.Start; bool needMoreData = true; try { if (buffer.IsEmpty && _input.Completion.IsCompleted) { // We're done with this connection return; } if (_state == ParsingState.StartLine) { // Find \n var delim = buffer.IndexOf(ref CommonVectors.LF); if (delim == ReadCursor.NotFound) { continue; } // Grab the entire start line var startLine = buffer.Slice(0, delim); // Move the buffer to the rest buffer = buffer.Slice(delim).Slice(1); delim = startLine.IndexOf(ref CommonVectors.Space); if (delim == ReadCursor.NotFound) { throw new Exception(); } var method = startLine.Slice(0, delim); Method = method.Preserve(); // Skip ' ' startLine = startLine.Slice(delim).Slice(1); delim = startLine.IndexOf(ref CommonVectors.Space); if (delim == ReadCursor.NotFound) { throw new Exception(); } var path = startLine.Slice(0, delim); Path = path.Preserve(); // Skip ' ' startLine = startLine.Slice(delim).Slice(1); delim = startLine.IndexOf(ref CommonVectors.CR); if (delim == ReadCursor.NotFound) { throw new Exception(); } var httpVersion = startLine.Slice(0, delim); HttpVersion = httpVersion.Preserve(); _state = ParsingState.Headers; consumed = startLine.End; } // Parse headers // key: value\r\n while (!buffer.IsEmpty) { var ch = buffer.Peek(); if (ch == -1) { break; } if (ch == '\r') { // Check for final CRLF. buffer = buffer.Slice(1); ch = buffer.Peek(); buffer = buffer.Slice(1); if (ch == -1) { break; } else if (ch == '\n') { consumed = buffer.Start; needMoreData = false; break; } // Headers don't end in CRLF line. throw new Exception(); } var headerName = default(ReadableBuffer); var headerValue = default(ReadableBuffer); // End of the header // \n var delim = buffer.IndexOf(ref CommonVectors.LF); if (delim == ReadCursor.NotFound) { break; } var headerPair = buffer.Slice(0, delim); buffer = buffer.Slice(delim).Slice(1); // : delim = headerPair.IndexOf(ref CommonVectors.Colon); if (delim == ReadCursor.NotFound) { throw new Exception(); } headerName = headerPair.Slice(0, delim).TrimStart(); headerPair = headerPair.Slice(delim).Slice(1); // \r delim = headerPair.IndexOf(ref CommonVectors.CR); if (delim == ReadCursor.NotFound) { // Bad request throw new Exception(); } headerValue = headerPair.Slice(0, delim).TrimStart(); RequestHeaders.SetHeader(ref headerName, ref headerValue); // Move the consumed consumed = buffer.Start; } } catch (Exception) { StatusCode = 400; await EndResponse(); return; } finally { buffer.Consumed(consumed); } if (needMoreData) { continue; } var context = _application.CreateContext(this); try { await _application.ProcessRequestAsync(context); } catch (Exception ex) { StatusCode = 500; _application.DisposeContext(context, ex); } finally { await EndResponse(); } if (!KeepAlive) { break; } Reset(); } }