Skip to content

Commit bfb1666

Browse files
committed
Move shareable code out of runtime.
1 parent 6269162 commit bfb1666

File tree

6 files changed

+188
-166
lines changed

6 files changed

+188
-166
lines changed

src/Servers/Kestrel/Core/src/Microsoft.AspNetCore.Server.Kestrel.Core.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<Description>Core components of ASP.NET Core Kestrel cross-platform web server.</Description>
@@ -19,6 +19,7 @@
1919
<Compile Include="$(SharedSourceRoot)runtime\*.cs" Link="Shared\runtime\%(Filename)%(Extension)" />
2020
<Compile Include="$(SharedSourceRoot)runtime\Http2\**\*.cs" Link="Shared\runtime\Http2\%(Filename)%(Extension)" />
2121
<Compile Include="$(SharedSourceRoot)runtime\Http3\**\*.cs" Link="Shared\runtime\Http3\%(Filename)%(Extension)" />
22+
<Compile Include="$(SharedSourceRoot)Hpack\**\*.cs" Link="Shared\Hpack\%(Filename)%(Extension)" />
2223
<Compile Include="$(SharedSourceRoot)ServerInfrastructure\**\*.cs" LinkBase="Shared\" />
2324
<Compile Include="$(RepoRoot)src\Shared\TaskToApm.cs" Link="Internal\TaskToApm.cs" />
2425
</ItemGroup>

src/Shared/runtime/Http2/Hpack/HPackEncoder.Dynamic.cs renamed to src/Shared/Hpack/HPackEncoder.Dynamic.cs

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
// See the LICENSE file in the project root for more information.
44

55
#nullable enable
6-
using System.Collections.Generic;
76
using System.Diagnostics;
87

98
namespace System.Net.Http.HPack
@@ -41,6 +40,8 @@ public void UpdateMaxHeaderTableSize(uint maxHeaderTableSize)
4140
if (_maxHeaderTableSize != maxHeaderTableSize)
4241
{
4342
_maxHeaderTableSize = maxHeaderTableSize;
43+
44+
// Dynamic table size update will be written next HEADERS frame
4445
_pendingTableSizeUpdate = true;
4546

4647
// Check capacity and remove entries that exceed the new capacity
@@ -50,6 +51,7 @@ public void UpdateMaxHeaderTableSize(uint maxHeaderTableSize)
5051

5152
public bool EnsureDynamicTableSizeUpdate(Span<byte> buffer, out int length)
5253
{
54+
// Check if there is a table size update that should be encoded
5355
if (_pendingTableSizeUpdate)
5456
{
5557
bool success = EncodeDynamicTableSizeUpdate((int)_maxHeaderTableSize, buffer, out length);
@@ -68,7 +70,7 @@ public bool EncodeHeader(Span<byte> buffer, int staticTableIndex, HeaderEncoding
6870
// Never index sensitive value.
6971
if (encodingHint == HeaderEncodingHint.NeverIndex)
7072
{
71-
var index = ResolveDynamicTableIndex(staticTableIndex, name);
73+
int index = ResolveDynamicTableIndex(staticTableIndex, name);
7274

7375
return index == -1
7476
? EncodeLiteralHeaderFieldNeverIndexingNewName(name, value, buffer, out bytesWritten)
@@ -87,7 +89,7 @@ public bool EncodeHeader(Span<byte> buffer, int staticTableIndex, HeaderEncoding
8789
// Don't attempt to add dynamic header as all existing dynamic headers will be removed.
8890
if (HeaderField.GetLength(name.Length, value.Length) > _maxHeaderTableSize)
8991
{
90-
var index = ResolveDynamicTableIndex(staticTableIndex, name);
92+
int index = ResolveDynamicTableIndex(staticTableIndex, name);
9193

9294
return index == -1
9395
? EncodeLiteralHeaderFieldWithoutIndexingNewName(name, value, buffer, out bytesWritten)
@@ -110,20 +112,20 @@ private int ResolveDynamicTableIndex(int staticTableIndex, string name)
110112

111113
private bool EncodeDynamicHeader(Span<byte> buffer, int staticTableIndex, string name, string value, out int bytesWritten)
112114
{
113-
var headerField = GetEntry(name, value);
115+
EncoderHeaderEntry? headerField = GetEntry(name, value);
114116
if (headerField != null)
115117
{
116118
// Already exists in dynamic table. Write index.
117-
var index = CalculateDynamicTableIndex(headerField.Index);
119+
int index = CalculateDynamicTableIndex(headerField.Index);
118120
return EncodeIndexedHeaderField(index, buffer, out bytesWritten);
119121
}
120122
else
121123
{
122124
// Doesn't exist in dynamic table. Add new entry to dynamic table.
123-
var headerSize = (uint)HeaderField.GetLength(name.Length, value.Length);
125+
uint headerSize = (uint)HeaderField.GetLength(name.Length, value.Length);
124126

125-
var index = ResolveDynamicTableIndex(staticTableIndex, name);
126-
var success = index == -1
127+
int index = ResolveDynamicTableIndex(staticTableIndex, name);
128+
bool success = index == -1
127129
? EncodeLiteralHeaderFieldIndexingNewName(name, value, buffer, out bytesWritten)
128130
: EncodeLiteralHeaderFieldIndexing(index, value, buffer, out bytesWritten);
129131

@@ -147,7 +149,7 @@ private void EnsureCapacity(uint headerSize)
147149

148150
while (_maxHeaderTableSize - _headerTableSize < headerSize)
149151
{
150-
var removed = RemoveHeaderEntry();
152+
EncoderHeaderEntry? removed = RemoveHeaderEntry();
151153
Debug.Assert(removed != null);
152154

153155
// Removed entries are tracked to be reused.
@@ -161,9 +163,9 @@ private void EnsureCapacity(uint headerSize)
161163
{
162164
return null;
163165
}
164-
var hash = name.GetHashCode();
165-
var bucketIndex = CalculateBucketIndex(hash);
166-
for (var e = _headerBuckets[bucketIndex]; e != null; e = e.Next)
166+
int hash = name.GetHashCode();
167+
int bucketIndex = CalculateBucketIndex(hash);
168+
for (EncoderHeaderEntry? e = _headerBuckets[bucketIndex]; e != null; e = e.Next)
167169
{
168170
// We've already looked up entries based on a hash of the name.
169171
// Compare value before name as it is more likely to be different.
@@ -183,9 +185,9 @@ private int CalculateDynamicTableIndex(string name)
183185
{
184186
return -1;
185187
}
186-
var hash = name.GetHashCode();
187-
var bucketIndex = CalculateBucketIndex(hash);
188-
for (var e = _headerBuckets[bucketIndex]; e != null; e = e.Next)
188+
int hash = name.GetHashCode();
189+
int bucketIndex = CalculateBucketIndex(hash);
190+
for (EncoderHeaderEntry? e = _headerBuckets[bucketIndex]; e != null; e = e.Next)
189191
{
190192
if (e.Hash == hash && string.Equals(name, e.Name, StringComparison.Ordinal))
191193
{
@@ -205,11 +207,11 @@ private void AddHeaderEntry(string name, string value, uint headerSize)
205207
Debug.Assert(headerSize <= _maxHeaderTableSize, "Header is bigger than dynamic table size.");
206208
Debug.Assert(headerSize <= _maxHeaderTableSize - _headerTableSize, "Not enough room in dynamic table.");
207209

208-
var hash = name.GetHashCode();
209-
var bucketIndex = CalculateBucketIndex(hash);
210-
var oldEntry = _headerBuckets[bucketIndex];
210+
int hash = name.GetHashCode();
211+
int bucketIndex = CalculateBucketIndex(hash);
212+
EncoderHeaderEntry? oldEntry = _headerBuckets[bucketIndex];
211213
// Attempt to reuse removed entry
212-
var newEntry = PopRemovedEntry() ?? new EncoderHeaderEntry();
214+
EncoderHeaderEntry? newEntry = PopRemovedEntry() ?? new EncoderHeaderEntry();
213215
newEntry.Initialize(hash, name, value, Head.Before.Index - 1, oldEntry);
214216
_headerBuckets[bucketIndex] = newEntry;
215217
newEntry.AddBefore(Head);
@@ -229,7 +231,7 @@ private void PushRemovedEntry(EncoderHeaderEntry removed)
229231
{
230232
if (_removed != null)
231233
{
232-
var removed = _removed;
234+
EncoderHeaderEntry? removed = _removed;
233235
_removed = _removed.Next;
234236
return removed;
235237
}
@@ -246,11 +248,11 @@ private void PushRemovedEntry(EncoderHeaderEntry removed)
246248
{
247249
return null;
248250
}
249-
var eldest = Head.After;
250-
var hash = eldest.Hash;
251-
var bucketIndex = CalculateBucketIndex(hash);
252-
var prev = _headerBuckets[bucketIndex];
253-
var e = prev;
251+
EncoderHeaderEntry? eldest = Head.After;
252+
int hash = eldest.Hash;
253+
int bucketIndex = CalculateBucketIndex(hash);
254+
EncoderHeaderEntry? prev = _headerBuckets[bucketIndex];
255+
EncoderHeaderEntry? e = prev;
254256
while (e != null)
255257
{
256258
EncoderHeaderEntry next = e.Next;
@@ -280,6 +282,10 @@ private int CalculateBucketIndex(int hash)
280282
}
281283
}
282284

285+
/// <summary>
286+
/// Hint for how the header should be encoded as HPack. This value can be overriden.
287+
/// For example, a header that is larger than the dynamic table won't be indexed.
288+
/// </summary>
283289
internal enum HeaderEncodingHint
284290
{
285291
Index,

src/Shared/Hpack/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
HPack dynamic compression. These files are kept separate to help avoid ASP.NET Core dependencies being added to them.
2+
3+
Runtime currently doesn't implement HPack dynamic compression. These files will move into runtime shareable code in the future when support is added to runtime.

src/Shared/Hpack/StatusCodes.cs

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
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+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Globalization;
6+
using System.Text;
7+
8+
namespace System.Net.Http.HPack
9+
{
10+
internal static partial class StatusCodes
11+
{
12+
public static string ToStatusString(int statusCode)
13+
{
14+
switch (statusCode)
15+
{
16+
case (int)HttpStatusCode.Continue:
17+
return "100";
18+
case (int)HttpStatusCode.SwitchingProtocols:
19+
return "101";
20+
case (int)HttpStatusCode.Processing:
21+
return "102";
22+
23+
case (int)HttpStatusCode.OK:
24+
return "200";
25+
case (int)HttpStatusCode.Created:
26+
return "201";
27+
case (int)HttpStatusCode.Accepted:
28+
return "202";
29+
case (int)HttpStatusCode.NonAuthoritativeInformation:
30+
return "203";
31+
case (int)HttpStatusCode.NoContent:
32+
return "204";
33+
case (int)HttpStatusCode.ResetContent:
34+
return "205";
35+
case (int)HttpStatusCode.PartialContent:
36+
return "206";
37+
case (int)HttpStatusCode.MultiStatus:
38+
return "207";
39+
case (int)HttpStatusCode.AlreadyReported:
40+
return "208";
41+
case (int)HttpStatusCode.IMUsed:
42+
return "226";
43+
44+
case (int)HttpStatusCode.MultipleChoices:
45+
return "300";
46+
case (int)HttpStatusCode.MovedPermanently:
47+
return "301";
48+
case (int)HttpStatusCode.Found:
49+
return "302";
50+
case (int)HttpStatusCode.SeeOther:
51+
return "303";
52+
case (int)HttpStatusCode.NotModified:
53+
return "304";
54+
case (int)HttpStatusCode.UseProxy:
55+
return "305";
56+
case (int)HttpStatusCode.Unused:
57+
return "306";
58+
case (int)HttpStatusCode.TemporaryRedirect:
59+
return "307";
60+
case (int)HttpStatusCode.PermanentRedirect:
61+
return "308";
62+
63+
case (int)HttpStatusCode.BadRequest:
64+
return "400";
65+
case (int)HttpStatusCode.Unauthorized:
66+
return "401";
67+
case (int)HttpStatusCode.PaymentRequired:
68+
return "402";
69+
case (int)HttpStatusCode.Forbidden:
70+
return "403";
71+
case (int)HttpStatusCode.NotFound:
72+
return "404";
73+
case (int)HttpStatusCode.MethodNotAllowed:
74+
return "405";
75+
case (int)HttpStatusCode.NotAcceptable:
76+
return "406";
77+
case (int)HttpStatusCode.ProxyAuthenticationRequired:
78+
return "407";
79+
case (int)HttpStatusCode.RequestTimeout:
80+
return "408";
81+
case (int)HttpStatusCode.Conflict:
82+
return "409";
83+
case (int)HttpStatusCode.Gone:
84+
return "410";
85+
case (int)HttpStatusCode.LengthRequired:
86+
return "411";
87+
case (int)HttpStatusCode.PreconditionFailed:
88+
return "412";
89+
case (int)HttpStatusCode.RequestEntityTooLarge:
90+
return "413";
91+
case (int)HttpStatusCode.RequestUriTooLong:
92+
return "414";
93+
case (int)HttpStatusCode.UnsupportedMediaType:
94+
return "415";
95+
case (int)HttpStatusCode.RequestedRangeNotSatisfiable:
96+
return "416";
97+
case (int)HttpStatusCode.ExpectationFailed:
98+
return "417";
99+
case (int)418:
100+
return "418";
101+
case (int)419:
102+
return "419";
103+
case (int)HttpStatusCode.MisdirectedRequest:
104+
return "421";
105+
case (int)HttpStatusCode.UnprocessableEntity:
106+
return "422";
107+
case (int)HttpStatusCode.Locked:
108+
return "423";
109+
case (int)HttpStatusCode.FailedDependency:
110+
return "424";
111+
case (int)HttpStatusCode.UpgradeRequired:
112+
return "426";
113+
case (int)HttpStatusCode.PreconditionRequired:
114+
return "428";
115+
case (int)HttpStatusCode.TooManyRequests:
116+
return "429";
117+
case (int)HttpStatusCode.RequestHeaderFieldsTooLarge:
118+
return "431";
119+
case (int)HttpStatusCode.UnavailableForLegalReasons:
120+
return "451";
121+
122+
case (int)HttpStatusCode.InternalServerError:
123+
return "500";
124+
case (int)HttpStatusCode.NotImplemented:
125+
return "501";
126+
case (int)HttpStatusCode.BadGateway:
127+
return "502";
128+
case (int)HttpStatusCode.ServiceUnavailable:
129+
return "503";
130+
case (int)HttpStatusCode.GatewayTimeout:
131+
return "504";
132+
case (int)HttpStatusCode.HttpVersionNotSupported:
133+
return "505";
134+
case (int)HttpStatusCode.VariantAlsoNegotiates:
135+
return "506";
136+
case (int)HttpStatusCode.InsufficientStorage:
137+
return "507";
138+
case (int)HttpStatusCode.LoopDetected:
139+
return "508";
140+
case (int)HttpStatusCode.NotExtended:
141+
return "510";
142+
case (int)HttpStatusCode.NetworkAuthenticationRequired:
143+
return "511";
144+
145+
default:
146+
return statusCode.ToString(CultureInfo.InvariantCulture);
147+
148+
}
149+
}
150+
}
151+
}

0 commit comments

Comments
 (0)