4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CloudFrontの自動gzip圧縮が突然始まった

4
Posted at

はじめに

Railsのアップグレード後にAPIが突然破壊されました。

調査してみると CloudFront が「それまで圧縮していなかったレスポンスを gzip 圧縮して返すようになった」ということが発覚しました。

CloudFrontが圧縮する条件

CloudFront では、次の条件で自動圧縮されます1

  • リクエストに Accept-Encoding: gzip(または br)が含まれている
  • オリジンの応答が未圧縮である(Content-Encoding ヘッダが付いていない)
  • Content-Type が application/jsontext/html など圧縮対象の型である
  • ステータスコードが 200403404 のいずれかで、ボディが空でない

かてて加えて、 Content-Length が1,000〜10,000,000 バイトだと自動圧縮されます。1

RailsのアップデートでContent-Lengthが付与

Rails のアプリケーションサーバ puma は、アプリが Content-Length を指定していない場合に、ボディから計算して付与されるようになりました2
このアップデートを反映させると、アプリのコードは全く変わっていないのにレスポンスヘッダーに Content-Length が自動で付与されます。すると、CloudFront が1,000バイト以上のレスポンスを自動で圧縮しはじめます。

クライアントの処理

HTTP クライアントは Accept-Encoding: gzip を指定して送ることがあります。しかし、これを送っておきながら返ってきた gzip データを展開する処理がないと、生の gzip バイト列(先頭が 0x1f 0x8b)がそのまま JSON パーサに渡り、パースエラーで失敗します。

まとめ

  • CloudFrontは Content-Length が無いレスポンスは圧縮しない
  • Content-Length はサーバやミドルウェアが決めるため、アプリコードを変えなくてもアップグレードで圧縮されうる
  • 受け取る側が Accept-Encoding: gzip を送るなら、Content-Encoding を見て展開する前提で設計する

参考文献

  1. 圧縮ファイルを供給する - Amazon CloudFront。圧縮の条件(Accept-Encoding、Content-Encoding、Content-Type、Content-Length、サイズ 1,000〜10,000,000 バイト、ステータス 200/403/404)。引用は「圧縮の条件」節より。参照日 2026-07-13 2

  2. puma/puma#2896: Response refactor, increase requests-per-second, body type handling。"An Array - Puma will determine the content-length if not provided"。puma 6.0.0(2022-09-13 マージ)に含まれる。参照日 2026-07-13

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?