Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.

Commit 89a37da

Browse files
author
John Luo
committed
Implement HeaderTableSize for HTTP/2
1 parent 6bcb46b commit 89a37da

File tree

4 files changed

+41
-2
lines changed

4 files changed

+41
-2
lines changed

src/Kestrel.Core/Http2Limits.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
1111
public class Http2Limits
1212
{
1313
private int _maxStreamsPerConnection = 100;
14+
private int _headerTableSize = MaxAllowedHeaderTableSize;
1415
private int _maxFrameSize = MinAllowedMaxFrameSize;
1516

1617
// These are limits defined by the RFC https://tools.ietf.org/html/rfc7540#section-4.2
18+
public const int MaxAllowedHeaderTableSize = 4096;
1719
public const int MinAllowedMaxFrameSize = 16 * 1024;
1820
public const int MaxAllowedMaxFrameSize = 16 * 1024 * 1024 - 1;
1921

@@ -37,6 +39,26 @@ public int MaxStreamsPerConnection
3739
}
3840
}
3941

42+
/// <summary>
43+
/// Limits the size of the header compression table, in octets, the HPACK decoder on the server can use.
44+
/// <para>
45+
/// Defaults to 4096
46+
/// </para>
47+
/// </summary>
48+
public int HeaderTableSize
49+
{
50+
get => _headerTableSize;
51+
set
52+
{
53+
if (value <= 0 || value > MaxAllowedHeaderTableSize)
54+
{
55+
throw new ArgumentOutOfRangeException(nameof(value), value, CoreStrings.FormatArgumentOutOfRange(0, MaxAllowedHeaderTableSize));
56+
}
57+
58+
_headerTableSize = value;
59+
}
60+
}
61+
4062
/// <summary>
4163
/// Indicates the size of the largest frame payload that is allowed to be received, in octets. The size must be between 2^14 and 2^24-1.
4264
/// <para>

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,10 @@ public Http2Connection(Http2ConnectionContext context)
8787
{
8888
_context = context;
8989
_frameWriter = new Http2FrameWriter(context.Transport.Output, context.ConnectionContext, _outputFlowControl, this, context.ConnectionId, context.ServiceContext.Log);
90-
_hpackDecoder = new HPackDecoder((int)_serverSettings.HeaderTableSize);
9190
_serverSettings.MaxConcurrentStreams = (uint)context.ServiceContext.ServerOptions.Limits.Http2.MaxStreamsPerConnection;
9291
_serverSettings.MaxFrameSize = (uint)context.ServiceContext.ServerOptions.Limits.Http2.MaxFrameSize;
92+
_serverSettings.HeaderTableSize = (uint)context.ServiceContext.ServerOptions.Limits.Http2.HeaderTableSize;
93+
_hpackDecoder = new HPackDecoder((int)_serverSettings.HeaderTableSize);
9394
_incomingFrame = new Http2Frame(_serverSettings.MaxFrameSize);
9495
}
9596

test/Kestrel.Core.Tests/KestrelServerLimitsTests.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,22 @@ public void Http2MaxFrameSizeDefault()
318318
[InlineData(1 << 14 - 1)]
319319
[InlineData(1 << 24)]
320320
[InlineData(-1)]
321-
public void Http2MaxFrameSizeInvalide(int value)
321+
public void Http2MaxFrameSizeInvalid(int value)
322+
{
323+
var ex = Assert.Throws<ArgumentOutOfRangeException>(() => new KestrelServerLimits().Http2.MaxFrameSize = value);
324+
Assert.Contains("A value between", ex.Message);
325+
}
326+
327+
[Fact]
328+
public void Http2HeaderTableSizeDefault()
329+
{
330+
Assert.Equal(4096, new KestrelServerLimits().Http2.HeaderTableSize);
331+
}
332+
333+
[Theory]
334+
[InlineData(4097)]
335+
[InlineData(-1)]
336+
public void Http2HeaderTableSizeInvalid(int value)
322337
{
323338
var ex = Assert.Throws<ArgumentOutOfRangeException>(() => new KestrelServerLimits().Http2.MaxFrameSize = value);
324339
Assert.Contains("A value between", ex.Message);

test/Kestrel.InMemory.FunctionalTests/Http2/Http2ConnectionTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2100,6 +2100,7 @@ await WaitForConnectionErrorAsync<Http2ConnectionErrorException>(
21002100
[InlineData(Http2SettingsParameter.SETTINGS_MAX_FRAME_SIZE, 16 * 1024 - 1, Http2ErrorCode.PROTOCOL_ERROR)]
21012101
[InlineData(Http2SettingsParameter.SETTINGS_MAX_FRAME_SIZE, 16 * 1024 * 1024, Http2ErrorCode.PROTOCOL_ERROR)]
21022102
[InlineData(Http2SettingsParameter.SETTINGS_MAX_FRAME_SIZE, uint.MaxValue, Http2ErrorCode.PROTOCOL_ERROR)]
2103+
[InlineData(Http2SettingsParameter.SETTINGS_HEADER_TABLE_SIZE, 4097, Http2ErrorCode.PROTOCOL_ERROR)]
21032104
public async Task SETTINGS_Received_InvalidParameterValue_ConnectionError(Http2SettingsParameter parameter, uint value, Http2ErrorCode expectedErrorCode)
21042105
{
21052106
await InitializeConnectionAsync(_noopApplication);

0 commit comments

Comments
 (0)