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:
parent
a6fb55c405
commit
2de6c732d1
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue