Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expand documentation #117

Open
slanden opened this issue Jun 23, 2020 · 12 comments
Open

Expand documentation #117

slanden opened this issue Jun 23, 2020 · 12 comments

Comments

@slanden
Copy link

slanden commented Jun 23, 2020

This middleware looks useful, but I'm not sure how to use it. Perhaps more examples with explanations would help?

I'd like to use brotli if the client accepts it, and fallback to gzip if not. In the readme, your example disables brotli and later states,

Brotli compression is supported in node v11.7.0+, which includes it natively.

Is brotli disabled because Node includes it natively or because that's just the example?

The current encodings are, in order of preference: br, gzip, deflate

Does the order of the encodings in the options object matter or is the "preference" always the same order?

Does one encoding fallback to another if not supported?

I'm unable to help with contributing these changes because I don't understand how it works, but I think answering these questions in the readme would help others understand. Or maybe it's just me..

@niftylettuce
Copy link
Contributor

PR welcome!

@niftylettuce
Copy link
Contributor

The user/client is the one that ultimately determines what compression methods it accepts.

@uhop
Copy link
Contributor

uhop commented Jul 7, 2020

Is brotli disabled because Node includes it natively or because that's just the example?

It is just an example. If you don't do anything, clients supporting br will get a br response, if your server is running on v11.7.0+.

Does one encoding fallback to another if not supported?

If a client or a server doesn't support an encoding from the list, the next one will be checked and used.

Does this explanation work for you? If not, ask away and let's refine our message. If it does, I'll be happy to submit a PR to update the docs.

@slanden
Copy link
Author

slanden commented Jul 8, 2020

@uhop Thank you, yes I think your answers make sense. It'd be helpful as well to be clear about what will happen by default (whether Node 11.7+ or an unsupported version), and then the order the fallbacks will happen.

So, here's my understanding based on what you've said:

app.use(compress())

will result in responses using brotli compression if using Node 11.7+, and otherwise return gzip responses. If for some reason gzip doesn't work or is not an option (again, I don't know anything about compression), then deflate is used.

This is always the order of selection. If an Options object is passed, the order of its keys doesn't change this order.

Is that correct?

Also, for options.defaultEncoding

An optional string, which specifies what encoders to use for requests without Accept-Encoding

does this mean that in all cases, Koa Compress checks the request's Accept-Encoding header to further eliminate compression options from the selection?

It seems natural that this would be the case, but I'm not one for assumptions..

options.defaultEncoding is also stated to be set to identity by default. What does that do?

@uhop
Copy link
Contributor

uhop commented Jul 8, 2020

So, here's my understanding based on what you've said

Encoders are going to be tried in this order: ['br', 'gzip', 'deflate'] unless eliminated by Accept-Encoding and availability of actual encoders (brotli).

Also, for options.defaultEncoding

When a client sends Accept-Encoding, its value is a list/set of accepted encodings. The rest is trivial. But there are two edge cases:

  1. The client does not send Accept-Encoding at all.
  2. The client sends Accept-Encoding set to "*".

In the former case, options.defaultEncoding is used. By default, it is identity. By the standard, it should be "*", which gets many people with curl or wget puzzled.

In the latter case, it will be ['gzip', 'deflate'].

What if all encoders are somehow eliminated? The catch-all will be identity.

options.defaultEncoding is also stated to be set to identity by default. What does that do?

identity means "no compression". Data will be left unchanged and no encoding is going to be used.


options.defaultEncoding is documented. Two other arrays (the order of encoders and the "*" substitute) are not, but they are available to be replaced by a user. Probably they should be documented, and even made available through options.

@slanden
Copy link
Author

slanden commented Jul 9, 2020

In the latter case, it will be ['gzip', 'deflate'].

Why is 'br' not listed here also?

@uhop
Copy link
Contributor

uhop commented Jul 9, 2020

Beats me. TBH using "*" doesn't make much sense at all. What does it mean? All possible encodings, including uninvented yet? I never saw it being used in the wild. I suspect that if some client uses it, it is probably a legacy one, which doesn't know about brotli. That's probably why.

IMHO the only plausible scenario for "*" is a closed system. For example, I have a client, which talks only to a certain server. The server can use only a set of predefined encodings. My client may understand all of them and indicate it with "*". In this scenario, the set of supported encodings on both sides is implicitly defined and cannot change.

@slanden
Copy link
Author

slanden commented Jul 12, 2020

I think you've cleared up everything that was missing from the docs, thank you! I don't understand the relation between our last two comments, but

Beats me.

tells me you didn't leave out the 'br' from that list by accident so that's good enough for me.

@uhop
Copy link
Contributor

uhop commented Jul 13, 2020

Beats me.

I guess that the authors decided to be reasonably conservative and in the case of "*" they will serve gzip. I don't see any other possible scenario when any other encoding is going to be selected. br is not included to prevent it from being selected instead of gzip.

@jonathanong
Copy link
Member

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding we are just trying to be as true to the specs as possible :) it's very confusing

@guillermodlpa
Copy link

Hello there! Catching up with this thread. Have a question for a simple general use case using Koa for an API for a website. Can just use compress() without any customizations? It seems to work fine. As a library user, I'd like to trust the defaults.

In examples around the internet, I've seen gzip: { flush: require('zlib').constants.Z_SYNC_FLUSH } passed very frequently. What does this do, and is it required to explicitly pass?

Thanks to all for contributing and maintaining koa-compress!

@titanism
Copy link

Here's what we do for @forwardemail and @ladjs:

      // https://github.com/koajs/compress
      app.use(compress({
        br: {
          params: {
            [zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_TEXT,
            [zlib.constants.BROTLI_PARAM_QUALITY]: 4
          }
        }
      }));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants