Remove the HTTP2 and HTTP3 implementations on browser-wasm. (#52420)
authorEric Erhardt <eric.erhardt@microsoft.com>
Mon, 10 May 2021 19:00:48 +0000 (14:00 -0500)
committerGitHub <noreply@github.com>
Mon, 10 May 2021 19:00:48 +0000 (14:00 -0500)
* Remove the HTTP2 and HTTP3 implementations on browser-wasm.

This allows for HPackEncoder and QPackEncoder to be trimmed in browser wasm.

Contributes to #44534

src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/H2StaticTable.Http2.cs [new file with mode: 0644]
src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/H2StaticTable.cs
src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/H3StaticTable.Http3.cs [new file with mode: 0644]
src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/H3StaticTable.cs
src/libraries/Common/tests/Common.Tests.csproj
src/libraries/System.Net.Http/src/System.Net.Http.csproj
src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeader.Http2And3.cs [new file with mode: 0644]
src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeader.cs
src/libraries/System.Net.Http/src/System/Net/Http/HttpMethod.Http3.cs [new file with mode: 0644]
src/libraries/System.Net.Http/src/System/Net/Http/HttpMethod.cs
src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj

diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/H2StaticTable.Http2.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/H2StaticTable.Http2.cs
new file mode 100644 (file)
index 0000000..71ef901
--- /dev/null
@@ -0,0 +1,100 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Text;
+
+namespace System.Net.Http.HPack
+{
+    internal static partial class H2StaticTable
+    {
+        public static int Count => s_staticDecoderTable.Length;
+
+        public static ref readonly HeaderField Get(int index) => ref s_staticDecoderTable[index];
+
+        public static int GetStatusIndex(int status) =>
+            status switch
+            {
+                200 => 8,
+                204 => 9,
+                206 => 10,
+                304 => 11,
+                400 => 12,
+                404 => 13,
+                500 => 14,
+                _ => throw new ArgumentOutOfRangeException()
+            };
+
+        private static readonly HeaderField[] s_staticDecoderTable = new HeaderField[]
+        {
+            CreateHeaderField(":authority", ""),
+            CreateHeaderField(":method", "GET"),
+            CreateHeaderField(":method", "POST"),
+            CreateHeaderField(":path", "/"),
+            CreateHeaderField(":path", "/index.html"),
+            CreateHeaderField(":scheme", "http"),
+            CreateHeaderField(":scheme", "https"),
+            CreateHeaderField(":status", "200"),
+            CreateHeaderField(":status", "204"),
+            CreateHeaderField(":status", "206"),
+            CreateHeaderField(":status", "304"),
+            CreateHeaderField(":status", "400"),
+            CreateHeaderField(":status", "404"),
+            CreateHeaderField(":status", "500"),
+            CreateHeaderField("accept-charset", ""),
+            CreateHeaderField("accept-encoding", "gzip, deflate"),
+            CreateHeaderField("accept-language", ""),
+            CreateHeaderField("accept-ranges", ""),
+            CreateHeaderField("accept", ""),
+            CreateHeaderField("access-control-allow-origin", ""),
+            CreateHeaderField("age", ""),
+            CreateHeaderField("allow", ""),
+            CreateHeaderField("authorization", ""),
+            CreateHeaderField("cache-control", ""),
+            CreateHeaderField("content-disposition", ""),
+            CreateHeaderField("content-encoding", ""),
+            CreateHeaderField("content-language", ""),
+            CreateHeaderField("content-length", ""),
+            CreateHeaderField("content-location", ""),
+            CreateHeaderField("content-range", ""),
+            CreateHeaderField("content-type", ""),
+            CreateHeaderField("cookie", ""),
+            CreateHeaderField("date", ""),
+            CreateHeaderField("etag", ""),
+            CreateHeaderField("expect", ""),
+            CreateHeaderField("expires", ""),
+            CreateHeaderField("from", ""),
+            CreateHeaderField("host", ""),
+            CreateHeaderField("if-match", ""),
+            CreateHeaderField("if-modified-since", ""),
+            CreateHeaderField("if-none-match", ""),
+            CreateHeaderField("if-range", ""),
+            CreateHeaderField("if-unmodified-since", ""),
+            CreateHeaderField("last-modified", ""),
+            CreateHeaderField("link", ""),
+            CreateHeaderField("location", ""),
+            CreateHeaderField("max-forwards", ""),
+            CreateHeaderField("proxy-authenticate", ""),
+            CreateHeaderField("proxy-authorization", ""),
+            CreateHeaderField("range", ""),
+            CreateHeaderField("referer", ""),
+            CreateHeaderField("refresh", ""),
+            CreateHeaderField("retry-after", ""),
+            CreateHeaderField("server", ""),
+            CreateHeaderField("set-cookie", ""),
+            CreateHeaderField("strict-transport-security", ""),
+            CreateHeaderField("transfer-encoding", ""),
+            CreateHeaderField("user-agent", ""),
+            CreateHeaderField("vary", ""),
+            CreateHeaderField("via", ""),
+            CreateHeaderField("www-authenticate", "")
+        };
+
+        // TODO: The HeaderField constructor will allocate and copy again. We should avoid this.
+        // Tackle as part of header table allocation strategy in general (see note in HeaderField constructor).
+
+        private static HeaderField CreateHeaderField(string name, string value) =>
+            new HeaderField(
+                Encoding.ASCII.GetBytes(name),
+                value.Length != 0 ? Encoding.ASCII.GetBytes(value) : Array.Empty<byte>());
+    }
+}
index 9324c50..926d1fb 100644 (file)
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
-using System.Collections.Generic;
-using System.Text;
-
 namespace System.Net.Http.HPack
 {
-    internal static class H2StaticTable
+    internal static partial class H2StaticTable
     {
-        public static int Count => s_staticDecoderTable.Length;
-
-        public static ref readonly HeaderField Get(int index) => ref s_staticDecoderTable[index];
-
-        public static int GetStatusIndex(int status) =>
-            status switch
-            {
-                200 => 8,
-                204 => 9,
-                206 => 10,
-                304 => 11,
-                400 => 12,
-                404 => 13,
-                500 => 14,
-                _ => throw new ArgumentOutOfRangeException()
-            };
-
-        private static readonly HeaderField[] s_staticDecoderTable = new HeaderField[]
-        {
-            CreateHeaderField(":authority", ""),
-            CreateHeaderField(":method", "GET"),
-            CreateHeaderField(":method", "POST"),
-            CreateHeaderField(":path", "/"),
-            CreateHeaderField(":path", "/index.html"),
-            CreateHeaderField(":scheme", "http"),
-            CreateHeaderField(":scheme", "https"),
-            CreateHeaderField(":status", "200"),
-            CreateHeaderField(":status", "204"),
-            CreateHeaderField(":status", "206"),
-            CreateHeaderField(":status", "304"),
-            CreateHeaderField(":status", "400"),
-            CreateHeaderField(":status", "404"),
-            CreateHeaderField(":status", "500"),
-            CreateHeaderField("accept-charset", ""),
-            CreateHeaderField("accept-encoding", "gzip, deflate"),
-            CreateHeaderField("accept-language", ""),
-            CreateHeaderField("accept-ranges", ""),
-            CreateHeaderField("accept", ""),
-            CreateHeaderField("access-control-allow-origin", ""),
-            CreateHeaderField("age", ""),
-            CreateHeaderField("allow", ""),
-            CreateHeaderField("authorization", ""),
-            CreateHeaderField("cache-control", ""),
-            CreateHeaderField("content-disposition", ""),
-            CreateHeaderField("content-encoding", ""),
-            CreateHeaderField("content-language", ""),
-            CreateHeaderField("content-length", ""),
-            CreateHeaderField("content-location", ""),
-            CreateHeaderField("content-range", ""),
-            CreateHeaderField("content-type", ""),
-            CreateHeaderField("cookie", ""),
-            CreateHeaderField("date", ""),
-            CreateHeaderField("etag", ""),
-            CreateHeaderField("expect", ""),
-            CreateHeaderField("expires", ""),
-            CreateHeaderField("from", ""),
-            CreateHeaderField("host", ""),
-            CreateHeaderField("if-match", ""),
-            CreateHeaderField("if-modified-since", ""),
-            CreateHeaderField("if-none-match", ""),
-            CreateHeaderField("if-range", ""),
-            CreateHeaderField("if-unmodified-since", ""),
-            CreateHeaderField("last-modified", ""),
-            CreateHeaderField("link", ""),
-            CreateHeaderField("location", ""),
-            CreateHeaderField("max-forwards", ""),
-            CreateHeaderField("proxy-authenticate", ""),
-            CreateHeaderField("proxy-authorization", ""),
-            CreateHeaderField("range", ""),
-            CreateHeaderField("referer", ""),
-            CreateHeaderField("refresh", ""),
-            CreateHeaderField("retry-after", ""),
-            CreateHeaderField("server", ""),
-            CreateHeaderField("set-cookie", ""),
-            CreateHeaderField("strict-transport-security", ""),
-            CreateHeaderField("transfer-encoding", ""),
-            CreateHeaderField("user-agent", ""),
-            CreateHeaderField("vary", ""),
-            CreateHeaderField("via", ""),
-            CreateHeaderField("www-authenticate", "")
-        };
-
-        // TODO: The HeaderField constructor will allocate and copy again. We should avoid this.
-        // Tackle as part of header table allocation strategy in general (see note in HeaderField constructor).
-
-        private static HeaderField CreateHeaderField(string name, string value) =>
-            new HeaderField(
-                Encoding.ASCII.GetBytes(name),
-                value.Length != 0 ? Encoding.ASCII.GetBytes(value) : Array.Empty<byte>());
-
         // Values for encoding.
         // Unused values are omitted.
         public const int Authority = 1;
diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/H3StaticTable.Http3.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/H3StaticTable.Http3.cs
new file mode 100644 (file)
index 0000000..efa5f9b
--- /dev/null
@@ -0,0 +1,154 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections.Generic;
+using System.Text;
+
+namespace System.Net.Http.QPack
+{
+    internal static partial class H3StaticTable
+    {
+        private static readonly Dictionary<int, int> s_statusIndex = new Dictionary<int, int>
+        {
+            [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<HttpMethod, int> s_methodIndex = new Dictionary<HttpMethod, int>
+        {
+            // TODO connect is internal to system.net.http
+            [HttpMethod.Delete] = 16,
+            [HttpMethod.Get] = 17,
+            [HttpMethod.Head] = 18,
+            [HttpMethod.Options] = 19,
+            [HttpMethod.Post] = 20,
+            [HttpMethod.Put] = 21,
+        };
+
+        public static int Count => s_staticTable.Length;
+
+        // TODO: just use Dictionary directly to avoid interface dispatch.
+        public static IReadOnlyDictionary<int, int> StatusIndex => s_statusIndex;
+        public static IReadOnlyDictionary<HttpMethod, int> MethodIndex => s_methodIndex;
+
+        public static HeaderField GetHeaderFieldAt(int index) => s_staticTable[index];
+
+        private static readonly HeaderField[] s_staticTable = new HeaderField[]
+        {
+            CreateHeaderField(":authority", ""), // 0
+            CreateHeaderField(":path", "/"), // 1
+            CreateHeaderField("age", "0"), // 2
+            CreateHeaderField("content-disposition", ""),
+            CreateHeaderField("content-length", "0"),
+            CreateHeaderField("cookie", ""),
+            CreateHeaderField("date", ""),
+            CreateHeaderField("etag", ""),
+            CreateHeaderField("if-modified-since", ""),
+            CreateHeaderField("if-none-match", ""),
+            CreateHeaderField("last-modified", ""), // 10
+            CreateHeaderField("link", ""),
+            CreateHeaderField("location", ""),
+            CreateHeaderField("referer", ""),
+            CreateHeaderField("set-cookie", ""),
+            CreateHeaderField(":method", "CONNECT"),
+            CreateHeaderField(":method", "DELETE"),
+            CreateHeaderField(":method", "GET"),
+            CreateHeaderField(":method", "HEAD"),
+            CreateHeaderField(":method", "OPTIONS"),
+            CreateHeaderField(":method", "POST"), // 20
+            CreateHeaderField(":method", "PUT"),
+            CreateHeaderField(":scheme", "http"),
+            CreateHeaderField(":scheme", "https"),
+            CreateHeaderField(":status", "103"),
+            CreateHeaderField(":status", "200"),
+            CreateHeaderField(":status", "304"),
+            CreateHeaderField(":status", "404"),
+            CreateHeaderField(":status", "503"),
+            CreateHeaderField("accept", "*/*"),
+            CreateHeaderField("accept", "application/dns-message"), // 30
+            CreateHeaderField("accept-encoding", "gzip, deflate, br"),
+            CreateHeaderField("accept-ranges", "bytes"),
+            CreateHeaderField("access-control-allow-headers", "cache-control"),
+            CreateHeaderField("access-control-allow-origin", "content-type"),
+            CreateHeaderField("access-control-allow-origin", "*"),
+            CreateHeaderField("cache-control", "max-age=0"),
+            CreateHeaderField("cache-control", "max-age=2592000"),
+            CreateHeaderField("cache-control", "max-age=604800"),
+            CreateHeaderField("cache-control", "no-cache"),
+            CreateHeaderField("cache-control", "no-store"), // 40
+            CreateHeaderField("cache-control", "public, max-age=31536000"),
+            CreateHeaderField("content-encoding", "br"),
+            CreateHeaderField("content-encoding", "gzip"),
+            CreateHeaderField("content-type", "application/dns-message"),
+            CreateHeaderField("content-type", "application/javascript"),
+            CreateHeaderField("content-type", "application/json"),
+            CreateHeaderField("content-type", "application/x-www-form-urlencoded"),
+            CreateHeaderField("content-type", "image/gif"),
+            CreateHeaderField("content-type", "image/jpeg"),
+            CreateHeaderField("content-type", "image/png"), // 50
+            CreateHeaderField("content-type", "text/css"),
+            CreateHeaderField("content-type", "text/html; charset=utf-8"),
+            CreateHeaderField("content-type", "text/plain"),
+            CreateHeaderField("content-type", "text/plain;charset=utf-8"),
+            CreateHeaderField("range", "bytes=0-"),
+            CreateHeaderField("strict-transport-security", "max-age=31536000"),
+            CreateHeaderField("strict-transport-security", "max-age=31536000;includesubdomains"), // TODO confirm spaces here don't matter?
+            CreateHeaderField("strict-transport-security", "max-age=31536000;includesubdomains; preload"),
+            CreateHeaderField("vary", "accept-encoding"),
+            CreateHeaderField("vary", "origin"), // 60
+            CreateHeaderField("x-content-type-options", "nosniff"),
+            CreateHeaderField("x-xss-protection", "1; mode=block"),
+            CreateHeaderField(":status", "100"),
+            CreateHeaderField(":status", "204"),
+            CreateHeaderField(":status", "206"),
+            CreateHeaderField(":status", "302"),
+            CreateHeaderField(":status", "400"),
+            CreateHeaderField(":status", "403"),
+            CreateHeaderField(":status", "421"),
+            CreateHeaderField(":status", "425"), // 70
+            CreateHeaderField(":status", "500"),
+            CreateHeaderField("accept-language", ""),
+            CreateHeaderField("access-control-allow-credentials", "FALSE"),
+            CreateHeaderField("access-control-allow-credentials", "TRUE"),
+            CreateHeaderField("access-control-allow-headers", "*"),
+            CreateHeaderField("access-control-allow-methods", "get"),
+            CreateHeaderField("access-control-allow-methods", "get, post, options"),
+            CreateHeaderField("access-control-allow-methods", "options"),
+            CreateHeaderField("access-control-expose-headers", "content-length"),
+            CreateHeaderField("access-control-request-headers", "content-type"), // 80
+            CreateHeaderField("access-control-request-method", "get"),
+            CreateHeaderField("access-control-request-method", "post"),
+            CreateHeaderField("alt-svc", "clear"),
+            CreateHeaderField("authorization", ""),
+            CreateHeaderField("content-security-policy", "script-src 'none'; object-src 'none'; base-uri 'none'"),
+            CreateHeaderField("early-data", "1"),
+            CreateHeaderField("expect-ct", ""),
+            CreateHeaderField("forwarded", ""),
+            CreateHeaderField("if-range", ""),
+            CreateHeaderField("origin", ""), // 90
+            CreateHeaderField("purpose", "prefetch"),
+            CreateHeaderField("server", ""),
+            CreateHeaderField("timing-allow-origin", "*"),
+            CreateHeaderField("upgrading-insecure-requests", "1"),
+            CreateHeaderField("user-agent", ""),
+            CreateHeaderField("x-forwarded-for", ""),
+            CreateHeaderField("x-frame-options", "deny"),
+            CreateHeaderField("x-frame-options", "sameorigin"),
+        };
+
+        private static HeaderField CreateHeaderField(string name, string value)
+            => new HeaderField(Encoding.ASCII.GetBytes(name), Encoding.ASCII.GetBytes(value));
+    }
+}
index ae60597..145da12 100644 (file)
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
-using System.Collections.Generic;
-using System.Text;
-
 namespace System.Net.Http.QPack
 {
-    internal static class H3StaticTable
+    internal static partial class H3StaticTable
     {
-        private static readonly Dictionary<int, int> s_statusIndex = new Dictionary<int, int>
-        {
-            [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<HttpMethod, int> s_methodIndex = new Dictionary<HttpMethod, int>
-        {
-            // TODO connect is internal to system.net.http
-            [HttpMethod.Delete] = 16,
-            [HttpMethod.Get] = 17,
-            [HttpMethod.Head] = 18,
-            [HttpMethod.Options] = 19,
-            [HttpMethod.Post] = 20,
-            [HttpMethod.Put] = 21,
-        };
-
-        public static int Count => s_staticTable.Length;
-
-        // TODO: just use Dictionary directly to avoid interface dispatch.
-        public static IReadOnlyDictionary<int, int> StatusIndex => s_statusIndex;
-        public static IReadOnlyDictionary<HttpMethod, int> MethodIndex => s_methodIndex;
-
-        public static HeaderField GetHeaderFieldAt(int index) => s_staticTable[index];
-
-        private static readonly HeaderField[] s_staticTable = new HeaderField[]
-        {
-            CreateHeaderField(":authority", ""), // 0
-            CreateHeaderField(":path", "/"), // 1
-            CreateHeaderField("age", "0"), // 2
-            CreateHeaderField("content-disposition", ""),
-            CreateHeaderField("content-length", "0"),
-            CreateHeaderField("cookie", ""),
-            CreateHeaderField("date", ""),
-            CreateHeaderField("etag", ""),
-            CreateHeaderField("if-modified-since", ""),
-            CreateHeaderField("if-none-match", ""),
-            CreateHeaderField("last-modified", ""), // 10
-            CreateHeaderField("link", ""),
-            CreateHeaderField("location", ""),
-            CreateHeaderField("referer", ""),
-            CreateHeaderField("set-cookie", ""),
-            CreateHeaderField(":method", "CONNECT"),
-            CreateHeaderField(":method", "DELETE"),
-            CreateHeaderField(":method", "GET"),
-            CreateHeaderField(":method", "HEAD"),
-            CreateHeaderField(":method", "OPTIONS"),
-            CreateHeaderField(":method", "POST"), // 20
-            CreateHeaderField(":method", "PUT"),
-            CreateHeaderField(":scheme", "http"),
-            CreateHeaderField(":scheme", "https"),
-            CreateHeaderField(":status", "103"),
-            CreateHeaderField(":status", "200"),
-            CreateHeaderField(":status", "304"),
-            CreateHeaderField(":status", "404"),
-            CreateHeaderField(":status", "503"),
-            CreateHeaderField("accept", "*/*"),
-            CreateHeaderField("accept", "application/dns-message"), // 30
-            CreateHeaderField("accept-encoding", "gzip, deflate, br"),
-            CreateHeaderField("accept-ranges", "bytes"),
-            CreateHeaderField("access-control-allow-headers", "cache-control"),
-            CreateHeaderField("access-control-allow-origin", "content-type"),
-            CreateHeaderField("access-control-allow-origin", "*"),
-            CreateHeaderField("cache-control", "max-age=0"),
-            CreateHeaderField("cache-control", "max-age=2592000"),
-            CreateHeaderField("cache-control", "max-age=604800"),
-            CreateHeaderField("cache-control", "no-cache"),
-            CreateHeaderField("cache-control", "no-store"), // 40
-            CreateHeaderField("cache-control", "public, max-age=31536000"),
-            CreateHeaderField("content-encoding", "br"),
-            CreateHeaderField("content-encoding", "gzip"),
-            CreateHeaderField("content-type", "application/dns-message"),
-            CreateHeaderField("content-type", "application/javascript"),
-            CreateHeaderField("content-type", "application/json"),
-            CreateHeaderField("content-type", "application/x-www-form-urlencoded"),
-            CreateHeaderField("content-type", "image/gif"),
-            CreateHeaderField("content-type", "image/jpeg"),
-            CreateHeaderField("content-type", "image/png"), // 50
-            CreateHeaderField("content-type", "text/css"),
-            CreateHeaderField("content-type", "text/html; charset=utf-8"),
-            CreateHeaderField("content-type", "text/plain"),
-            CreateHeaderField("content-type", "text/plain;charset=utf-8"),
-            CreateHeaderField("range", "bytes=0-"),
-            CreateHeaderField("strict-transport-security", "max-age=31536000"),
-            CreateHeaderField("strict-transport-security", "max-age=31536000;includesubdomains"), // TODO confirm spaces here don't matter?
-            CreateHeaderField("strict-transport-security", "max-age=31536000;includesubdomains; preload"),
-            CreateHeaderField("vary", "accept-encoding"),
-            CreateHeaderField("vary", "origin"), // 60
-            CreateHeaderField("x-content-type-options", "nosniff"),
-            CreateHeaderField("x-xss-protection", "1; mode=block"),
-            CreateHeaderField(":status", "100"),
-            CreateHeaderField(":status", "204"),
-            CreateHeaderField(":status", "206"),
-            CreateHeaderField(":status", "302"),
-            CreateHeaderField(":status", "400"),
-            CreateHeaderField(":status", "403"),
-            CreateHeaderField(":status", "421"),
-            CreateHeaderField(":status", "425"), // 70
-            CreateHeaderField(":status", "500"),
-            CreateHeaderField("accept-language", ""),
-            CreateHeaderField("access-control-allow-credentials", "FALSE"),
-            CreateHeaderField("access-control-allow-credentials", "TRUE"),
-            CreateHeaderField("access-control-allow-headers", "*"),
-            CreateHeaderField("access-control-allow-methods", "get"),
-            CreateHeaderField("access-control-allow-methods", "get, post, options"),
-            CreateHeaderField("access-control-allow-methods", "options"),
-            CreateHeaderField("access-control-expose-headers", "content-length"),
-            CreateHeaderField("access-control-request-headers", "content-type"), // 80
-            CreateHeaderField("access-control-request-method", "get"),
-            CreateHeaderField("access-control-request-method", "post"),
-            CreateHeaderField("alt-svc", "clear"),
-            CreateHeaderField("authorization", ""),
-            CreateHeaderField("content-security-policy", "script-src 'none'; object-src 'none'; base-uri 'none'"),
-            CreateHeaderField("early-data", "1"),
-            CreateHeaderField("expect-ct", ""),
-            CreateHeaderField("forwarded", ""),
-            CreateHeaderField("if-range", ""),
-            CreateHeaderField("origin", ""), // 90
-            CreateHeaderField("purpose", "prefetch"),
-            CreateHeaderField("server", ""),
-            CreateHeaderField("timing-allow-origin", "*"),
-            CreateHeaderField("upgrading-insecure-requests", "1"),
-            CreateHeaderField("user-agent", ""),
-            CreateHeaderField("x-forwarded-for", ""),
-            CreateHeaderField("x-frame-options", "deny"),
-            CreateHeaderField("x-frame-options", "sameorigin"),
-        };
-
-        private static HeaderField CreateHeaderField(string name, string value)
-            => new HeaderField(Encoding.ASCII.GetBytes(name), Encoding.ASCII.GetBytes(value));
-
         public const int Authority = 0;
         public const int PathSlash = 1;
         public const int Age0 = 2;
index 8a8a8b0..ba76497 100644 (file)
@@ -62,6 +62,8 @@
              Link="Common\System\Net\Http\aspnetcore\Http2\Hpack\IntegerEncoder.cs" />
     <Compile Include="$(CommonPath)System\Net\Http\aspnetcore\Http2\Hpack\H2StaticTable.cs"
              Link="Common\System\Net\Http\aspnetcore\Http2\Hpack\H2StaticTable.cs" />
+    <Compile Include="$(CommonPath)System\Net\Http\aspnetcore\Http2\Hpack\H2StaticTable.Http2.cs"
+             Link="Common\System\Net\Http\aspnetcore\Http2\Hpack\H2StaticTable.Http2.cs" />
     <Compile Include="$(CommonPath)System\Net\Http\aspnetcore\Http2\Hpack\StatusCodes.cs"
              Link="Common\System\Net\Http\aspnetcore\Http2\Hpack\StatusCodes.cs" />
     <Compile Include="$(CommonPath)System\Text\SimpleRegex.cs"
index 8f495eb..bbe75c7 100644 (file)
              Link="Common\System\Net\ArrayBuffer.cs"/>
     <Compile Include="$(CommonPath)System\Net\MultiArrayBuffer.cs"
              Link="Common\System\Net\MultiArrayBuffer.cs"/>
+    <Compile Include="$(CommonPath)System\Net\Http\aspnetcore\Http2\Hpack\H2StaticTable.cs"
+             Link="Common\System\Net\Http\aspnetcore\Http2\Hpack\H2StaticTable.cs" />
+    <Compile Include="$(CommonPath)System\Net\Http\aspnetcore\Http3\QPack\H3StaticTable.cs"
+             Link="Common\System\Net\Http\aspnetcore\Http3\QPack\H3StaticTable.cs" />
   </ItemGroup>
   <!-- SocketsHttpHandler implementation -->
   <ItemGroup Condition="'$(TargetsBrowser)' != 'true'">
     <Compile Include="System\Net\Http\HttpHandlerDefaults.cs" />
+    <Compile Include="System\Net\Http\HttpMethod.Http3.cs" />
+    <Compile Include="System\Net\Http\Headers\KnownHeader.Http2And3.cs" />
     <Compile Include="System\Net\Http\SocketsHttpHandler\AuthenticationHelper.cs" />
     <Compile Include="System\Net\Http\SocketsHttpHandler\AuthenticationHelper.Digest.cs" />
     <Compile Include="System\Net\Http\SocketsHttpHandler\AuthenticationHelper.NtAuth.cs" />
              Link="Common\System\Text\ValueStringBuilder.cs" />
     <Compile Include="$(CommonPath)Extensions\ValueStopwatch\ValueStopwatch.cs"
              Link="Common\Extensions\ValueStopwatch\ValueStopwatch.cs" />
-  </ItemGroup>
   <!-- Header support -->
-  <ItemGroup>
     <Compile Include="$(CommonPath)System\Net\Http\aspnetcore\IHttpHeadersHandler.cs">
       <Link>Common\System\Net\Http\aspnetcore\IHttpHeadersHandler.cs</Link>
     </Compile>
     <Compile Include="$(CommonPath)System\Net\Http\aspnetcore\Http2\Hpack\IntegerEncoder.cs">
       <Link>Common\System\Net\Http\aspnetcore\Http2\Hpack\IntegerEncoder.cs</Link>
     </Compile>
-    <Compile Include="$(CommonPath)System\Net\Http\aspnetcore\Http2\Hpack\H2StaticTable.cs">
-      <Link>Common\System\Net\Http\aspnetcore\Http2\Hpack\H2StaticTable.cs</Link>
+    <Compile Include="$(CommonPath)System\Net\Http\aspnetcore\Http2\Hpack\H2StaticTable.Http2.cs">
+      <Link>Common\System\Net\Http\aspnetcore\Http2\Hpack\H2StaticTable.Http2.cs</Link>
     </Compile>
     <Compile Include="$(CommonPath)System\Net\Http\aspnetcore\Http2\Hpack\StatusCodes.cs">
       <Link>Common\System\Net\Http\aspnetcore\Http2\Hpack\StatusCodes.cs</Link>
     <Compile Include="$(CommonPath)System\Net\Http\aspnetcore\Http3\QPack\QPackEncodingException.cs">
       <Link>Common\System\Net\Http\aspnetcore\Http3\QPack\QPackEncodingException.cs</Link>
     </Compile>
-    <Compile Include="$(CommonPath)System\Net\Http\aspnetcore\Http3\QPack\H3StaticTable.cs">
-      <Link>Common\System\Net\Http\aspnetcore\Http3\QPack\H3StaticTable.cs</Link>
+    <Compile Include="$(CommonPath)System\Net\Http\aspnetcore\Http3\QPack\H3StaticTable.Http3.cs">
+      <Link>Common\System\Net\Http\aspnetcore\Http3\QPack\H3StaticTable.Http3.cs</Link>
     </Compile>
   </ItemGroup>
   <!-- Linux specific files -->
diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeader.Http2And3.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeader.Http2And3.cs
new file mode 100644 (file)
index 0000000..1a2d689
--- /dev/null
@@ -0,0 +1,27 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Diagnostics.CodeAnalysis;
+using System.Net.Http.HPack;
+
+namespace System.Net.Http.Headers
+{
+    internal sealed partial class KnownHeader
+    {
+        [MemberNotNull(nameof(Http2EncodedName))]
+        [MemberNotNull(nameof(Http3EncodedName))]
+        partial void Initialize(int? http2StaticTableIndex, int? http3StaticTableIndex)
+        {
+            Http2EncodedName = http2StaticTableIndex.HasValue ?
+                HPackEncoder.EncodeLiteralHeaderFieldWithoutIndexingToAllocatedArray(http2StaticTableIndex.GetValueOrDefault()) :
+                HPackEncoder.EncodeLiteralHeaderFieldWithoutIndexingNewNameToAllocatedArray(Name);
+
+            Http3EncodedName = http3StaticTableIndex.HasValue ?
+                QPack.QPackEncoder.EncodeLiteralHeaderFieldWithStaticNameReferenceToArray(http3StaticTableIndex.GetValueOrDefault()) :
+                QPack.QPackEncoder.EncodeLiteralHeaderFieldWithoutNameReferenceToArray(Name);
+        }
+
+        public byte[] Http2EncodedName { get; private set; }
+        public byte[] Http3EncodedName { get; private set; }
+    }
+}
index 29e33d1..0163db0 100644 (file)
@@ -2,12 +2,11 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 using System.Diagnostics;
-using System.Net.Http.HPack;
 using System.Text;
 
 namespace System.Net.Http.Headers
 {
-    internal sealed class KnownHeader
+    internal sealed partial class KnownHeader
     {
         public KnownHeader(string name, int? http2StaticTableIndex = null, int? http3StaticTableIndex = null) :
             this(name, HttpHeaderType.Custom, parser: null, knownValues: null, http2StaticTableIndex, http3StaticTableIndex)
@@ -26,13 +25,7 @@ namespace System.Net.Http.Headers
             Parser = parser;
             KnownValues = knownValues;
 
-            Http2EncodedName = http2StaticTableIndex.HasValue ?
-                HPackEncoder.EncodeLiteralHeaderFieldWithoutIndexingToAllocatedArray(http2StaticTableIndex.GetValueOrDefault()) :
-                HPackEncoder.EncodeLiteralHeaderFieldWithoutIndexingNewNameToAllocatedArray(name);
-
-            Http3EncodedName = http3StaticTableIndex.HasValue ?
-                QPack.QPackEncoder.EncodeLiteralHeaderFieldWithStaticNameReferenceToArray(http3StaticTableIndex.GetValueOrDefault()) :
-                QPack.QPackEncoder.EncodeLiteralHeaderFieldWithoutNameReferenceToArray(name);
+            Initialize(http2StaticTableIndex, http3StaticTableIndex);
 
             var asciiBytesWithColonSpace = new byte[name.Length + 2]; // + 2 for ':' and ' '
             int asciiBytes = Encoding.ASCII.GetBytes(name, asciiBytesWithColonSpace);
@@ -42,6 +35,8 @@ namespace System.Net.Http.Headers
             AsciiBytesWithColonSpace = asciiBytesWithColonSpace;
         }
 
+        partial void Initialize(int? http2StaticTableIndex, int? http3StaticTableIndex);
+
         public string Name { get; }
         public HttpHeaderParser? Parser { get; }
         public HttpHeaderType HeaderType { get; }
@@ -52,7 +47,5 @@ namespace System.Net.Http.Headers
         public string[]? KnownValues { get; }
         public byte[] AsciiBytesWithColonSpace { get; }
         public HeaderDescriptor Descriptor => new HeaderDescriptor(this);
-        public byte[] Http2EncodedName { get; }
-        public byte[] Http3EncodedName { get; }
     }
 }
diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpMethod.Http3.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpMethod.Http3.cs
new file mode 100644 (file)
index 0000000..c8580d1
--- /dev/null
@@ -0,0 +1,29 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Net.Http.QPack;
+using System.Threading;
+
+namespace System.Net.Http
+{
+    public partial class HttpMethod
+    {
+        private byte[]? _http3EncodedBytes;
+
+        internal byte[] Http3EncodedBytes
+        {
+            get
+            {
+                byte[]? http3EncodedBytes = Volatile.Read(ref _http3EncodedBytes);
+                if (http3EncodedBytes is null)
+                {
+                    Volatile.Write(ref _http3EncodedBytes, http3EncodedBytes = _http3Index is int index && index >= 0 ?
+                        QPackEncoder.EncodeStaticIndexedHeaderFieldToArray(index) :
+                        QPackEncoder.EncodeLiteralHeaderFieldWithStaticNameReferenceToArray(H3StaticTable.MethodGet, _method));
+                }
+
+                return http3EncodedBytes;
+            }
+        }
+    }
+}
index 917e769..6fddc9d 100644 (file)
@@ -1,20 +1,17 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
-using System.Collections.Generic;
 using System.Diagnostics;
 using System.Diagnostics.CodeAnalysis;
 using System.Net.Http.QPack;
-using System.Threading;
 
 namespace System.Net.Http
 {
-    public class HttpMethod : IEquatable<HttpMethod>
+    public partial class HttpMethod : IEquatable<HttpMethod>
     {
         private readonly string _method;
         private readonly int? _http3Index;
 
-        private byte[]? _http3EncodedBytes;
         private int _hashcode;
 
         private static readonly HttpMethod s_getMethod = new HttpMethod("GET", http3StaticTableIndex: H3StaticTable.MethodGet);
@@ -80,20 +77,6 @@ namespace System.Net.Http
             get { return _method; }
         }
 
-        internal byte[] Http3EncodedBytes
-        {
-            get {
-                byte[]? http3EncodedBytes = Volatile.Read(ref _http3EncodedBytes);
-                if (http3EncodedBytes is null) {
-                    Volatile.Write (ref _http3EncodedBytes, http3EncodedBytes = _http3Index is int index && index >= 0 ?
-                        QPackEncoder.EncodeStaticIndexedHeaderFieldToArray(index) :
-                        QPackEncoder.EncodeLiteralHeaderFieldWithStaticNameReferenceToArray(H3StaticTable.MethodGet, _method));
-                }
-
-                return http3EncodedBytes;
-            }
-        }
-
         public HttpMethod(string method)
         {
             if (string.IsNullOrEmpty(method))
index 9476e3c..da0a180 100644 (file)
              Link="ProductionCode\System\Net\Http\Headers\KnownHeaders.cs" />
     <Compile Include="..\..\src\System\Net\Http\Headers\KnownHeader.cs"
              Link="ProductionCode\System\Net\Http\Headers\KnownHeader.cs" />
+    <Compile Include="..\..\src\System\Net\Http\Headers\KnownHeader.Http2And3.cs"
+             Link="ProductionCode\System\Net\Http\Headers\KnownHeader.Http2And3.cs" />
     <Compile Include="..\..\src\System\Net\Http\Headers\MediaTypeHeaderParser.cs"
              Link="ProductionCode\System\Net\Http\Headers\MediaTypeHeaderParser.cs" />
     <Compile Include="..\..\src\System\Net\Http\Headers\MediaTypeHeaderValue.cs"
              Link="Common\System\Net\Http\aspnetcore\Http2\Hpack\IntegerEncoder.cs" />
     <Compile Include="$(CommonPath)System\Net\Http\aspnetcore\Http2\Hpack\H2StaticTable.cs"
              Link="Common\System\Net\Http\aspnetcore\Http2\Hpack\H2StaticTable.cs" />
+    <Compile Include="$(CommonPath)System\Net\Http\aspnetcore\Http2\Hpack\H2StaticTable.Http2.cs"
+             Link="Common\System\Net\Http\aspnetcore\Http2\Hpack\H2StaticTable.Http2.cs" />
     <Compile Include="$(CommonPath)System\Net\Http\aspnetcore\Http2\Hpack\StatusCodes.cs"
              Link="Common\System\Net\Http\aspnetcore\Http2\Hpack\StatusCodes.cs" />
     <Compile Include="$(CommonPath)System\Net\Http\aspnetcore\Http3\QPack\H3StaticTable.cs"
              Link="Common\System\Net\Http\aspnetcore\Http3\QPack\H3StaticTable.cs" />
+    <Compile Include="$(CommonPath)System\Net\Http\aspnetcore\Http3\QPack\H3StaticTable.Http3.cs"
+             Link="Common\System\Net\Http\aspnetcore\Http3\QPack\H3StaticTable.Http3.cs" />
     <Compile Include="$(CommonPath)System\Net\Http\aspnetcore\Http3\QPack\HeaderField.cs"
              Link="Common\System\Net\Http\aspnetcore\Http3\QPack\HeaderField.cs" />
     <Compile Include="$(CommonPath)System\Net\Http\aspnetcore\Http3\QPack\QPackEncoder.cs"