| | | 1 | | // Licensed to the .NET Foundation under one or more agreements. |
| | | 2 | | // The .NET Foundation licenses this file to you under the MIT license. |
| | | 3 | | |
| | | 4 | | using System.Text; |
| | | 5 | | |
| | | 6 | | namespace System.Net.Http.HPack |
| | | 7 | | { |
| | | 8 | | internal static partial class H2StaticTable |
| | | 9 | | { |
| | 0 | 10 | | public static int Count => s_staticDecoderTable.Length; |
| | | 11 | | |
| | 0 | 12 | | public static ref readonly HeaderField Get(int index) => ref s_staticDecoderTable[index]; |
| | | 13 | | |
| | | 14 | | public static bool TryGetStatusIndex(int status, out int index) |
| | | 15 | | { |
| | | 16 | | index = status switch |
| | | 17 | | { |
| | | 18 | | 200 => 8, |
| | | 19 | | 204 => 9, |
| | | 20 | | 206 => 10, |
| | | 21 | | 304 => 11, |
| | | 22 | | 400 => 12, |
| | | 23 | | 404 => 13, |
| | | 24 | | 500 => 14, |
| | | 25 | | _ => -1 |
| | | 26 | | }; |
| | | 27 | | |
| | | 28 | | return index != -1; |
| | | 29 | | } |
| | | 30 | | |
| | 0 | 31 | | private static readonly HeaderField[] s_staticDecoderTable = new HeaderField[] |
| | 0 | 32 | | { |
| | 0 | 33 | | CreateHeaderField(1, ":authority", ""), |
| | 0 | 34 | | CreateHeaderField(2, ":method", "GET"), |
| | 0 | 35 | | CreateHeaderField(3, ":method", "POST"), |
| | 0 | 36 | | CreateHeaderField(4, ":path", "/"), |
| | 0 | 37 | | CreateHeaderField(5, ":path", "/index.html"), |
| | 0 | 38 | | CreateHeaderField(6, ":scheme", "http"), |
| | 0 | 39 | | CreateHeaderField(7, ":scheme", "https"), |
| | 0 | 40 | | CreateHeaderField(8, ":status", "200"), |
| | 0 | 41 | | CreateHeaderField(9, ":status", "204"), |
| | 0 | 42 | | CreateHeaderField(10, ":status", "206"), |
| | 0 | 43 | | CreateHeaderField(11, ":status", "304"), |
| | 0 | 44 | | CreateHeaderField(12, ":status", "400"), |
| | 0 | 45 | | CreateHeaderField(13, ":status", "404"), |
| | 0 | 46 | | CreateHeaderField(14, ":status", "500"), |
| | 0 | 47 | | CreateHeaderField(15, "accept-charset", ""), |
| | 0 | 48 | | CreateHeaderField(16, "accept-encoding", "gzip, deflate"), |
| | 0 | 49 | | CreateHeaderField(17, "accept-language", ""), |
| | 0 | 50 | | CreateHeaderField(18, "accept-ranges", ""), |
| | 0 | 51 | | CreateHeaderField(19, "accept", ""), |
| | 0 | 52 | | CreateHeaderField(20, "access-control-allow-origin", ""), |
| | 0 | 53 | | CreateHeaderField(21, "age", ""), |
| | 0 | 54 | | CreateHeaderField(22, "allow", ""), |
| | 0 | 55 | | CreateHeaderField(23, "authorization", ""), |
| | 0 | 56 | | CreateHeaderField(24, "cache-control", ""), |
| | 0 | 57 | | CreateHeaderField(25, "content-disposition", ""), |
| | 0 | 58 | | CreateHeaderField(26, "content-encoding", ""), |
| | 0 | 59 | | CreateHeaderField(27, "content-language", ""), |
| | 0 | 60 | | CreateHeaderField(28, "content-length", ""), |
| | 0 | 61 | | CreateHeaderField(29, "content-location", ""), |
| | 0 | 62 | | CreateHeaderField(30, "content-range", ""), |
| | 0 | 63 | | CreateHeaderField(31, "content-type", ""), |
| | 0 | 64 | | CreateHeaderField(32, "cookie", ""), |
| | 0 | 65 | | CreateHeaderField(33, "date", ""), |
| | 0 | 66 | | CreateHeaderField(34, "etag", ""), |
| | 0 | 67 | | CreateHeaderField(35, "expect", ""), |
| | 0 | 68 | | CreateHeaderField(36, "expires", ""), |
| | 0 | 69 | | CreateHeaderField(37, "from", ""), |
| | 0 | 70 | | CreateHeaderField(38, "host", ""), |
| | 0 | 71 | | CreateHeaderField(39, "if-match", ""), |
| | 0 | 72 | | CreateHeaderField(40, "if-modified-since", ""), |
| | 0 | 73 | | CreateHeaderField(41, "if-none-match", ""), |
| | 0 | 74 | | CreateHeaderField(42, "if-range", ""), |
| | 0 | 75 | | CreateHeaderField(43, "if-unmodified-since", ""), |
| | 0 | 76 | | CreateHeaderField(44, "last-modified", ""), |
| | 0 | 77 | | CreateHeaderField(45, "link", ""), |
| | 0 | 78 | | CreateHeaderField(46, "location", ""), |
| | 0 | 79 | | CreateHeaderField(47, "max-forwards", ""), |
| | 0 | 80 | | CreateHeaderField(48, "proxy-authenticate", ""), |
| | 0 | 81 | | CreateHeaderField(49, "proxy-authorization", ""), |
| | 0 | 82 | | CreateHeaderField(50, "range", ""), |
| | 0 | 83 | | CreateHeaderField(51, "referer", ""), |
| | 0 | 84 | | CreateHeaderField(52, "refresh", ""), |
| | 0 | 85 | | CreateHeaderField(53, "retry-after", ""), |
| | 0 | 86 | | CreateHeaderField(54, "server", ""), |
| | 0 | 87 | | CreateHeaderField(55, "set-cookie", ""), |
| | 0 | 88 | | CreateHeaderField(56, "strict-transport-security", ""), |
| | 0 | 89 | | CreateHeaderField(57, "transfer-encoding", ""), |
| | 0 | 90 | | CreateHeaderField(58, "user-agent", ""), |
| | 0 | 91 | | CreateHeaderField(59, "vary", ""), |
| | 0 | 92 | | CreateHeaderField(60, "via", ""), |
| | 0 | 93 | | CreateHeaderField(61, "www-authenticate", "") |
| | 0 | 94 | | }; |
| | | 95 | | |
| | | 96 | | // TODO: The HeaderField constructor will allocate and copy again. We should avoid this. |
| | | 97 | | // Tackle as part of header table allocation strategy in general (see note in HeaderField constructor). |
| | | 98 | | |
| | | 99 | | private static HeaderField CreateHeaderField(int staticTableIndex, string name, string value) => |
| | 0 | 100 | | new HeaderField( |
| | 0 | 101 | | staticTableIndex, |
| | 0 | 102 | | Encoding.ASCII.GetBytes(name), |
| | 0 | 103 | | value.Length != 0 ? Encoding.ASCII.GetBytes(value) : Array.Empty<byte>()); |
| | | 104 | | } |
| | | 105 | | } |