ブラウザでURL画像をクリックしたら、php起動したい
画像のURLをクリックすると、WEBサーバから画像が送信される。当たり前のことですが、この当たり前の処理に、ハンドラを加えてプログラムを追加したいと思います。
http://example.com/img/top_banner.jpg
通常処理の場合
WEBサーバーは次の処理をする。
- URLにリクエスト来る
- URL からOSパスに変換する。
- 該当パスのファイルを実行して返す
Apacheのモジュールや設定はそれぞれ段階で処理を挟みますよね。
- mod_rewrite は リクエストを書換
- < Location> はOSパス変換をスキップ
- .htaccess チェックは OS パス変換
- Allows は該当ファイルの実行時に
- 実行はhandler に任せる。またはファイル中身を送信
今回はハンドラを追加して、バイナリを処理する
画像を自動変換する、画像の直リンク(リファラ・セッション)をチェックなど。
これらを使ってApacheのハンドラを見なおしてみる。
画像URLをPHPで処理する基本的な考え方
次の流れで、JPGファイルを送信するのではなく、間にハンドラを挟むところ。
- http://example.jp/img/top_banner.jpg にリクエストが来る
- /var/www/example.jp/img/banner.jpg に変換
- 拡張子.jpgに jpg_hander (cgi-bin) が登録されている
- jpg_handler を実行して中身を送信。
ポイントは jpg にハンドラ(関連付け)を行う。その実行する関連付けるプログラムを自分で書こうってはなし。
Apacheのハンドラは拡張子毎に登録します。ApacheがOSと変わらん動作をするのでチャント使うと便利ってことです。
最初にハンドラを用意します。
Apache の設定側に ScriptAliasを設定。設定ディレクトリにCGI実行を許可する。
ScriptAlias "/cgi-bin/" "/var/www/example.com/cgi-bin/" <Directory /var/www/example.com/cgi-bin/> # AllowOverride None Addhandler application/x-httpd-php .php Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch Order allow,deny Allow from all </Directory>
許可したディレクトリに、独自のハンドラを追加。Apacheリロード。
$ cd /var/www/example.com/cgi-bin/ $ echo "<?php phpinfo();" > info.php
念のため、単体でphpが実行できることを確認
curl -v http://example.com/cgi-bin/info.php | grep _SERVER["SCRIPT_FILENAME"] /var/www/example.com/cgi-bin/info.php
これで準備終わり。はい簡単です。
拡張子JPGを、作成した info.php で処理移譲するハンドラ設定をします。
Action my_sample /cgi-bin/info.php AddHandler my_sample .jpg
Actionで my_sample という名前で/cgi-bin/info.php を登録する 拡張子JPGを処理するのを my_sample ハンドラに設定する。
この設定を好きな場所(htaccess / directory / conf ) に記述すればオッケ。
今回は.htaccessで /var/www/example.com/img/.htaccess に書いた。
完成したら、jpg にアクセスしてみる
curl -v http://example.com/img/sample.jpg | grep _SERVER["SCRIPT_FILENAME"]
出来た。これで指定の拡張子を任意のプログラムでApache実行できることがわかるね。
リクエストが来たファイル名はPATH_INFOでわかるね。
自分でプログラムを書いてそれで処理できる。それがCGI
CGIの仕組みは、自分でプログラムを書いて、そのプログラムを指定拡張子に関連付け、またはディレクトリを関連付けが本来の姿だった。
そのプログラムをphp / ruby / clang で記述すればいいわけですよね。
画像処理するCGIの例
画像やバイナリを関連付けで、処理するのにはいくつか便利な方法がある
- 画像のリサイズ
- 画像のリファラチェック
- 画像の直リンク時にHTMLを表示する
一番大きいのは GET引数が使えること
http://example.com/img/sample.jpg?width=100
次に大きいのはリクエスト引数の文字列を使わなくてイイ
Apache側でファイルの存在確認と実行確認、パーミッションチェックまでヤってくれる。
http://example.com/show_img.php?path=sample.jpg&width=100
このような、ファイルの処理にまつわる処理を安全にできる。
パス変換やファイル存在チェックまではapahce側に依存できる。自分でプログラム書いたりフレームワークに頼らなくていい。ディレクトリ・トラバーサル脆弱性などに対応できうる。
php'er フレームワーク使いすぎ問題。CGIでいい。
ファイル処理くらい1枚のCGIで終わるものを、フレームワークかいてテストって意味なくね?
アップロード・ファイル処理する系はCGIが強いです。