|
@@ -41,42 +41,11 @@ public partial class BenchmarkApplication : IHttpConnection
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private bool ParseHttpRequest(ref SequenceReader<byte> reader, bool isCompleted)
|
|
|
- {
|
|
|
- var state = _state;
|
|
|
-
|
|
|
- if (state == State.StartLine)
|
|
|
- {
|
|
|
- if (Parser.ParseRequestLine(new ParsingAdapter(this), ref reader))
|
|
|
- {
|
|
|
- state = State.Headers;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (state == State.Headers)
|
|
|
- {
|
|
|
- var success = Parser.ParseHeaders(new ParsingAdapter(this), ref reader);
|
|
|
-
|
|
|
- if (success)
|
|
|
- {
|
|
|
- state = State.Body;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (state != State.Body && isCompleted)
|
|
|
- {
|
|
|
- ThrowUnexpectedEndOfData();
|
|
|
- }
|
|
|
-
|
|
|
- _state = state;
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
private async Task ProcessRequestsAsync()
|
|
|
{
|
|
|
while (true)
|
|
|
{
|
|
|
- var readResult = await Reader.ReadAsync(default);
|
|
|
+ var readResult = await Reader.ReadAsync();
|
|
|
var buffer = readResult.Buffer;
|
|
|
var isCompleted = readResult.IsCompleted;
|
|
|
|
|
@@ -85,35 +54,23 @@ public partial class BenchmarkApplication : IHttpConnection
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if (!HandleRequests(buffer, isCompleted))
|
|
|
+ if (!HandleRequests(ref buffer, isCompleted))
|
|
|
{
|
|
|
- await ProcessRequestAsync();
|
|
|
+ await HandleRequestAsync(buffer);
|
|
|
}
|
|
|
-
|
|
|
- await Writer.FlushAsync(default);
|
|
|
+
|
|
|
+ await Writer.FlushAsync();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private bool HandleRequests(in ReadOnlySequence<byte> buffer, bool isCompleted)
|
|
|
+ private bool HandleRequests(ref ReadOnlySequence<byte> buffer, bool isCompleted)
|
|
|
{
|
|
|
var reader = new SequenceReader<byte>(buffer);
|
|
|
- var hasWriter = false;
|
|
|
- BufferWriter<WriterAdapter> writer = default;
|
|
|
+ var writer = GetWriter(Writer, sizeHint: 160 * 16); // 160*16 is for Plaintext, for Json 160 would be enough
|
|
|
|
|
|
while (true)
|
|
|
{
|
|
|
- if (!ParseHttpRequest(ref reader, isCompleted))
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- // Only create the local writer if the request is Plaintext or Json
|
|
|
-
|
|
|
- if (!hasWriter)
|
|
|
- {
|
|
|
- hasWriter = true;
|
|
|
- writer = GetWriter(Writer, sizeHint: 160 * 16); // 160*16 is for Plaintext, for Json 160 would be enough
|
|
|
- }
|
|
|
+ ParseHttpRequest(ref reader, ref buffer, isCompleted);
|
|
|
|
|
|
if (_state == State.Body)
|
|
|
{
|
|
@@ -136,12 +93,104 @@ public partial class BenchmarkApplication : IHttpConnection
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- if (hasWriter)
|
|
|
- {
|
|
|
- writer.Commit();
|
|
|
+ writer.Commit();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ private async Task HandleRequestAsync(ReadOnlySequence<byte> buffer)
|
|
|
+ {
|
|
|
+ if (_state == State.Body)
|
|
|
+ {
|
|
|
+ await ProcessRequestAsync();
|
|
|
+
|
|
|
+ _state = State.StartLine;
|
|
|
}
|
|
|
|
|
|
- return true;
|
|
|
+ // No more input or incomplete data, Advance the Reader
|
|
|
+ Reader.AdvanceTo(buffer.Start, buffer.End);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void ParseHttpRequest(ref ReadOnlySequence<byte> buffer, bool isCompleted)
|
|
|
+ {
|
|
|
+ var reader = new SequenceReader<byte>(buffer);
|
|
|
+ var state = _state;
|
|
|
+
|
|
|
+ if (state == State.StartLine)
|
|
|
+ {
|
|
|
+ if (Parser.ParseRequestLine(new ParsingAdapter(this), ref reader))
|
|
|
+ {
|
|
|
+ state = State.Headers;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (state == State.Headers)
|
|
|
+ {
|
|
|
+ var success = Parser.ParseHeaders(new ParsingAdapter(this), ref reader);
|
|
|
+
|
|
|
+ if (success)
|
|
|
+ {
|
|
|
+ state = State.Body;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (state != State.Body && isCompleted)
|
|
|
+ {
|
|
|
+ ThrowUnexpectedEndOfData();
|
|
|
+ }
|
|
|
+
|
|
|
+ _state = state;
|
|
|
+
|
|
|
+ if (state == State.Body)
|
|
|
+ {
|
|
|
+ // Complete request read, consumed and examined are the same (length 0)
|
|
|
+ buffer = buffer.Slice(reader.Position, 0);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // In-complete request read, consumed is current position and examined is the remaining.
|
|
|
+ buffer = buffer.Slice(reader.Position);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void ParseHttpRequest(ref SequenceReader<byte> reader, ref ReadOnlySequence<byte> buffer, bool isCompleted)
|
|
|
+ {
|
|
|
+ var state = _state;
|
|
|
+
|
|
|
+ if (state == State.StartLine)
|
|
|
+ {
|
|
|
+ if (Parser.ParseRequestLine(new ParsingAdapter(this), ref reader))
|
|
|
+ {
|
|
|
+ state = State.Headers;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (state == State.Headers)
|
|
|
+ {
|
|
|
+ var success = Parser.ParseHeaders(new ParsingAdapter(this), ref reader);
|
|
|
+
|
|
|
+ if (success)
|
|
|
+ {
|
|
|
+ state = State.Body;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (state != State.Body && isCompleted)
|
|
|
+ {
|
|
|
+ ThrowUnexpectedEndOfData();
|
|
|
+ }
|
|
|
+
|
|
|
+ _state = state;
|
|
|
+
|
|
|
+ if (state == State.Body)
|
|
|
+ {
|
|
|
+ // Complete request read, consumed and examined are the same (length 0)
|
|
|
+ buffer = buffer.Slice(reader.Position, 0);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // In-complete request read, consumed is current position and examined is the remaining.
|
|
|
+ buffer = buffer.Slice(reader.Position);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private static HtmlEncoder CreateHtmlEncoder()
|