Process all buffers in the Http2Connection (#13921)

- Change method name to TryReadFrame instead of ReadFrame
- Make TryReadFrame slice the incoming buffer
This commit is contained in:
David Fowler 2019-09-16 18:26:45 -07:00 committed by GitHub
parent a6fb55c405
commit 2de6c732d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 16 additions and 24 deletions

View File

@ -204,27 +204,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
while (_isClosed == 0)
{
var result = await Input.ReadAsync();
var readableBuffer = result.Buffer;
var consumed = readableBuffer.Start;
var examined = readableBuffer.Start;
var buffer = result.Buffer;
// Call UpdateCompletedStreams() prior to frame processing in order to remove any streams that have exceded their drain timeouts.
UpdateCompletedStreams();
try
{
if (!readableBuffer.IsEmpty)
while (Http2FrameReader.TryReadFrame(ref buffer, _incomingFrame, _serverSettings.MaxFrameSize, out var framePayload))
{
if (Http2FrameReader.ReadFrame(readableBuffer, _incomingFrame, _serverSettings.MaxFrameSize, out var framePayload))
{
Log.Http2FrameReceived(ConnectionId, _incomingFrame);
consumed = examined = framePayload.End;
await ProcessFrameAsync(application, framePayload);
}
else
{
examined = readableBuffer.End;
}
Log.Http2FrameReceived(ConnectionId, _incomingFrame);
await ProcessFrameAsync(application, framePayload);
}
if (result.IsCompleted)
@ -242,7 +232,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
}
finally
{
Input.AdvanceTo(consumed, examined);
Input.AdvanceTo(buffer.Start, buffer.End);
UpdateConnectionState();
}

View File

@ -31,16 +31,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
public const int SettingSize = 6; // 2 bytes for the id, 4 bytes for the value.
public static bool ReadFrame(in ReadOnlySequence<byte> readableBuffer, Http2Frame frame, uint maxFrameSize, out ReadOnlySequence<byte> framePayload)
public static bool TryReadFrame(ref ReadOnlySequence<byte> buffer, Http2Frame frame, uint maxFrameSize, out ReadOnlySequence<byte> framePayload)
{
framePayload = ReadOnlySequence<byte>.Empty;
if (readableBuffer.Length < HeaderLength)
if (buffer.Length < HeaderLength)
{
return false;
}
var headerSlice = readableBuffer.Slice(0, HeaderLength);
var headerSlice = buffer.Slice(0, HeaderLength);
var header = headerSlice.ToSpan();
var payloadLength = (int)Bitshifter.ReadUInt24BigEndian(header);
@ -51,7 +51,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
// Make sure the whole frame is buffered
var frameLength = HeaderLength + payloadLength;
if (readableBuffer.Length < frameLength)
if (buffer.Length < frameLength)
{
return false;
}
@ -61,10 +61,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
frame.Flags = header[FlagsOffset];
frame.StreamId = (int)Bitshifter.ReadUInt31BigEndian(header.Slice(StreamIdOffset));
var extendedHeaderLength = ReadExtendedFields(frame, readableBuffer);
var extendedHeaderLength = ReadExtendedFields(frame, buffer);
// The remaining payload minus the extra fields
framePayload = readableBuffer.Slice(HeaderLength + extendedHeaderLength, payloadLength - extendedHeaderLength);
framePayload = buffer.Slice(HeaderLength + extendedHeaderLength, payloadLength - extendedHeaderLength);
buffer = buffer.Slice(framePayload.End);
return true;
}

View File

@ -1112,12 +1112,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
var buffer = result.Buffer;
var consumed = buffer.Start;
var examined = buffer.Start;
var copyBuffer = buffer;
try
{
Assert.True(buffer.Length > 0);
if (Http2FrameReader.ReadFrame(buffer, frame, maxFrameSize, out var framePayload))
if (Http2FrameReader.TryReadFrame(ref buffer, frame, maxFrameSize, out var framePayload))
{
consumed = examined = framePayload.End;
frame.Payload = framePayload.ToArray();
@ -1135,7 +1136,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
}
finally
{
_bytesReceived += buffer.Slice(buffer.Start, consumed).Length;
_bytesReceived += copyBuffer.Slice(copyBuffer.Start, consumed).Length;
_pair.Application.Input.AdvanceTo(consumed, examined);
}
}

View File

@ -103,7 +103,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests.Http2
try
{
if (Http2FrameReader.ReadFrame(buffer, frame, 16_384, out var framePayload))
if (Http2FrameReader.TryReadFrame(ref buffer, frame, 16_384, out var framePayload))
{
consumed = examined = framePayload.End;
return frame;