Apache Module メモ
※この記事は2.x系前提。概ね2.4。
What is Apache Module
可変長リストやkey-valueのハッシュテーブルなど、C言語らしからぬリッチな機能が一通りそろっておりC言語と言えど効率的に開発できる。 Apacheモジュール開発に許された特権。 メモリプールをがばっと確保して解放するということをApache側が勝手にやってくれるのでメモリ管理もかなり楽。 そしてなによりCなので高速に動作する。
メモ
おおざっぱに分かっておくとよい事
httpd起動時に準備をしている
主に認識しておくとよいのは以下。
- confの読み込み
- 子プロセスのfork, 設定
- リクエスト処理ループに入る
リクエスト処理ループ
httpリクエストを受け取ったら入る処理フロー。この処理フローのどこかに到達したらモジュールが動作するように設定できる。
Apacheはモジュールの集合体である
これは忘れがちなので覚えておく
ディレクティブはモジュールの設定である
Apacheはモジュールの集合体であることを踏まえると、confはApacheに対する設定ではなくディレクティブに紐づく各モジュールに対する設定と認識する。
お手軽な作り方
CentOS系を想定
必要なrpmを入れる
yum install httpd httpd-devel
testモジュールを生成する
apxs -g -n test
MakeFile, modules.mk, mod_test.cの3つが生成される。
コンパイルする
apxs -c -i -a mod_test.c
基本的には動的リンクを用いた動的組み込みをしたほうがよいため、loadmoduleディレクティブを追加するべく -a オプションをつけてコンパイルしている。 既にLoadModuleを追加している場合は重複が発生してエラーになるようなので注意。
httpd.confにLocationを追加する
<Location "/hoge/"> SetHandler test </Location>
リクエストしてみる
curl "http://localhost/hoge/"
The sample page from mod_test.cと帰ってきたら成功。
自動生成したmod_test.cのコメントに書かれているとおりlynxを使っても良い
lynx -mime_header http://localhost/hoge/
mod_○○.cのざっくり全体構成
ヘッダインクルード 設定情報を保持する変数を作成する関数(ここで初期化) 設定情報を更新する関数(コマンドの配列とセットで定義) コマンドの配列(ディレクティブで定義している設定情報を読み込むための関数や、ディレクティブの構造を指定) フックに登録したい関数たち(フックをかけるタイミングがわかるように名前を定義するとよい) フックに実際に登録する関数 ↑で定義してきたものをディスパッチするための配列
ログ周り
ログフォーマット
カスタムログ
良くやるのが以下(上記リンクより引用)
LogFormat "%h %l %u %t \"%r\" %>s %b" common CustomLog logs/access_log common
LogFormatを決めてnicknameを名付ける(ここではcommon)。 CostomLogで既に定義したLogFormatを読み込み、指定したディレクトリにログファイルを生成する。 commonのところにLogFormatが展開されている感じ。
本格的に使っていくなら例えば以下のようにしてログローテートさせる。
CustomLog "|/usr/local/apache/bin/rotatelogs /var/log/access_log 86400" common env=common_env SetEnvIf Request_URI "^/hoge$" common_env
env=common_envのところは、CutomLogを用いてログ収集をするのかを決めるための判断軸。 右辺に指定した環境変数が存在する場合にログを落とす。 その環境変数はSetEnvIfを使って指定している。この場合、/hogeに完全一致するURIでリクエストが来ていたらcommon_env環境変数をセットするようにしてある。これによりどのリクエストのログを落とすのかの分岐が可能。
rotatelog
以下を参照。-c -L -l あたりは良く使うはず。 httpd.apache.org
参考になるモジュール
コメントもしっかり書いてあるので勉強になる。 github.com