diff --git a/src/Shared/runtime/Http2/Hpack/H2StaticTable.Http2.cs b/src/Shared/runtime/Http2/Hpack/H2StaticTable.Http2.cs index a4db64ab5862..fdb619a3ff7a 100644 --- a/src/Shared/runtime/Http2/Hpack/H2StaticTable.Http2.cs +++ b/src/Shared/runtime/Http2/Hpack/H2StaticTable.Http2.cs @@ -11,9 +11,8 @@ internal static partial class H2StaticTable public static ref readonly HeaderField Get(int index) => ref s_staticDecoderTable[index]; - public static bool TryGetStatusIndex(int status, out int index) - { - index = status switch + public static int GetStatusIndex(int status) => + status switch { 200 => 8, 204 => 9, @@ -22,12 +21,9 @@ public static bool TryGetStatusIndex(int status, out int index) 400 => 12, 404 => 13, 500 => 14, - _ => -1 + _ => throw new ArgumentOutOfRangeException(nameof(status)) }; - return index != -1; - } - private static readonly HeaderField[] s_staticDecoderTable = new HeaderField[] { CreateHeaderField(":authority", ""), diff --git a/src/Shared/runtime/Http2/Hpack/HPackEncoder.cs b/src/Shared/runtime/Http2/Hpack/HPackEncoder.cs index 780e7433c32a..a7f33d2c9298 100644 --- a/src/Shared/runtime/Http2/Hpack/HPackEncoder.cs +++ b/src/Shared/runtime/Http2/Hpack/HPackEncoder.cs @@ -44,31 +44,36 @@ public static bool EncodeIndexedHeaderField(int index, Span destination, o public static bool EncodeStatusHeader(int statusCode, Span destination, out int bytesWritten) { // Bytes written depend on whether the status code value maps directly to an index - if (H2StaticTable.TryGetStatusIndex(statusCode, out var index)) + switch (statusCode) { - // Status codes which exist in the HTTP/2 StaticTable. - return EncodeIndexedHeaderField(index, destination, out bytesWritten); - } - else - { - // If the status code doesn't have a static index then we need to include the full value. - // Write a status index and then the number bytes as a string literal. - if (!EncodeLiteralHeaderFieldWithoutIndexing(H2StaticTable.Status200, destination, out var nameLength)) - { - bytesWritten = 0; - return false; - } + case 200: + case 204: + case 206: + case 304: + case 400: + case 404: + case 500: + // Status codes which exist in the HTTP/2 StaticTable. + return EncodeIndexedHeaderField(H2StaticTable.GetStatusIndex(statusCode), destination, out bytesWritten); + default: + // If the status code doesn't have a static index then we need to include the full value. + // Write a status index and then the number bytes as a string literal. + if (!EncodeLiteralHeaderFieldWithoutIndexing(H2StaticTable.Status200, destination, out var nameLength)) + { + bytesWritten = 0; + return false; + } - var statusBytes = StatusCodes.ToStatusBytes(statusCode); + var statusBytes = StatusCodes.ToStatusBytes(statusCode); - if (!EncodeStringLiteral(statusBytes, destination.Slice(nameLength), out var valueLength)) - { - bytesWritten = 0; - return false; - } + if (!EncodeStringLiteral(statusBytes, destination.Slice(nameLength), out var valueLength)) + { + bytesWritten = 0; + return false; + } - bytesWritten = nameLength + valueLength; - return true; + bytesWritten = nameLength + valueLength; + return true; } } diff --git a/src/Shared/runtime/Http3/QPack/H3StaticTable.Http3.cs b/src/Shared/runtime/Http3/QPack/H3StaticTable.Http3.cs index 8e812b15c64b..ebb9142752ef 100644 --- a/src/Shared/runtime/Http3/QPack/H3StaticTable.Http3.cs +++ b/src/Shared/runtime/Http3/QPack/H3StaticTable.Http3.cs @@ -8,6 +8,24 @@ namespace System.Net.Http.QPack { internal static partial class H3StaticTable { + private static readonly Dictionary s_statusIndex = new Dictionary + { + [103] = 24, + [200] = 25, + [304] = 26, + [404] = 27, + [503] = 28, + [100] = 63, + [204] = 64, + [206] = 65, + [302] = 66, + [400] = 67, + [403] = 68, + [421] = 69, + [425] = 70, + [500] = 71, + }; + private static readonly Dictionary s_methodIndex = new Dictionary { // TODO connect is internal to system.net.http @@ -19,33 +37,10 @@ internal static partial class H3StaticTable [HttpMethod.Put] = 21, }; - public static bool TryGetStatusIndex(int status, out int index) - { - index = status switch - { - 103 => 24, - 200 => 25, - 304 => 26, - 404 => 27, - 503 => 28, - 100 => 63, - 204 => 64, - 206 => 65, - 302 => 66, - 400 => 67, - 403 => 68, - 421 => 69, - 425 => 70, - 500 => 71, - _ => -1 - }; - - return index != -1; - } - public static int Count => s_staticTable.Length; // TODO: just use Dictionary directly to avoid interface dispatch. + public static IReadOnlyDictionary StatusIndex => s_statusIndex; public static IReadOnlyDictionary MethodIndex => s_methodIndex; public static HeaderField GetHeaderFieldAt(int index) => s_staticTable[index];