Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Sanchez <1175054+carlossanlop@users.noreply.github.com>2022-05-11 05:12:57 +0300
committerGitHub <noreply@github.com>2022-05-11 05:12:57 +0300
commit4aadfea70082ae23e6c54a449268341e9429434e (patch)
tree40ca76ac8df97a2ee75519a1ec821957007449f0
parentf3cd2f06521e3793da7667e05a629ecb0e2dadf5 (diff)
parent6a984143635bde23e728abaaccbde52f5ea8fa3e (diff)
Merge pull request #69152 from vseanreesermsft/internal-merge-5.0-2022-05-10-1213v5.0.18release/5.0
Merging internal commits for release/5.0
-rw-r--r--src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs6
-rw-r--r--src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs8
-rw-r--r--src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs54
3 files changed, 62 insertions, 6 deletions
diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs
index b9ccbcef76d..06b541f7662 100644
--- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs
+++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs
@@ -21,8 +21,6 @@ namespace System.Net.Http
/// infinite chunk length is sent. This value is arbitrary and can be changed as needed.
/// </remarks>
private const int MaxChunkBytesAllowed = 16 * 1024;
- /// <summary>How long a trailing header can be. This value is arbitrary and can be changed as needed.</summary>
- private const int MaxTrailingHeaderLength = 16 * 1024;
/// <summary>The number of bytes remaining in the chunk.</summary>
private ulong _chunkBytesRemaining;
/// <summary>The current state of the parsing state machine for the chunked response.</summary>
@@ -297,6 +295,9 @@ namespace System.Net.Http
else
{
_state = ParsingState.ConsumeTrailers;
+ // Apply the MaxResponseHeadersLength limit to all trailing headers.
+ // The limit is applied to regular response headers and trailing headers separately.
+ _connection._allowedReadLineBytes = _connection.MaxResponseHeadersLength;
goto case ParsingState.ConsumeTrailers;
}
@@ -343,7 +344,6 @@ namespace System.Net.Http
while (true)
{
- _connection._allowedReadLineBytes = MaxTrailingHeaderLength;
if (!_connection.TryReadNextLine(out currentLine))
{
break;
diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs
index c8bfc919e9c..4c862f03f8a 100644
--- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs
+++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs
@@ -204,6 +204,8 @@ namespace System.Net.Http
public HttpConnectionKind Kind => _pool.Kind;
+ private int MaxResponseHeadersLength => (int)Math.Min(int.MaxValue, _pool.Settings._maxResponseHeadersLength * 1024L);
+
private int ReadBufferSize => _readBuffer.Length;
private ReadOnlyMemory<byte> RemainingBuffer => new ReadOnlyMemory<byte>(_readBuffer, _readOffset, _readLength - _readOffset);
@@ -497,7 +499,7 @@ namespace System.Net.Http
}
// Start to read response.
- _allowedReadLineBytes = (int)Math.Min(int.MaxValue, _pool.Settings._maxResponseHeadersLength * 1024L);
+ _allowedReadLineBytes = MaxResponseHeadersLength;
// We should not have any buffered data here; if there was, it should have been treated as an error
// by the previous request handling. (Note we do not support HTTP pipelining.)
@@ -1412,7 +1414,7 @@ namespace System.Net.Http
{
if (_allowedReadLineBytes < buffer.Length)
{
- throw new HttpRequestException(SR.Format(SR.net_http_response_headers_exceeded_length, _pool.Settings._maxResponseHeadersLength * 1024L));
+ throw new HttpRequestException(SR.Format(SR.net_http_response_headers_exceeded_length, MaxResponseHeadersLength));
}
line = default;
@@ -1523,7 +1525,7 @@ namespace System.Net.Http
{
if (_allowedReadLineBytes < 0)
{
- throw new HttpRequestException(SR.Format(SR.net_http_response_headers_exceeded_length, _pool.Settings._maxResponseHeadersLength * 1024L));
+ throw new HttpRequestException(SR.Format(SR.net_http_response_headers_exceeded_length, MaxResponseHeadersLength));
}
}
diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs
index 02e18e91090..295986b8201 100644
--- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs
+++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs
@@ -754,6 +754,60 @@ namespace System.Net.Http.Functional.Tests
}
});
}
+
+ [Theory]
+ [InlineData(1024, 64, false)]
+ [InlineData(1024, 1024 - 2, false)] // we need at least 2 spare bytes for the next CRLF
+ [InlineData(1024, 1024 - 1, true)]
+ [InlineData(1024, 1024, true)]
+ [InlineData(1024, 1024 + 1, true)]
+ [InlineData(1024 * 1024, 1024 * 1024 - 2, false)]
+ [InlineData(1024 * 1024, 1024 * 1024 - 1, true)]
+ [InlineData(1024 * 1024, 1024 * 1024, true)]
+ public async Task GetAsync_MaxResponseHeadersLength_EnforcedOnTrailingHeaders(int maxResponseHeadersLength, int trailersLength, bool shouldThrow)
+ {
+ await LoopbackServer.CreateClientAndServerAsync(
+ async uri =>
+ {
+ using HttpClientHandler handler = CreateHttpClientHandler();
+ using HttpClient client = CreateHttpClient(handler);
+
+ handler.MaxResponseHeadersLength = maxResponseHeadersLength / 1024;
+
+ if (shouldThrow)
+ {
+ await Assert.ThrowsAsync<HttpRequestException>(() => client.GetAsync(uri));
+ }
+ else
+ {
+ (await client.GetAsync(uri)).Dispose();
+ }
+ },
+ async server =>
+ {
+ try
+ {
+ const string TrailerName1 = "My-Trailer-1";
+ const string TrailerName2 = "My-Trailer-2";
+
+ int trailerOneLength = trailersLength / 2;
+ int trailerTwoLength = trailersLength - trailerOneLength;
+
+ await server.AcceptConnectionSendCustomResponseAndCloseAsync(
+ "HTTP/1.1 200 OK\r\n" +
+ "Connection: close\r\n" +
+ "Transfer-Encoding: chunked\r\n" +
+ "\r\n" +
+ "4\r\n" +
+ "data\r\n" +
+ "0\r\n" +
+ $"{TrailerName1}: {new string('a', trailerOneLength - TrailerName1.Length - 4)}\r\n" +
+ $"{TrailerName2}: {new string('b', trailerTwoLength - TrailerName2.Length - 4)}\r\n" +
+ "\r\n");
+ }
+ catch { }
+ });
+ }
}
// TODO: make generic to support HTTP/2 and HTTP/3.