diff --git a/README.md b/README.md index 2529f56a..a5257ad7 100644 --- a/README.md +++ b/README.md @@ -675,7 +675,7 @@ follows: builder.Services.AddResponseCompression(options => { options.EnableForHttps = true; // may lead to CRIME and BREACH attacks - options.MimeTypes = new[] { "application/json", "application/graphql-response+json" }; + options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Append("application/graphql-response+json"); }) // place this first/early in the pipeline @@ -687,7 +687,7 @@ added to the `MimeTypes` option. You may choose to enable other content types a Please note that enabling response compression over HTTPS can lead to CRIME and BREACH attacks. These side-channel attacks typically affects sites that rely on cookies for -authentication. Please read [this](https://docs.microsoft.com/en-us/aspnet/core/performance/response-compression?view=aspnetcore-6.0) +authentication. Please read [this](https://docs.microsoft.com/en-us/aspnet/core/performance/response-compression) and [this](http://www.breachattack.com/#howitworks) for more details. ### ASP.NET Core 2.1 / .NET Framework 4.8 diff --git a/tests/Transports.AspNetCore.Tests/Middleware/CompressionTests.cs b/tests/Transports.AspNetCore.Tests/Middleware/CompressionTests.cs new file mode 100644 index 00000000..bcaf1258 --- /dev/null +++ b/tests/Transports.AspNetCore.Tests/Middleware/CompressionTests.cs @@ -0,0 +1,67 @@ +#if !NETCOREAPP2_1 && !NET48 + +using System.IO.Compression; +using System.Net.Http.Headers; +using Microsoft.AspNetCore.ResponseCompression; + +namespace Tests.Middleware; + +public class CompressionTests +{ + [Fact] + public async Task ResponseCompression_ShouldCompressGraphQLResponse() + { + // Arrange + var hostBuilder = new WebHostBuilder(); + hostBuilder.ConfigureServices(services => + { + services.AddGraphQL(b => b + .AddAutoSchema() + .AddSystemTextJson()); + services.AddRouting(); + services.AddResponseCompression(options => + { + options.EnableForHttps = true; + options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Append("application/graphql-response+json"); + }); + }); + hostBuilder.Configure(app => + { + app.UseResponseCompression(); + app.UseGraphQL(); + }); + + using var server = new TestServer(hostBuilder); + using var client = server.CreateClient(); + + // Act + using var request = new HttpRequestMessage(HttpMethod.Post, "/graphql"); + var content = new StringContent("{hello}"); + content.Headers.ContentType = new MediaTypeHeaderValue("application/graphql"); + request.Content = content; + request.Headers.Add("Accept-Encoding", "gzip"); + + using var response = await client.SendAsync(request); + + // Assert + response.EnsureSuccessStatusCode(); + + // Check if response is compressed + response.Content.Headers.ContentEncoding.ShouldContain("gzip"); + + // Decompress and verify content + using var responseStream = await response.Content.ReadAsStreamAsync(); + using var decompressionStream = new GZipStream(responseStream, CompressionMode.Decompress); + using var reader = new StreamReader(decompressionStream); + var decompressedContent = await reader.ReadToEndAsync(); + + decompressedContent.ShouldBe("""{"data":{"hello":"world"}}"""); + } + + public class Query + { + public static string Hello => "world"; + } +} + +#endif