手軽に出来るApacheモジュール開発
こんにちは、アシアルの井川です。
今日はApacheモジュール開発方法を紹介したいと思います。難しそうに聞こえるかもしれませんが、Apacheのツール(apxs)を使うので意外と簡単に作成できます。また、今回作成するのは"hello world"をHTMLの先頭に加えるだけのシンプルなモジュールです。
本当に簡単なので、ぜひ一度作ってみて下さい。
開発の流れは次の通りです。
0. 開発環境の準備
1. モジュールのひな形の作成
2. コードの記述(C言語)
3. コンパイルしてインストール
4. httpdの再起動
開発環境は既にできている前提で話を進めます。必要なパッケージは
・httpd
・httpd-devel
・gcc
であり、検証環境は次の通りです。
・CentOS 5.5
・Apache 2.2.3
ただし、httpdにso_moduleが組み込まれている必要があります。次のコマンドを実行し、実行結果に"mod_so.c"が入っていれば大丈夫です。
> /usr/sbin/httpd -l
[実行結果例]
core.c
prefork.c
http_core.c
mod_so.c
① モジュールのひな形作成
まずは、apxsを使ってひな形を作りましょう。適当なディレクトリに移動して、次のコマンドを実行します。
> /usr/sbin/apxs -g -n hello_world
(-g:テンプレート生成、-n:モジュール名指定)
[実行結果]
Creating [DIR] hello_world
Creating [FILE] hello_world/Makefile
Creating [FILE] hello_world/modules.mk
Creating [FILE] hello_world/mod_hello_world.c
Creating [FILE] hello_world/.deps
これでhello_worldディレクトリが作 成されました。そのディレクトリへ移動します。
② コードの記述(C言語)
次に、生成されたソースコード(mod_hello_world.c)を見てみましょう。
#include "httpd.h"#include "http_config.h"#include "http_protocol.h"#include "ap_config.h" /* The sample content handler */static int hello_world_handler(request_rec *r){ if (strcmp(r->handler, "hello_world")) { return DECLINED; } r->content_type = "text/html"; if (!r->header_only) ap_rputs("The sample page from mod_hello_world.c\n", r); return OK;} static void hello_world_register_hooks(apr_pool_t *p){ ap_hook_handler(hello_world_handler, NULL, NULL, APR_HOOK_MIDDLE);} /* Dispatch list for API hooks */module AP_MODULE_DECLARE_DATA hello_world_module = { STANDARD20_MODULE_STUFF, NULL, /* create per-dir config structures */ NULL, /* merge per-dir config structures */ NULL, /* create per-server config structures */ NULL, /* merge per-server config structures */ NULL, /* table of config file commands */ hello_world_register_hooks /* register hooks */};
関数の役割は次の通りです。
hello_world_handler:実際の処理をするハンドラ
hello_world_register_hooks:ハンドラをフックポイントに登録する関数
今回はHTMLファイルに"hello_world"を追加したいので、hello_world_handlerを次のように修正します。
static int hello_world_handler(request_rec *r){ if (!strcmp(r->content_type, "text/html") && !r->header_only) { ap_rputs("hello world<br />\n", r); } return DECLINED;}
ここで、request_recはHTTPリクエストを表した構造体です。r->content_typeはContent-Typeヘッダであり、r->header_onlyはHEADリクエストか否かを示します。また、ap_rputs()はコンテンツを出力する関数です。ハンドラの戻り値にも意味があり、DECLINEDを返すと、Apacheは次のモジュールに処理を委譲します。
つまり、上記のコードでは、Content-Typeがtext/htmlで、HEADリクエストでない場合、"hello world"を追加して、Apacheの処理を続行します。
③ コンパイ ルしてインストール
では、さっそくコンパイルしてインストールしてみましょう(root権限もしくはsudoで実行)。
[コンパイルとインストールを同時に実行]
> /usr/sbin/apxs -i -a -c mod_hello_world.c
[別々に実行]
コンパイル > /usr/sbin/apxs -c mod_hello_world.c
インストール> /usr/sbin/apxs -i -a -n 'hello_world' mod_hello_world.la
(インストールが終わったら、make cleanしておく)
インストール後にhttpd.confを確認すると、
LoadModule hello_world_module /usr/lib/httpd/modules/mod_hello_world.so
という一文が追加されていると思います(なかったら追加して下さい)。これで準備は完了です。
④ httpdの再起動
Apacheを再起動します。
> /sbin/service httpd restart
ブラウザでサーバ内の適当なファイルへアクセスして下さい。先頭に"hello world"の一文がついているでしょうか?
と、こんな感じで作成できます。
これだけだとメリットが見えませんが、C言語による処理ですので非常に高速に動作するため、DBやmemcachedとの通信を加えると、大量のリクエストを高速に処理することも可能です。
ぜひ、一度試し、次のステップへとつなげて下さい。