Skip to content

Commit 4217441

Browse files
authored
Include ContentLength when enumerating HttpHeaders (#54760)
* Include ContentLength when enumerating HttpHeaders ...even if no bits are set. Fixes #54557 * Remove now-unnecessary using * Remove code that should have been deleted * Add MethodImplOptions.AggressiveInlining * Remove now-unnecessary using
1 parent f808b66 commit 4217441

File tree

6 files changed

+60
-8
lines changed

6 files changed

+60
-8
lines changed

src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8670,6 +8670,16 @@ public bool MoveNext()
86708670
return true;
86718671
}
86728672
}
8673+
8674+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
8675+
private static int GetNext(long bits, bool hasContentLength)
8676+
{
8677+
return bits != 0
8678+
? BitOperations.TrailingZeroCount(bits)
8679+
: hasContentLength
8680+
? 49
8681+
: -1;
8682+
}
86738683
}
86748684
}
86758685

@@ -15496,6 +15506,16 @@ public bool MoveNext()
1549615506
return true;
1549715507
}
1549815508
}
15509+
15510+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
15511+
private static int GetNext(long bits, bool hasContentLength)
15512+
{
15513+
return bits != 0
15514+
? BitOperations.TrailingZeroCount(bits)
15515+
: hasContentLength
15516+
? 38
15517+
: -1;
15518+
}
1549915519
}
1550015520
}
1550115521

@@ -17609,4 +17629,4 @@ public bool MoveNext()
1760917629
}
1761017630
}
1761117631
}
17612-
}
17632+
}

src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestHeaders.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System.Buffers.Text;
55
using System.Collections;
66
using System.Globalization;
7-
using System.Numerics;
87
using System.Runtime.CompilerServices;
98
using System.Text;
109
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
@@ -244,7 +243,7 @@ internal Enumerator(HttpRequestHeaders collection)
244243
{
245244
_collection = collection;
246245
_currentBits = collection._bits;
247-
_next = _currentBits != 0 ? BitOperations.TrailingZeroCount(_currentBits) : -1;
246+
_next = GetNext(_currentBits, collection.ContentLength.HasValue);
248247
_current = default;
249248
_hasUnknown = collection.MaybeUnknown != null;
250249
_unknownEnumerator = _hasUnknown
@@ -263,7 +262,7 @@ public readonly void Dispose()
263262
public void Reset()
264263
{
265264
_currentBits = _collection._bits;
266-
_next = _currentBits != 0 ? BitOperations.TrailingZeroCount(_currentBits) : -1;
265+
_next = GetNext(_currentBits, _collection.ContentLength.HasValue);
267266
}
268267
}
269268
}

src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseHeaders.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Collections;
66
using System.Diagnostics.CodeAnalysis;
77
using System.IO.Pipelines;
8-
using System.Numerics;
98
using System.Runtime.CompilerServices;
109
using System.Text;
1110
using Microsoft.Extensions.Primitives;
@@ -152,7 +151,7 @@ internal Enumerator(HttpResponseHeaders collection)
152151
{
153152
_collection = collection;
154153
_currentBits = collection._bits;
155-
_next = _currentBits != 0 ? BitOperations.TrailingZeroCount(_currentBits) : -1;
154+
_next = GetNext(_currentBits, collection.ContentLength.HasValue);
156155
_current = default;
157156
_currentKnownType = default;
158157
_hasUnknown = collection.MaybeUnknown != null;
@@ -174,7 +173,7 @@ public readonly void Dispose()
174173
public void Reset()
175174
{
176175
_currentBits = _collection._bits;
177-
_next = _currentBits != 0 ? BitOperations.TrailingZeroCount(_currentBits) : -1;
176+
_next = GetNext(_currentBits, _collection.ContentLength.HasValue);
178177
}
179178
}
180179
}

src/Servers/Kestrel/Core/test/HttpRequestHeadersTests.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,18 @@ public void MultiValueReuseEmptyAfterReset(bool reuseValue, string headerName)
831831
Assert.Equal(0, count);
832832
}
833833

834+
[Fact]
835+
public void ContentLengthEnumerableWithoutOtherKnownHeader()
836+
{
837+
IHeaderDictionary headers = new HttpRequestHeaders();
838+
headers["content-length"] = "1024";
839+
Assert.Single(headers);
840+
headers["unknown"] = "value";
841+
Assert.Equal(2, headers.Count()); // NB: enumerable count, not property
842+
headers["host"] = "myhost";
843+
Assert.Equal(3, headers.Count()); // NB: enumerable count, not property
844+
}
845+
834846
private static (string PrevHeaderValue, string NextHeaderValue) GetHeaderValues(HttpRequestHeaders headers, string prevName, string nextName, string prevValue, string nextValue)
835847
{
836848
headers.Reset();

src/Servers/Kestrel/Core/test/HttpResponseHeadersTests.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,18 @@ public void ContentLengthValueClearedWhenHeadersCleared()
392392
Assert.Null(headers.ContentLength);
393393
}
394394

395+
[Fact]
396+
public void ContentLengthEnumerableWithoutOtherKnownHeader()
397+
{
398+
IHeaderDictionary headers = new HttpResponseHeaders();
399+
headers["content-length"] = "1024";
400+
Assert.Single(headers);
401+
headers["unknown"] = "value";
402+
Assert.Equal(2, headers.Count()); // NB: enumerable count, not property
403+
headers["host"] = "myhost";
404+
Assert.Equal(3, headers.Count()); // NB: enumerable count, not property
405+
}
406+
395407
private static long ParseLong(string value)
396408
{
397409
return long.Parse(value, NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite, CultureInfo.InvariantCulture);

src/Servers/Kestrel/shared/KnownHeaders.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1428,7 +1428,17 @@ public bool MoveNext()
14281428
{(!loop.ClassName.Contains("Trailers") ? $@"_next = _collection._contentLength.HasValue ? {loop.Headers.Length - 1} : -1;" : "_next = -1;")}
14291429
return true;
14301430
}}
1431-
}}
1431+
}}{(loop.ClassName.Contains("Trailers") ? "" : $@"
1432+
1433+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
1434+
private static int GetNext(long bits, bool hasContentLength)
1435+
{{
1436+
return bits != 0
1437+
? BitOperations.TrailingZeroCount(bits)
1438+
: hasContentLength
1439+
? {loop.Headers.Length - 1}
1440+
: -1;
1441+
}}")}
14321442
}}
14331443
}}
14341444
")}}}";

0 commit comments

Comments
 (0)