なぜHTTPS接続時しかBrotliエンコーディングを要求しないのか?

主要ブラウザはHTTPS通信時しかBrotliエンコーディングを要求しません。なぜか?通信を暗号化することで、ミドルボックスがデータを書き換えられないようにするためです。
2020.05.11

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

BrotliHTTP圧縮を強く意識したデータ圧縮形式です。

Brotliの動作確認時にハマりがちなのが、主要ブラウザはHTTPS接続時しかBrotliエンコーディングを要求しないことです。

理由は、通信を暗号化することで、ミドルボックスがデータを書き換えられないようにするためです。

解説

HTTP通信時に、deflate・gzip以外のContent-Encodingを受け取ったミドルボックスの中には、元のエンコーディングを無視してgzipエンコードするものが存在します。

SDCHエンコーディング *1をChromeで展開する際にGoogleはこの問題に遭遇し、Content-Encoding: gzipを頼りにgzipデコードしてもうまくいかないときは、そこからさらにSDCHデコード(Content-Encoding: sdch,gzipでしょうか?)するといった涙ぐましいハックで対応するはめになりました。

そこでBrotli展開時にはこの苦い経験を活かし、HTTPS接続時のみBrotliをAccept-Encodingに含めるようにし、サーバーがdeflate・gzip以外のContent-Encodingを返却しても、ミドルボックスがデータを書き換えられないようにしたそうです。

QUICKプロトコルの設計者でもあるJim Roskind氏がblink-devメーリングリストに投稿した内容を引用します。

FYI: The reason why we removed bzip content encoding, which outperformed gzip, was because middle boxes routinely corrupted the data.

The most extreme class of middle box included Vodaphone UK (for instance), that "tried to improve" on unknown content encodings, by doing the following (bizarre) things:

a) Remove the unrecognized content encoding b) Pass the (already compressed!) content through another gzip encoding pass c) Claim that the content was merely encoded as gzip

Some code that handled sdch encoding actually "gracefully" handles such molestation, by *expecting* to get "sdch,gzip" content, and when it doesn't arrive as expected, it tries to fallback decode as "sdch,gzip,gzip." Note very pretty... but very functional.

Sadly, for bzip, there was no way of anticipating such molestation by middle boxes... so we yanked bzip... resolving complaints from tons of users.

Please anticipate (if history taught us anything) that a pile of customers will complain about "not being able to load content" from sites that use this new content encoding.

Intent to Ship: Brotli (Accept-encoding: br on HTTPS connection) - Google Groups(blink-dev)

まとめ

ブラウザからBrotliを動作確認するときは、必ずHTTPS接続しましょう。

参考

脚注

  1. SDCHもBrotliもGoogleが開発