Home > CakePHP | PHP | unix > PHPで認証して、mod_xsendfileでファイルを出力する

PHPで認証して、mod_xsendfileでファイルを出力する

この記事の所要時間: 545

ApacheでX-Sendfileが利用できるmod_xsendfileをPHPと連携して使ってみました。

PHPで認証してから、許可したユーザのみにファイルを出力する、という処理を実装する場合、ファイルはdocument_root外に配置しておいて、readfile()やfpassthru()でファイルを出力するという手法を良く使います。

この方法でも問題無い場合が多いのですが、容量の大きいファイルを出力する際は思ったようなスピードが出ない時があります。

そのような時はmod_xsendfileを使って、ファイル出力の部分をApacheに任せてしまう方法が有効です。

ここでは2010/11/12時点の最新版であるmod_xsendfile 0.12を対象としています。またインストール環境はRHEL、CentOSを想定しています。

mod_xsendfileのインストール

mod_xsendfileはApache2/2.2で動作するモジュールです。

インストールにあたって、apxsコマンドが必要となるので、もしインストールしていない場合はyum等でインストールします。(apxsは、RPMならhttpd-develパッケージに含まれています)

% sudo yum install httpd-devel

次にmod_xsendfileをダウンロードします。mod_xsendfileは、mod_xsendfile.cという1ファイルだけなので、それをダウンロードしてインストールします。

ブラウザからダウンロードする際は問題無いのですが、wgetでダウンロードしようとすると証明書エラーが発生します。–no-check-certificateオプションを付けるとこのエラーを避けることができます。

% wget --no-check-certificate https://tn123.org/mod_xsendfile/mod_xsendfile.c

apxsでmod_xsendfileをインストールします。

% sudo /usr/sbin/apxs -cia mod_xsendfile.c

インストールと共にhttpd.confにLoadModuleが追加されます。

[/etc/httpd/conf/httpd.conf]

LoadModule xsendfile_module   /usr/lib/httpd/modules/mod_xsendfile.so

mod_xsendfileを設定する

mod_xsendfileを利用するために設定を行います。

httpd.confでXSendFilePathを指定する

まず、XSendFilePathで出力を許可するパスを指定します。mod_xsenfileではdocument_root外のファイルを出力することができるので、誤って意図しないファイルの出力を避けるために出力対象のパスを指定する必要があります。

例えば、出力するファイルは「/path/to/images」以下にあるなら以下のように指定します。

[/etc/httpd/conf/httpd.conf]

XSendFilePath /path/to/images

XSendFilePathは、VirtualHostやDirecortyディレクティブでも指定が可能です。Directoryディレクティブでは実行するPHPファイルのパスを指定できます。例えば、CakePHPで指定するなら以下のようになります。(出力ファイルがapp/data以下にあるとします。)

[/etc/httpd/conf/httpd.conf]


  XSendFilePath /path/to/app/data

XSendFileをonにする

次にXSendFileをonに設定します。これによりX-Sendfileが有効となります。

/etc/httpd/conf*な設定ファイルでも記載できるのですが、アプリ側ファイルの方が都合が良いので、.htaccessに設定を書いておきます。

[/path/to/app/webroot/.htaccess]


    XSendFile on

これで設定は完了です。あとはPHPから出力するファイルを指定します。

XSendFileAllowAboveは削除

なおmod_xsendfile0.9ではXSendFileAllowAboveという設定項目があったのですが、これは0.10で削除されたようです。記載しているとエラーになるのでご注意を。

PHPから出力するファイルを指定

mod_xsendfileと使って、PHPからファイルを出力するにはX-Sendfileヘッダで出力ファイルパスを指定します。

下記のようにreadfile()を記載していた箇所(下から2行目)を、X-Sendfileを出力するheader()に書き換えます。

これでmod_xsendfileからファイルが出力されます。

ちょっと気になったこと

X-Sendfileヘッダは外部に出力される?

X-Sendfileヘッダには出力ファイルのパスを指定するので、外部に出力されるのはあまり好ましいことではありません。mod_xsendfileの処理が有効になっていれば、このヘッダは除去され外部には出力されないようになっています。

0バイトのファイルが出力される

X-Sendfileヘッダで指定したファイルパスが、XSendFilePathで指定したパスにマッチしないと0バイトになるようです。必要であれば、XSendFilePathにファイルパスを追加しましょう。

404が発生する

X-Sendfileヘッダで指定したファイルが存在しない場合は404になります。

PHP以外でも使える?

X-Sendfileヘッダをレスポンスヘッダに出力できれば良いので、PHP以外でも利用できるようです。

Apacheで使えるX-Sendfile

数年前にこんなエントリも書いたりしていたのですが、たしか当時はApacheでの実装は無かったと思います。

なんとなくそのままのイメージでいたので、Lighttpd(nginxにも似た機能があったような。X-Accel-Redirectかな。)いいなあと思ってたら、実は結構前からApacheでもできるようになったんですね。

この認証ロジックはPHP、出力はmod_xsendfileと、それぞれ得意な分野に分けるのは、Unixっぽくて好きです。

Pocket

follow us in feedly

トラックバック:1

このエントリーのトラックバックURL
/blog/2010/11/php_to_mod_xsendfile.html/trackback
Listed below are links to weblogs that reference
PHPで認証して、mod_xsendfileでファイルを出力する from Shin x blog
pingback from Bookmarks for 11月 17th through 11月 19th « bulblub 10-11-19 (金) 17:26

[…] PHPで認証して、mod_xsendfileでファイルを出力する – Shin x blog – […]

Home > CakePHP | PHP | unix > PHPで認証して、mod_xsendfileでファイルを出力する

検索
フィード
メタ情報

Return to page top