Why is app.UseResponseCompression() increasing the size of the response transferred over network?

Viewed 2735

I'm trying to enable response compression using a very simple Asp.Net Core 3.1 application. My current code:

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<BrotliCompressionProviderOptions>(options => options.Level = CompressionLevel.Optimal);
        services.AddResponseCompression(options =>
        {
            options.Providers.Add<BrotliCompressionProvider>();
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseResponseCompression();
        app.UseRouting();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGet("/", async context =>
            {
                var text = File.ReadAllText(@"D:\huge-response.txt");
                await context.Response.WriteAsync(text);
            });
        });
    }

In the huge-response.txt file, I have this:

qwer qwert qwert qwert qwert
qwer qwert qwert qwert qwert
qwer qwert qwert qwert qwert
qwer qwert qwert qwert qwert
qwer qwert qwert qwert qwert
qwer qwert qwert qwert qwert
....

repeated a lot times. The file is 626 KB.

Now, let's see what Chrome says about it:

enter image description here

Odd. So let's see in Fiddler. The first request is "normal", the second one is with the header Accept-Encoding: br

enter image description here

I also tried Gzip compression, with basically the same result.

This pretty much the opposite of what I thought would happen. Such a text file should be absurdly compressible, even in the "fastest" configuration. I expect to see less than 1 KB transferred over the network.

What am I doing wrong? Thanks in advance.

1 Answers

app.UseResponseCompression(); middleware is only working for Content-Type which presents MIME Types in HttpResponse instead of writing a file stream to HttpResponse likes you are doing.

Following the documentation, you will see this line:

Content-Type: Specifies the MIME type of the content. Every response should specify its Content-Type. The middleware checks this value to determine if the response should be compressed. The middleware specifies a set of default MIME types that it can encode, but you can replace or add MIME types.

In case you want to compress custom file, you need to write file stream with Content-Type header. Then later when this response is back to ResponseCompression middleware, it will be compressed.

public async Task Invoke(HttpContext context)
{
    context.Response.ContentType = "text/plain";
    using (var fs = new FileStream(@"D:\huge-response.txt", FileMode.Open))
    {
        await fs.CopyToAsync(context.Response.Body);
    }
}
Related