CDN は GZIP を取り除き、ファイル名に mojibake を生成し、破損したダウンロードを修正する charset ヘッダーの強制を生成しました。

公開: 2025-11-21

大規模な Web サイトがグローバル インフラストラクチャに依存してコンテンツを確実かつ効率的に配信する場合、コンテンツ配信ネットワーク (CDN) が重要な役割を果たします。 CDN は単にアセットをユーザーの近くにキャッシュするだけでなく、ファイルの圧縮、ダウンロードの高速化、ユーザー エクスペリエンスの向上にも役立ちます。ただし、特定の条件下では、意図せずに新たな問題が発生する可能性があります。そのようなインシデントの 1 つは、GZIP 圧縮と文字セットの不適切な処理に関連しており、ダウンロードの破損やファイル名の文字化け (文字化け) を引き起こしました。この現象は、開発者とオペレータの両方に課題をもたらしました。

TL;DR: CDN サービスの構成ミスにより、ダウンロード可能なファイルから GZIP 圧縮ヘッダーが削除され、ファイル名の文字エンコーディングが誤解されました。その結果、破損したファイル名または判読できないファイル名 (mojibake) がダウンロードされることになりました。この問題は、HTTP ヘッダーに正しいcharset強制することで最終的に解決され、ファイル名のエンコーディングとコンテンツの両方がブラウザーによって正しく解釈されるようになりました。このケースでは、特に HTTP ヘッダーを変更する可能性のある CDN を使用する場合、コンテンツのエンコードにおける一貫性の重要性が強調されています。

問題点: 圧縮管理の不手際

問題の核心は、CDN によるContent-Encodingヘッダーの不適切な処理でした。オリジンサーバーは GZIP を使用してファイルを正しく圧縮し、次のヘッダーでラベルを付けました。

 Content-Encoding: gzip

ただし、配信の最適化を目的とした CDN は、このヘッダーを取り除き、コンテンツを非圧縮であるかのように提供することを決定しました。これは、CSS や JavaScript などの生のファイルを期待するブラウザでは正常に機能しましたが、ユーザーが CSV、PDF、ZIP アーカイブなどのファイルをダウンロードしようとすると、破損したダウンロードが受信されました。このようなファイルの解凍は完全に失敗するか、読み取り不可能または不完全と思われるデータが生成されます。

バイナリの破損を超えて、さらに不可解な問題が浮上しました。特に Chrome や Firefox などのブラウザを使用してダウンロードした場合、一部のファイル名が奇妙な記号で歪んで表示されます。この現象はmojibakeとして知られており、プログラムが意図しない文字エンコーディングを使用してバイト シーケンスを解釈するときに発生します。

文字エンコーディングの混乱

ダウンロードされたファイル名の文字化けは通常、次の場合に発生します。

  • ファイル名に非 ASCII 文字 (アクセント付き文字やアジア文字など) が含まれています。
  • ブラウザはどの文字セットを使用すればよいかを知りません
  • Content-DispositionヘッダーまたはContent-Typeヘッダーに適切な文字セット宣言がありません。

ブラウザは間違った推測をして、ISO-8859-1 などのデフォルトまたはフォールバック エンコーディングを使用してファイル名を解釈しようとし、判読可能な文字の代わりに意味不明な文字が表示されます。これは通常、日本語、ロシア語、ドイツ語など、特殊文字が多く使用される言語のファイル名を持つファイルをダウンロードするユーザーに影響します。

当初、開発者はアプリケーション サーバーから次のような適切なヘッダーを設定していました。

 Content-Type: application/octet-stream; charset=utf-8 Content-Disposition: attachment; filename="resume.pdf"

しかし、ここでも CDN がこれらのヘッダーを削除または置換することで変更し、文字セットのヒントなしでダウンロードが行われるようになりました。これにより、ファイル名が間違ったエンコーディングで解釈され、ブラウザーの誤った動作が引き起こされました。

修正: HTTP ヘッダーでの文字セットの強制

開発者は、多くのデバッグとログ トレースを行った結果、次のことを確認しました。

  • ファイルはオリジンサーバーで破損していませんでした。
  • ダウンロードは、curl および直接 IP アクセス経由で成功しました。
  • この問題は、CDN 経由で提供された場合にのみ発生しました。

したがって、適切な解決策は次の 2 つでした。

  1. ブラウザーが GZIP コンテンツを適切に受信して解凍できるように、CDN にContent-Encodingヘッダーを強制的に保存させます。
  2. Content-TypeContent-Dispositionヘッダー内の両方に明示的なcharsetを設定して、適切な国際ファイル名のデコードを保証します。

最終的に動作するヘッダー構成は次のようになります。

 Content-Type: application/octet-stream; charset=utf-8 Content-Disposition: attachment; filename*=UTF-8''r%C3%A9sum%C3%A9.pdf Content-Encoding: gzip

UTF-8'' URL エンコーディング構文でfilename*を使用すると、ブラウザーは RFC 5987 に従ってファイル名を解釈します。これは特に最新のブラウザーでサポートされており、クロスプラットフォームの動作を調整します。

CDN がヘッダーを変更する理由

CDN は多くの場合、パフォーマンスの最適化、冗長性の削減、応答の標準化を目的としています。この目的のために、彼らは次のことを行うことができます。

  • 圧縮ディレクティブを削除または置換する
  • コンテンツタイプを正規化する
  • セキュリティフィルターまたはキャッシュルールを通過しないヘッダーを削除します。

ただし、これらの最適化は、コンテンツのレンダリングやファイルのダウンロードに重要な慎重に設定されたパラメーターをオーバーライドすると、逆効果になる可能性があります。このインシデントでは、CDN が正しいContent-Encodingcharsetを保持できなかったことが、使いやすさと国際化の両方に有害であることが判明しました。

学んだ教訓

この問題は、分散環境で作業する開発者にとって貴重な思い出として役立ちます。

  • コンテンツ配信を常にエンドツーエンドでテストしてください。サーバー上で動作するファイルは、CDN の背後では異なる動作をする可能性があります。
  • ヘッダーでは明示的にしてください。デフォルトの動作については何も想定しません。コンテンツ タイプ、エンコーディング、および文字セットを常に宣言してください。
  • 構成を通じて CDN の動作を制御します。ほとんどの CDN では、ヘッダーを保存するためのオーバーライドまたはルールが許可されています。それらを活用してください。
  • 複数のブラウザーとロケールでのダウンロード動作を確認します。国際化のバグは、多くの場合、これらの条件下でのみ発生します。

よくある質問

モジバケとは?

文字化けとは、文字エンコーディングの不一致によって引き起こされる文字化けまたは不正な表示を表すために使用される用語です。これは、ソフトウェアがテキスト データの保存または送信に使用される文字エンコーディングを誤って解釈した場合によく発生します。

gzip はファイルのダウンロードにどのような影響を与えますか?

正しく使用すると、GZIP はファイルを圧縮してダウンロード時間を短縮します。ただし、ファイルが GZIP 圧縮として提供され、適切なContent-Encoding: gzipヘッダーが欠落している場合、ブラウザーはファイルを解凍できず、ダウンロードが破損したり、読めなくなったりする可能性があります。

CDN が Content-Encoding や charset などのヘッダーを削除するのはなぜですか?

CDN はパフォーマンスとセキュリティを優先します。その際、多くの場合、ヘッダーを正規化したり、安全でない可能性のある情報や不要な情報を削除するポリシーを適用したりします。これにより、コンテンツを正しく処理するために必要な重要なメタデータが誤って削除される可能性があります。

ダウンロード用に非 ASCII ファイル名を指定する正しい方法は何ですか?

RFC 5987 で指定されているように、UTF-8 エンコードとパーセントエスケープ形式を使用して、 filename*属性を持つContent-Dispositionヘッダーを使用します。次に例を示します。

Content-Disposition: attachment; filename*=UTF-8''r%C3%A9sum%C3%A9.pdf

開発者は今後このような問題をどのように回避できるでしょうか?

CDN 層を通じてテストを実施し、ヘッダーを明示的に指定し、必要なすべてのメタデータを保存または通過させる CDN 構成を利用する必要があります。さらに、デバッグ段階では、CDN がトラフィックをどのように変更するかに関するドキュメントを維持しておくことが不可欠です。