Skip to content

Commit e75fc27

Browse files
authored
Change DefaultMaximumErrorResponseLength to KB from Byte (#105396)
* Change DefaultMaximumErrorResponseLength to KB from Byte * Handle overflow * Review feedback
1 parent 4a8aca8 commit e75fc27

File tree

2 files changed

+57
-19
lines changed

2 files changed

+57
-19
lines changed

src/libraries/System.Net.Requests/src/System/Net/HttpWebResponse.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ public override Stream GetResponseStream()
346346
return contentStream;
347347
}
348348

349-
return new TruncatedReadStream(contentStream, maxErrorResponseLength);
349+
return new TruncatedReadStream(contentStream, (long)maxErrorResponseLength * 1024);
350350
}
351351

352352
return Stream.Null;
@@ -381,8 +381,9 @@ private void CheckDisposed()
381381

382382
private static string GetHeaderValueAsString(IEnumerable<string> values) => string.Join(", ", values);
383383

384-
internal sealed class TruncatedReadStream(Stream innerStream, int maxSize) : Stream
384+
internal sealed class TruncatedReadStream(Stream innerStream, long maxSize) : Stream
385385
{
386+
private long _maxRemainingLength = maxSize;
386387
public override bool CanRead => true;
387388
public override bool CanSeek => false;
388389
public override bool CanWrite => false;
@@ -399,8 +400,8 @@ public override int Read(byte[] buffer, int offset, int count)
399400

400401
public override int Read(Span<byte> buffer)
401402
{
402-
int readBytes = innerStream.Read(buffer.Slice(0, Math.Min(buffer.Length, maxSize)));
403-
maxSize -= readBytes;
403+
int readBytes = innerStream.Read(buffer.Slice(0, (int)Math.Min(buffer.Length, _maxRemainingLength)));
404+
_maxRemainingLength -= readBytes;
404405
return readBytes;
405406
}
406407

@@ -411,9 +412,9 @@ public override Task<int> ReadAsync(byte[] buffer, int offset, int count, Cancel
411412

412413
public override async ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default)
413414
{
414-
int readBytes = await innerStream.ReadAsync(buffer.Slice(0, Math.Min(buffer.Length, maxSize)), cancellationToken)
415+
int readBytes = await innerStream.ReadAsync(buffer.Slice(0, (int)Math.Min(buffer.Length, _maxRemainingLength)), cancellationToken)
415416
.ConfigureAwait(false);
416-
maxSize -= readBytes;
417+
_maxRemainingLength -= readBytes;
417418
return readBytes;
418419
}
419420

src/libraries/System.Net.Requests/tests/HttpWebRequestTest.cs

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2318,33 +2318,70 @@ await server.AcceptConnectionAsync(
23182318
[ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
23192319
public async Task SendHttpRequest_WhenDefaultMaximumErrorResponseLengthSet_Success()
23202320
{
2321-
await RemoteExecutor.Invoke(async (async) =>
2321+
await RemoteExecutor.Invoke(async isAsync =>
23222322
{
23232323
TaskCompletionSource tcs = new TaskCompletionSource();
23242324
await LoopbackServer.CreateClientAndServerAsync(
2325-
async (uri) =>
2325+
async uri =>
23262326
{
23272327
HttpWebRequest request = WebRequest.CreateHttp(uri);
2328-
HttpWebRequest.DefaultMaximumErrorResponseLength = 5;
2329-
var exception =
2330-
await Assert.ThrowsAsync<WebException>(() => bool.Parse(async) ? request.GetResponseAsync() : Task.Run(() => request.GetResponse()));
2328+
HttpWebRequest.DefaultMaximumErrorResponseLength = 1; // 1 KB
2329+
WebException exception =
2330+
await Assert.ThrowsAsync<WebException>(() => bool.Parse(isAsync) ? request.GetResponseAsync() : Task.Run(() => request.GetResponse()));
23312331
tcs.SetResult();
23322332
Assert.NotNull(exception.Response);
2333-
using (var responseStream = exception.Response.GetResponseStream())
2333+
using (Stream responseStream = exception.Response.GetResponseStream())
23342334
{
2335-
var buffer = new byte[10];
2336-
int readLen = responseStream.Read(buffer, 0, buffer.Length);
2337-
Assert.Equal(5, readLen);
2338-
Assert.Equal(new string('a', 5), Encoding.UTF8.GetString(buffer[0..readLen]));
2339-
Assert.Equal(0, responseStream.Read(buffer));
2335+
byte[] buffer = new byte[10 * 1024];
2336+
int totalReadLen = 0;
2337+
int readLen = 0;
2338+
while ((readLen = responseStream.Read(buffer, readLen, buffer.Length - readLen)) > 0)
2339+
{
2340+
totalReadLen += readLen;
2341+
}
2342+
2343+
Assert.Equal(1024, totalReadLen);
2344+
Assert.Equal(new string('a', 1024), Encoding.UTF8.GetString(buffer[0..totalReadLen]));
23402345
}
23412346
},
2342-
async (server) =>
2347+
async server =>
2348+
{
2349+
await server.AcceptConnectionAsync(
2350+
async connection =>
2351+
{
2352+
await connection.SendResponseAsync(statusCode: HttpStatusCode.BadRequest, content: new string('a', 10 * 1024));
2353+
await tcs.Task;
2354+
});
2355+
});
2356+
}, IsAsync.ToString()).DisposeAsync();
2357+
}
2358+
2359+
[ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
2360+
public async Task SendHttpRequest_WhenDefaultMaximumErrorResponseLengthSetToIntMax_DoesNotThrow()
2361+
{
2362+
await RemoteExecutor.Invoke(async isAsync =>
2363+
{
2364+
TaskCompletionSource tcs = new TaskCompletionSource();
2365+
await LoopbackServer.CreateClientAndServerAsync(
2366+
async uri =>
2367+
{
2368+
HttpWebRequest request = WebRequest.CreateHttp(uri);
2369+
HttpWebRequest.DefaultMaximumErrorResponseLength = int.MaxValue; // KB
2370+
WebException exception =
2371+
await Assert.ThrowsAsync<WebException>(() => bool.Parse(isAsync) ? request.GetResponseAsync() : Task.Run(() => request.GetResponse()));
2372+
tcs.SetResult();
2373+
Assert.NotNull(exception.Response);
2374+
using (Stream responseStream = exception.Response.GetResponseStream())
2375+
{
2376+
Assert.Equal(1, await responseStream.ReadAsync(new byte[1]));
2377+
}
2378+
},
2379+
async server =>
23432380
{
23442381
await server.AcceptConnectionAsync(
23452382
async connection =>
23462383
{
2347-
await connection.SendResponseAsync(statusCode: HttpStatusCode.BadRequest, content: new string('a', 10));
2384+
await connection.SendResponseAsync(statusCode: HttpStatusCode.BadRequest, content: new string('a', 10 * 1024));
23482385
await tcs.Task;
23492386
});
23502387
});

0 commit comments

Comments
 (0)