compress icon indicating copy to clipboard operation
compress copied to clipboard

[fix] Not Support identity;q=1, *;q=0

Open 743v45 opened this issue 10 months ago • 12 comments

Describe the bug

Node.js version: v22.11.0

OS version: MacOS 15.3.1

koa-compress version: 5.1.1

Description: Accept-Encoding: identity;q=1, *;q=0 not work

Actual behavior

response with Content-Encoding: gzip

Expected behavior

Content-Encoding: identity

Code to reproduce

const Koa = require('koa');
const compress = require('koa-compress');

const app = new Koa();

app.use(compress(
  {
    filter: (contentType) => {
      return true;
    },
    threshold: 1,
    br: false,
  },
));

app.use(async (ctx) => {
    ctx.body = 'This is a sample response that will be compressed if the client supports it.';
});

const port = 3000;
app.listen(port, () => {
    console.log(`Server is running on port ${port}`);
});

Image

Checklist

  • [x] I have searched through GitHub issues for similar issues.
  • [x] I have completely read through the README and documentation.
  • [x] I have tested my code with the latest version of Node.js and this package and confirmed it is still not working.

743v45 avatar Mar 05 '25 08:03 743v45

returning a weight of 0 means you still are requesting gzip. what you actually want to request is just Accept-Encoding: identity

jonathanong avatar Mar 20 '25 06:03 jonathanong

@jonathanong

The Chrome browser initiated this request with Accept-Encoding: identity;q=1, *;q=0. This is not my delusion, but koa-compress forced a gzip return.

identity is also a function

identity Indicates the identity function (that is, without modification or compression). This value is always considered as acceptable, even if omitted.

I did not find an authoritative statement that is a perfect match. The following is the description of the gpt-4o

Image

743v45 avatar Apr 01 '25 05:04 743v45

yes, the authoritative statement says that it's a priority, not a rejection. content negotiation is a negotiation. we can return identity here, but we don't have to - it does not break specifications because you still requested gzip even if with priority = 0.

we can make this an option, but realistically, it's not practical (browsers and clients generally do not request encodings like this) and most people would prefer the response size savings.

however, IIRC your PR was incorrect as it explicitly rejected p=0, which is incorrect. if the client wants identity, then it should only request identity.

jonathanong avatar Apr 01 '25 07:04 jonathanong

Let me describe the scenario I encountered.

I added ctx.compress = true; to the route <host>/path/to/:filename to support compression. At first, only images were handled, and later videos were adapted.

However, when there is a video request, the request carries Accept-Encoding: identity;q=1, *;q=0, but the response is encoded, which leads to net::ERR_CONTENT_DECODING_FAILED.

Image

Image

Image

Accept-Encoding is a parameter on the client side. From the client's perspective, for Accept-Encoding: identity;q=1, *;q=0, it is best to return identity.

Of course, this is not suitable for the default koa-compress. The filter only filters text types supported by compressible and is not adapted to video/mp4 by default.

It seems that when Chrome initiates a request with Accept-Encoding: identity;q=1, *;q=0, it only wants the identity encoding and doesn't want gzip.

743v45 avatar Apr 02 '25 03:04 743v45

I agree with @743v45 this is a real bug and is causing issues with Chrome and an HLS server I wrote that uses koa-compress.

I have written a more detailed response with a link to the related RFC here: https://github.com/koajs/compress/pull/233#issuecomment-3536191507

I believe this bug should be re-opened.

mempf avatar Nov 15 '25 08:11 mempf

How to repro it without programming *;q=0? What is the actual real-world use case?

uhop avatar Nov 16 '25 00:11 uhop

How to repro it without programming *;q=0? What is the actual real-world use case?

The original steps to reproduce should work with sending the Accept-Encoding: identity;q=1, *;q=0 directly.

In terms of real world use case this comes up with Chrome 141+ requesting HLS playlists and video segments with this header and expecting uncompressed data.

This is a behaviour you should be able to see if you go to this HLS test page and look at the network requests being sent by Chrome. You must ensure that the override native flag is disabled as it only seems to be Chromes native HLS support that sends headers like this. https://videojs-http-streaming.netlify.app/?debug=false&autoplay=false&muted=false&fluid=false&minified=false&sync-workers=false&liveui=true&llhls=true&url=https%3A%2F%2Fd2zihajmogu5jn.cloudfront.net%2Fhls-webvtt%2Fmaster.m3u8&type=application%2Fx-mpegurl&keysystems=&buffer-water=false&exact-manifest-timings=false&pixel-diff-selector=false&network-info=true&dts-offset=false&override-native=false&object-fit=false&use-mms=true&preload=auto&mirror-source=true&forced-subtitles=false&native-text-tracks=false

mempf avatar Nov 16 '25 00:11 mempf

@mempf thanks for a real-world use-case. It seems like HLS playlists are compressible? Not sure why they would request it uncompressed. PR welcomed

jonathanong avatar Nov 26 '25 05:11 jonathanong

@mempf thanks for a real-world use-case. It seems like HLS playlists are compressible? Not sure why they would request it uncompressed. PR welcomed

They seem to be doing some byte range stuff with their requests I imagine wouldn't work properly if compressed. I'm not thrilled with it either as yeah the playlists tend to compress well. Regardless it exposes a bug.

mempf avatar Nov 26 '25 06:11 mempf

Can we re-open and merge https://github.com/koajs/compress/pull/233 from @743v45 ?

mempf avatar Nov 26 '25 06:11 mempf

@mempf I am prepping a new release and it will include the fix for this bug as well. Could you prepare a test for your use case? It'll help a lot. See https://github.com/koajs/compress/tree/master/tests how they are done.

uhop avatar Nov 27 '25 17:11 uhop

@mempf I am prepping a new release and it will include the fix for this bug as well. Could you prepare a test for your use case? It'll help a lot. See https://github.com/koajs/compress/tree/master/tests how they are done.

Will do. I'll keep an eye out for a new release and try it with our hls-server.

mempf avatar Nov 27 '25 22:11 mempf