mod_rewriteを用いたダウンロードカウンターに欠点があることが分かった。それは、CGIによってファイルを出力しているので、.htaccessによってアクセス制限をかけているファイルでもダウンロードできるようになってしまうということ。うーん、欠点はなさそうに思ったんだけどなぁ。
これを回避する方法はいくつか思いつくけど、どれもあまりスマートではなさそう。こうなれば、ダウンロード専用ディレクトリに特化したスクリプトにするのがよさそう。サブディレクトリ以下のファイルにも有効なので、たとえば/softwareでmod_rewriteの設定をしておけば、/software以下のすべてのダウンロードファイルに対応できる。これでも十分便利っしょ。
CGIでダウンロード用のバイナリファイルを出力するときは、サーバーから返すヘッダにContent-type: application/octet-streamとContent-Disposition: attachmentを指定するみたい。
Content-Type: application/octet-stream Content-Disposition: attachment
で、index.cgiからhoge.lzhのファイル内容を出力したときは、ダウンロードしたファイル名はindex.cgiになる。mod_rewriteを利用してhoge.lzhというURLをindex.cgiというスクリプトに対応させたときでも、ダウンロードしたファイル名はhoge.lzhになるのかと思いきや、なんとindex.cgiという名前で保存される。ちゃんとhoge.lzhというファイル名で保存されるようにするためには、サーバーが返すヘッダにContent-Disposition: attachment; filename=○○を追加する必要があるみたい。さらに、Content-Lengthとしてファイルサイズを出力すると、ダウンロード前にクライアント側でファイルサイズを知ることができる(もしかしてContent-Lengthの出力は、ダウンロードのレジューム機能にも関係あるのかな?)
Content-Type: application/octet-stream Content-Disposition: attachment; filename=ファイル名 Content-Length: ファイルサイズ
それから、ちゃんとヘッダの出力やbinmodeの指定をしても、サーバーやブラウザの組み合わせによってはダウンロードが開始せず、テキストファイルみたいにウィンドウにファイルの内容が表示されてしまうことがある。なんでだろ? 今日からアクセスカウンターの運用を開始して、lzhファイルはCGIで出力するようにしてみたけど、ファイルの出力がこんなに奥が深いとは知らなかった。