このブログがさくらのブログであることからも明らかですが、さくらのレンタルサーバライトを利用して、いくつかのWebサービスを運用しております。
何年も前に青空文庫形態素解析データ集というサイトを作っておりまして、このサイトもさくらのレンタルサーバ上にコンテンツを配置しております。
その名の通り、青空文庫で公開されているデータを形態素解析した結果をzipやらgzipでダウンロードできるサイトなのですが、先日gzip圧縮されているファイルをダウンロードしたところ、拡張子はgzなのに、実際は解凍済みのファイルがダウンロードされるという事象が発生しました。
一括ダウンロードのページでは、わざわざ解凍前と解凍後のサイズを明記しているというのに…
オペミスか何かで解凍済みのファイルを拡張子をgzとして配置してしまったのかとも思いましたが、サーバに格納されているファイルを確認すると、ちゃんとgzip圧縮されたファイルが配置されていました。
どうも、Content-Encodingのgzipが有効になっていて、圧縮転送がされているとブラウザ(Chrome)が判断して、自動的に解凍してしまっている模様です。
はて、Content-Encodingのgzipとは、意図的に設定しないでも勝手につくものだったのかしら…ということも気になりますが、とりあえずはブラウザで解凍されないようにすることが先決ですので、方法を調べてみました。
で、思ったより苦戦しましたが、とりあえず、.htaccessに以下を追記することで、Chromeでは解凍されずにダウンロードできるようになりました。
<FilesMatch "\.gz$">
AddEncoding identity .gz
</FilesMatch>
さて、以下は上記に至るまでの経過を示していきます。内容に不備があるようであれば、有識者の方は突っ込みをお願いいたします。
そもそも、ブラウザがgzファイルを解凍してしまうのは、HTTPレスポンスヘッダのContent-Encodingにgzipが含まれているからではないかと推測し、Wiresharkでパケットを確認した結果、確かに「Content-Encoding: gzip」が含まれていました。
ちなみに、他のサイトでgzファイルをダウンロードしても自動的に解凍されませんでした(レスポンスにContent-Encodingそのものがなかった)ので、やはりサーバの設定の問題のようです。
で、ブラウザに解凍をさせたくない場合は、Content-Encodingヘッダそのものをつけないのが正しいようですので、初めはmod_headersを用いて以下のようにしてみましたが、どうにもContent-Encodingヘッダが削除されませんでした。
<FilesMatch "\.gz$">
Header unset Content-Encoding
</FilesMatch>
ETagヘッダで試してみると問題なく削除できましたので、機能が動作していないということはない筈なのですが…
あまり自信のない推測ですが、Content-Encodingヘッダはレスポンスヘッダの末尾についておりますので、除去された後にもう一度付与されている…のでしょうか。(私の単なる勘違いだったら申し訳ないですが)
次は、Content-Encodingを削除することは一旦あきらめて、内容を変更する方法で検討しました。
AddEncodingで変更できることはわかったのですが、何の文字列に変更すべきかがわからない…
RFC2616を見る限りでは…以下のような記載がありますので、やはり、identityが一番近いように読めます。
identity The default (identity) encoding; the use of no transformation whatsoever. This content-coding is used only in the Accept- Encoding header, and SHOULD NOT be used in the Content-Encoding header.
(長時間かけてググったわけではないですが、同じ事象で困っている人は見つけられませんでしたので、何か私が根本的な勘違いをしている気もしておりますが…)