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

Fix quality parse error in Accept-Encoding HTTP header #2344

Merged
merged 7 commits into from
Sep 1, 2021

Conversation

arthurlm
Copy link
Contributor

@arthurlm arthurlm commented Jul 23, 2021

PR Type

Bug Fix

PR Checklist

  • Tests for the changes have been added / updated.
  • Documentation comments have been added / updated.
  • A changelog entry has been made for the appropriate packages.
  • Format code with the latest stable rustfmt.
  • (Team) Label with affected crates and semver status.

Overview

HTTP header Accept-Encoding was not correctly parsed.

Other changes:

  • Better respect of client algorithms choices.
  • Follow MDN spec about default qfactor value.
  • It client need compressed response, now server send 406 HTTP error if there is no available algorithms.
  • Make ContentEncoding::parse fail instead of returning default value.

Issue open to discussion

I have change CompressMiddleware trait requirements.

- B: MessageBody
+ B: MessageBody + From<String>

Indeed, I have not been able to use the Either trait correctly to answer available compress algorithm when we have to answer NotAcceptable status code.

So the only way I have been able to work with is adding From<String> requirement to B.

This make test common_combinations fail (see: dade818). So I have disable it ...
If anyone has a good idea to fix this, I will be happy to edit my PR.

Closes #2322

Copy link
Member

@robjtede robjtede left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice change, thanks for the contribution

@robjtede robjtede added A-http project: actix-http A-web project: actix-web B-semver-minor labels Sep 1, 2021
@robjtede
Copy link
Member

robjtede commented Sep 1, 2021

I was able to sort out the problems you outlined in the description. Indeed adding the From<String> bound would have been unacceptable.

@robjtede robjtede merged commit ddc8c16 into actix:master Sep 1, 2021
@arthurlm arthurlm deleted the parse-accept-encoding branch September 1, 2021 08:23
Roms1383 pushed a commit to Roms1383/actix-web that referenced this pull request Sep 1, 2021
@istr
Copy link

istr commented Dec 24, 2022

While #2322 is a valid bug report, I would tend to say that some of the additional changes made with this PR are a regression over the previous version.

  • Neither the HTTP RFC nor the (only informative) MDN "spec" state that the order of equally weighted options has any significance.
  • Hence it is still up to the server to decide on the best option for equally weighted preferences. gzip,br,zstd, br,zstd,gzip, and zstd,gzip,br are completely equivalent (in each of the cases the client gives an implict q=1 for each option).
  • Given this, the test cases
    async fn negotiate_encoding_gzip() {
    async fn negotiate_encoding_br() {
    async fn negotiate_encoding_zstd() {
    are not only misleading. I would say they are plain wrong (ymmv).
  • Instead of this, the server should have a deterministic preference. These tests should verify that the server determines the preference of equally weighted options, regardless of the order in which the client sent them.
  • You could still argue that the server's preference is based on the order of equally weighted options. Still, like with TLS handshake it is desirable that the server will go for the best option at hand.
  • It was a good idea to have a built-in server preference, however the implementation was questionable:
    /// Default Q-factor (quality) value.
    #[inline]
    pub fn quality(self) -> f64 {
        match self {
            ContentEncoding::Br => 1.1,
            ContentEncoding::Gzip => 1.0,
            ContentEncoding::Deflate => 0.9,
            ContentEncoding::Identity | ContentEncoding::Auto => 0.1,
            ContentEncoding::Zstd => 0.0,
        }
    }

@robjtede could we try to recover the old server-side preference behavior? Or add an option to pass the preferred order to middleware::Compress somehow?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-http project: actix-http A-web project: actix-web B-semver-minor
Projects
None yet
Development

Successfully merging this pull request may close these issues.

middleware::Compress does not handle accept-encoding header correctly
3 participants