Skip to content

Commit 2de6c73

Browse files
authored
Process all buffers in the Http2Connection (#13921)
- Change method name to TryReadFrame instead of ReadFrame - Make TryReadFrame slice the incoming buffer
1 parent a6fb55c commit 2de6c73

File tree

4 files changed

+16
-24
lines changed

4 files changed

+16
-24
lines changed

src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -204,27 +204,17 @@ public async Task ProcessRequestsAsync<TContext>(IHttpApplication<TContext> appl
204204
while (_isClosed == 0)
205205
{
206206
var result = await Input.ReadAsync();
207-
var readableBuffer = result.Buffer;
208-
var consumed = readableBuffer.Start;
209-
var examined = readableBuffer.Start;
207+
var buffer = result.Buffer;
210208

211209
// Call UpdateCompletedStreams() prior to frame processing in order to remove any streams that have exceded their drain timeouts.
212210
UpdateCompletedStreams();
213211

214212
try
215213
{
216-
if (!readableBuffer.IsEmpty)
214+
while (Http2FrameReader.TryReadFrame(ref buffer, _incomingFrame, _serverSettings.MaxFrameSize, out var framePayload))
217215
{
218-
if (Http2FrameReader.ReadFrame(readableBuffer, _incomingFrame, _serverSettings.MaxFrameSize, out var framePayload))
219-
{
220-
Log.Http2FrameReceived(ConnectionId, _incomingFrame);
221-
consumed = examined = framePayload.End;
222-
await ProcessFrameAsync(application, framePayload);
223-
}
224-
else
225-
{
226-
examined = readableBuffer.End;
227-
}
216+
Log.Http2FrameReceived(ConnectionId, _incomingFrame);
217+
await ProcessFrameAsync(application, framePayload);
228218
}
229219

230220
if (result.IsCompleted)
@@ -242,7 +232,7 @@ public async Task ProcessRequestsAsync<TContext>(IHttpApplication<TContext> appl
242232
}
243233
finally
244234
{
245-
Input.AdvanceTo(consumed, examined);
235+
Input.AdvanceTo(buffer.Start, buffer.End);
246236

247237
UpdateConnectionState();
248238
}

src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameReader.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,16 @@ internal static class Http2FrameReader
3131

3232
public const int SettingSize = 6; // 2 bytes for the id, 4 bytes for the value.
3333

34-
public static bool ReadFrame(in ReadOnlySequence<byte> readableBuffer, Http2Frame frame, uint maxFrameSize, out ReadOnlySequence<byte> framePayload)
34+
public static bool TryReadFrame(ref ReadOnlySequence<byte> buffer, Http2Frame frame, uint maxFrameSize, out ReadOnlySequence<byte> framePayload)
3535
{
3636
framePayload = ReadOnlySequence<byte>.Empty;
3737

38-
if (readableBuffer.Length < HeaderLength)
38+
if (buffer.Length < HeaderLength)
3939
{
4040
return false;
4141
}
4242

43-
var headerSlice = readableBuffer.Slice(0, HeaderLength);
43+
var headerSlice = buffer.Slice(0, HeaderLength);
4444
var header = headerSlice.ToSpan();
4545

4646
var payloadLength = (int)Bitshifter.ReadUInt24BigEndian(header);
@@ -51,7 +51,7 @@ public static bool ReadFrame(in ReadOnlySequence<byte> readableBuffer, Http2Fram
5151

5252
// Make sure the whole frame is buffered
5353
var frameLength = HeaderLength + payloadLength;
54-
if (readableBuffer.Length < frameLength)
54+
if (buffer.Length < frameLength)
5555
{
5656
return false;
5757
}
@@ -61,10 +61,11 @@ public static bool ReadFrame(in ReadOnlySequence<byte> readableBuffer, Http2Fram
6161
frame.Flags = header[FlagsOffset];
6262
frame.StreamId = (int)Bitshifter.ReadUInt31BigEndian(header.Slice(StreamIdOffset));
6363

64-
var extendedHeaderLength = ReadExtendedFields(frame, readableBuffer);
64+
var extendedHeaderLength = ReadExtendedFields(frame, buffer);
6565

6666
// The remaining payload minus the extra fields
67-
framePayload = readableBuffer.Slice(HeaderLength + extendedHeaderLength, payloadLength - extendedHeaderLength);
67+
framePayload = buffer.Slice(HeaderLength + extendedHeaderLength, payloadLength - extendedHeaderLength);
68+
buffer = buffer.Slice(framePayload.End);
6869

6970
return true;
7071
}

src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,12 +1112,13 @@ internal async Task<Http2FrameWithPayload> ReceiveFrameAsync(uint maxFrameSize =
11121112
var buffer = result.Buffer;
11131113
var consumed = buffer.Start;
11141114
var examined = buffer.Start;
1115+
var copyBuffer = buffer;
11151116

11161117
try
11171118
{
11181119
Assert.True(buffer.Length > 0);
11191120

1120-
if (Http2FrameReader.ReadFrame(buffer, frame, maxFrameSize, out var framePayload))
1121+
if (Http2FrameReader.TryReadFrame(ref buffer, frame, maxFrameSize, out var framePayload))
11211122
{
11221123
consumed = examined = framePayload.End;
11231124
frame.Payload = framePayload.ToArray();
@@ -1135,7 +1136,7 @@ internal async Task<Http2FrameWithPayload> ReceiveFrameAsync(uint maxFrameSize =
11351136
}
11361137
finally
11371138
{
1138-
_bytesReceived += buffer.Slice(buffer.Start, consumed).Length;
1139+
_bytesReceived += copyBuffer.Slice(copyBuffer.Start, consumed).Length;
11391140
_pair.Application.Input.AdvanceTo(consumed, examined);
11401141
}
11411142
}

src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/TlsTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ private async Task<Http2Frame> ReceiveFrameAsync(PipeReader reader)
103103

104104
try
105105
{
106-
if (Http2FrameReader.ReadFrame(buffer, frame, 16_384, out var framePayload))
106+
if (Http2FrameReader.TryReadFrame(ref buffer, frame, 16_384, out var framePayload))
107107
{
108108
consumed = examined = framePayload.End;
109109
return frame;

0 commit comments

Comments
 (0)