

nginxのgzip、location単位で設定変えると優先されるのは一番具体的なパス
この記事は、構成と文章の整理にAIを使っています。
あくまで読みやすくするための補助で、内容そのものをAIにすべて任せて書いているわけではありませんが、ところどころ相談しながら整えています。
nginxのgzip設定はhttp・server・location・ifのどのコンテキストにも書ける。だから特定のパスだけ圧縮の閾値を変えたい、みたいなことができる。
location単位でgzip設定を分ける
例えば/api/以下は全部圧縮したいけど、/api/foo/barだけは閾値を変えたい、みたいなケース。
server { listen 80;
location /api/foo/bar { gzip on; gzip_min_length 512; }
location /api/ { gzip on; gzip_min_length 256; }}正規表現を使わない通常のlocation同士なら、リクエストパスと一番長く一致する(=一番具体的な)locationが優先される。なので/api/foo/barへのアクセスは上のlocation /api/foo/barが勝ってgzip_min_length 512が適用される。それ以外の/api/配下はgzip_min_length 256。
flowchart TD
A[リクエスト: /api/foo/bar] --> B{最長一致のlocationを探す}
B --> C[location /api/foo/bar]
B --> D[location /api/]
C -->|一致文字数が長い方が優先| E[gzip_min_length 512 が適用される]
圧縮されてるかはContent-Encodingヘッダーで見る
レスポンスにContent-Encoding: gzipが付いてれば圧縮されてる。付いてない場合は大体以下のどれか。
- クライアントが
Accept-Encoding: gzipを送ってない gzip_min_length未満でスキップされてるgzip_typesに該当MIMEタイプが入ってない(text/htmlはデフォルトで含まれてるので指定不要)
確認はcurlで十分。
curl -H "Accept-Encoding: gzip" -I https://example.com/api/foo/barContent-Encoding: gzipが出てれば圧縮成功。中身まで見たいなら--compressedオプションを付ける。
gzip_proxied anyは便利だけど無条件じゃない
gzip_proxied anyにするとプロキシ経由のレスポンスも問答無用で圧縮する。楽だけど、トークンとか個人情報を含むレスポンスまで圧縮対象になる。
TLS配下で秘密情報を含むレスポンスを圧縮すると、BREACHという攻撃手法でその内容を推測される可能性があるらしい(実機での検証はしてない)。gzip_proxied no-cache no-store private expired authのようにCache-Controlの値を見て判断する書き方にすれば、公開情報以外は圧縮しない分安全側に倒せる。
APIレスポンスに認証情報や個人データが混ざる可能性があるエンドポイントは、anyじゃなくてこっちの書き方を検討した方が良さそう。