Skip to content

Commit b6a3871

Browse files
authored
Fix ResponseCompression tests to work with different zlib implementations (#63988)
1 parent 29bd68c commit b6a3871

File tree

1 file changed

+100
-33
lines changed

1 file changed

+100
-33
lines changed

src/Middleware/ResponseCompression/test/ResponseCompressionMiddlewareTest.cs

Lines changed: 100 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public async Task Request_AcceptGzipDeflate_CompressedGzip()
5959
{
6060
var (response, logMessages) = await InvokeMiddleware(100, requestAcceptEncodings: new[] { "gzip", "deflate" }, responseType: TextPlain);
6161

62-
CheckResponseCompressed(response, expectedBodyLength: 29, expectedEncoding: "gzip");
62+
await CheckResponseCompressed(response, "gzip");
6363
AssertCompressedWithLog(logMessages, "gzip");
6464
}
6565

@@ -68,7 +68,7 @@ public async Task Request_AcceptBrotli_CompressedBrotli()
6868
{
6969
var (response, logMessages) = await InvokeMiddleware(100, requestAcceptEncodings: new[] { "br" }, responseType: TextPlain);
7070

71-
CheckResponseCompressed(response, expectedBodyLength: 21, expectedEncoding: "br");
71+
await CheckResponseCompressed(response, "br");
7272
AssertCompressedWithLog(logMessages, "br");
7373
}
7474

@@ -79,7 +79,7 @@ public async Task Request_AcceptMixed_CompressedBrotli(string encoding1, string
7979
{
8080
var (response, logMessages) = await InvokeMiddleware(100, new[] { encoding1, encoding2 }, responseType: TextPlain);
8181

82-
CheckResponseCompressed(response, expectedBodyLength: 21, expectedEncoding: "br");
82+
await CheckResponseCompressed(response, "br");
8383
AssertCompressedWithLog(logMessages, "br");
8484
}
8585

@@ -96,7 +96,7 @@ void Configure(ResponseCompressionOptions options)
9696

9797
var (response, logMessages) = await InvokeMiddleware(100, new[] { encoding1, encoding2 }, responseType: TextPlain, configure: Configure);
9898

99-
CheckResponseCompressed(response, expectedBodyLength: 29, expectedEncoding: "gzip");
99+
await CheckResponseCompressed(response, "gzip");
100100
AssertCompressedWithLog(logMessages, "gzip");
101101
}
102102

@@ -127,7 +127,7 @@ public async Task RequestHead_AcceptGzipDeflate_CompressedGzip()
127127
var (response, logMessages) = await InvokeMiddleware(100, requestAcceptEncodings: new[] { "gzip", "deflate" }, responseType: TextPlain, httpMethod: HttpMethods.Head);
128128

129129
// Per RFC 7231, section 4.3.2, the Content-Length header can be omitted on HEAD requests.
130-
CheckResponseCompressed(response, expectedBodyLength: null, expectedEncoding: "gzip");
130+
await CheckResponseCompressed(response, "gzip");
131131
AssertCompressedWithLog(logMessages, "gzip");
132132
}
133133

@@ -140,7 +140,7 @@ public async Task ContentType_WithCharset_Compress(string contentType)
140140
{
141141
var (response, logMessages) = await InvokeMiddleware(uncompressedBodyLength: 100, requestAcceptEncodings: new[] { "gzip" }, contentType);
142142

143-
CheckResponseCompressed(response, expectedBodyLength: 29, expectedEncoding: "gzip");
143+
await CheckResponseCompressed(response, "gzip");
144144
AssertCompressedWithLog(logMessages, "gzip");
145145
}
146146

@@ -179,7 +179,7 @@ public async Task GZipCompressionProvider_OptionsSetInDI_Compress()
179179

180180
var response = await client.SendAsync(request);
181181

182-
CheckResponseCompressed(response, expectedBodyLength: 133, expectedEncoding: "gzip");
182+
await CheckResponseCompressed(response, "gzip");
183183
}
184184

185185
[Theory]
@@ -272,7 +272,7 @@ bool compress
272272

273273
if (compress)
274274
{
275-
CheckResponseCompressed(response, expectedBodyLength: 29, expectedEncoding: "gzip");
275+
await CheckResponseCompressed(response, "gzip");
276276
AssertCompressedWithLog(logMessages, "gzip");
277277
}
278278
else
@@ -293,7 +293,7 @@ public async Task NoIncludedMimeTypes_UseDefaults()
293293
options.ExcludedMimeTypes = new[] { "text/*" };
294294
});
295295

296-
CheckResponseCompressed(response, expectedBodyLength: 29, expectedEncoding: "gzip");
296+
await CheckResponseCompressed(response, "gzip");
297297
AssertCompressedWithLog(logMessages, "gzip");
298298
}
299299

@@ -345,7 +345,7 @@ public async Task Request_AcceptStar_Compressed()
345345
{
346346
var (response, logMessages) = await InvokeMiddleware(100, requestAcceptEncodings: new[] { "*" }, responseType: TextPlain);
347347

348-
CheckResponseCompressed(response, expectedBodyLength: 21, expectedEncoding: "br");
348+
await CheckResponseCompressed(response, "br");
349349
AssertCompressedWithLog(logMessages, "br");
350350
}
351351

@@ -362,24 +362,24 @@ public async Task Request_AcceptIdentity_NotCompressed()
362362
}
363363

364364
[Theory]
365-
[InlineData(new[] { "identity;q=0.5", "gzip;q=1" }, 29)]
366-
[InlineData(new[] { "identity;q=0", "gzip;q=0.8" }, 29)]
367-
[InlineData(new[] { "identity;q=0.5", "gzip" }, 29)]
368-
public async Task Request_AcceptWithHigherCompressionQuality_Compressed(string[] acceptEncodings, int expectedBodyLength)
365+
[InlineData("identity;q=0.5", "gzip;q=1")]
366+
[InlineData("identity;q=0", "gzip;q=0.8")]
367+
[InlineData("identity;q=0.5", "gzip")]
368+
public async Task Request_AcceptWithHigherCompressionQuality_Compressed(string encoding1, string encoding2)
369369
{
370-
var (response, logMessages) = await InvokeMiddleware(100, requestAcceptEncodings: acceptEncodings, responseType: TextPlain);
370+
var (response, logMessages) = await InvokeMiddleware(100, requestAcceptEncodings: new[] { encoding1, encoding2 }, responseType: TextPlain);
371371

372-
CheckResponseCompressed(response, expectedBodyLength: expectedBodyLength, expectedEncoding: "gzip");
372+
await CheckResponseCompressed(response, "gzip");
373373
AssertCompressedWithLog(logMessages, "gzip");
374374
}
375375

376376
[Theory]
377-
[InlineData(new[] { "gzip;q=0.5", "identity;q=0.8" }, 100)]
378-
public async Task Request_AcceptWithhigherIdentityQuality_NotCompressed(string[] acceptEncodings, int expectedBodyLength)
377+
[InlineData("gzip;q=0.5", "identity;q=0.8")]
378+
public async Task Request_AcceptWithhigherIdentityQuality_NotCompressed(string encoding1, string encoding2)
379379
{
380-
var (response, logMessages) = await InvokeMiddleware(100, requestAcceptEncodings: acceptEncodings, responseType: TextPlain);
380+
var (response, logMessages) = await InvokeMiddleware(100, requestAcceptEncodings: new[] { encoding1, encoding2 }, responseType: TextPlain);
381381

382-
CheckResponseNotCompressed(response, expectedBodyLength: expectedBodyLength, sendVaryHeader: true);
382+
CheckResponseNotCompressed(response, expectedBodyLength: 100, sendVaryHeader: true);
383383
Assert.Equal(3, logMessages.Count);
384384
AssertLog(logMessages.First(), LogLevel.Trace, "This request accepts compression.");
385385
AssertLog(logMessages.Skip(1).First(), LogLevel.Trace, "Response compression is available for this Content-Type.");
@@ -476,7 +476,14 @@ public async Task Request_Https_CompressedIfEnabled(bool enableHttps, int expect
476476

477477
var response = await client.SendAsync(request);
478478

479-
Assert.Equal(expectedLength, (await response.Content.ReadAsByteArrayAsync()).Length);
479+
if (enableHttps)
480+
{
481+
await CheckResponseCompressed(response, "gzip");
482+
}
483+
else
484+
{
485+
Assert.Equal(expectedLength, (await response.Content.ReadAsByteArrayAsync()).Length);
486+
}
480487

481488
var logMessages = sink.Writes.ToList();
482489
if (enableHttps)
@@ -539,7 +546,14 @@ public async Task Request_Https_CompressedIfOptIn(HttpsCompressionMode mode, int
539546

540547
var response = await client.SendAsync(request);
541548

542-
Assert.Equal(expectedLength, (await response.Content.ReadAsByteArrayAsync()).Length);
549+
if (mode == HttpsCompressionMode.Compress)
550+
{
551+
await CheckResponseCompressed(response, "gzip");
552+
}
553+
else
554+
{
555+
Assert.Equal(expectedLength, (await response.Content.ReadAsByteArrayAsync()).Length);
556+
}
543557

544558
var logMessages = sink.Writes.ToList();
545559
if (mode == HttpsCompressionMode.Compress)
@@ -602,7 +616,14 @@ public async Task Request_Https_NotCompressedIfOptOut(HttpsCompressionMode mode,
602616

603617
var response = await client.SendAsync(request);
604618

605-
Assert.Equal(expectedLength, (await response.Content.ReadAsByteArrayAsync()).Length);
619+
if (mode != HttpsCompressionMode.DoNotCompress)
620+
{
621+
await CheckResponseCompressed(response, "gzip");
622+
}
623+
else
624+
{
625+
Assert.Equal(expectedLength, (await response.Content.ReadAsByteArrayAsync()).Length);
626+
}
606627

607628
var logMessages = sink.Writes.ToList();
608629
if (mode == HttpsCompressionMode.DoNotCompress)
@@ -616,8 +637,8 @@ public async Task Request_Https_NotCompressedIfOptOut(HttpsCompressionMode mode,
616637
}
617638

618639
[Theory]
619-
[MemberData(nameof(SupportedEncodingsWithBodyLength))]
620-
public async Task FlushHeaders_SendsHeaders_Compresses(string encoding, int expectedBodyLength)
640+
[MemberData(nameof(SupportedEncodings))]
641+
public async Task FlushHeaders_SendsHeaders_Compresses(string encoding)
621642
{
622643
var responseReceived = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
623644

@@ -658,12 +679,12 @@ public async Task FlushHeaders_SendsHeaders_Compresses(string encoding, int expe
658679

659680
await response.Content.LoadIntoBufferAsync();
660681

661-
CheckResponseCompressed(response, expectedBodyLength, encoding);
682+
await CheckResponseCompressed(response, encoding);
662683
}
663684

664685
[Theory]
665-
[MemberData(nameof(SupportedEncodingsWithBodyLength))]
666-
public async Task FlushAsyncHeaders_SendsHeaders_Compresses(string encoding, int expectedBodyLength)
686+
[MemberData(nameof(SupportedEncodings))]
687+
public async Task FlushAsyncHeaders_SendsHeaders_Compresses(string encoding)
667688
{
668689
var responseReceived = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
669690

@@ -703,7 +724,7 @@ public async Task FlushAsyncHeaders_SendsHeaders_Compresses(string encoding, int
703724

704725
await response.Content.LoadIntoBufferAsync();
705726

706-
CheckResponseCompressed(response, expectedBodyLength, encoding);
727+
await CheckResponseCompressed(response, encoding);
707728
}
708729

709730
[Theory]
@@ -1114,7 +1135,7 @@ public async Task SendFileAsync_FirstWrite_CompressesAndFlushes()
11141135

11151136
var response = await client.SendAsync(request);
11161137

1117-
CheckResponseCompressed(response, expectedBodyLength: 35, expectedEncoding: "gzip");
1138+
await CheckResponseCompressed(response, "gzip");
11181139

11191140
Assert.False(fakeSendFile.SendFileInvoked);
11201141
}
@@ -1164,7 +1185,7 @@ public async Task SendFileAsync_AfterFirstWrite_CompressesAndFlushes()
11641185

11651186
var response = await client.SendAsync(request);
11661187

1167-
CheckResponseCompressed(response, expectedBodyLength: 46, expectedEncoding: "gzip");
1188+
await CheckResponseCompressed(response, "gzip");
11681189

11691190
Assert.False(fakeSendFile.SendFileInvoked);
11701191
}
@@ -1286,7 +1307,7 @@ public async Task Dispose_SyncWriteOrFlushNotCalled(string encoding)
12861307
return (response, sink.Writes.ToList());
12871308
}
12881309

1289-
private static void CheckResponseCompressed(HttpResponseMessage response, long? expectedBodyLength, string expectedEncoding)
1310+
private static async Task CheckResponseCompressed(HttpResponseMessage response, string expectedEncoding)
12901311
{
12911312
var containsVaryAcceptEncoding = false;
12921313
foreach (var value in response.Headers.GetValues(HeaderNames.Vary))
@@ -1300,7 +1321,53 @@ private static void CheckResponseCompressed(HttpResponseMessage response, long?
13001321
Assert.True(containsVaryAcceptEncoding);
13011322
Assert.False(response.Content.Headers.TryGetValues(HeaderNames.ContentMD5, out _));
13021323
Assert.Single(response.Content.Headers.ContentEncoding, expectedEncoding);
1303-
Assert.Equal(expectedBodyLength, response.Content.Headers.ContentLength);
1324+
1325+
// Test functionality instead of exact byte counts
1326+
await CheckCompressionFunctionality(response, expectedEncoding, new string('a', 100));
1327+
}
1328+
1329+
private static async Task CheckCompressionFunctionality(HttpResponseMessage response, string expectedEncoding, string expectedContent)
1330+
{
1331+
var compressedBytes = await response.Content.ReadAsByteArrayAsync();
1332+
1333+
// Handle HEAD requests - no body to decompress
1334+
if (response.RequestMessage?.Method == HttpMethod.Head)
1335+
{
1336+
return;
1337+
}
1338+
1339+
// Decompress and verify content matches original
1340+
string decompressedContent;
1341+
1342+
if (expectedEncoding == "gzip")
1343+
{
1344+
using var compressedStream = new MemoryStream(compressedBytes);
1345+
using var gzipStream = new GZipStream(compressedStream, CompressionMode.Decompress);
1346+
using var reader = new StreamReader(gzipStream);
1347+
decompressedContent = await reader.ReadToEndAsync();
1348+
}
1349+
else if (expectedEncoding == "br")
1350+
{
1351+
using var compressedStream = new MemoryStream(compressedBytes);
1352+
using var brotliStream = new BrotliStream(compressedStream, CompressionMode.Decompress);
1353+
using var reader = new StreamReader(brotliStream);
1354+
decompressedContent = await reader.ReadToEndAsync();
1355+
}
1356+
else
1357+
{
1358+
throw new ArgumentException($"Unsupported encoding: {expectedEncoding}");
1359+
}
1360+
1361+
// Verify decompressed content matches what we expect
1362+
if (decompressedContent.Length >= expectedContent.Length && decompressedContent.StartsWith(expectedContent, StringComparison.Ordinal))
1363+
{
1364+
// Handles cases like SendFileAsync where additional content is appended
1365+
Assert.True(true);
1366+
}
1367+
else
1368+
{
1369+
Assert.Equal(expectedContent, decompressedContent);
1370+
}
13041371
}
13051372

13061373
private static void CheckResponseNotCompressed(HttpResponseMessage response, long? expectedBodyLength, bool sendVaryHeader)

0 commit comments

Comments
 (0)