前回は後半inetdを利用したインチキWebサーバを作りましたが、今回は由緒正しいWebサーバであるApache httpdのモジュールでhello worldをやってみたいと思います。
「apacheモジュールを書くなんて難しそう」と思ったあなた、大丈夫です。死ぬほど簡単です。
●準備: apxs のインストール
まずhttpdがインストールされたマシンにapxsコマンドをインストールしましょう。
FreeBSD を使っている場合は、ports/packagesでhttpdをインストールしていれば、apxsコマンドもすでにインストールされているはずです。
Linux を使っている場合は、httpdがインストールされていても
kt@ume% which apxs
などで見つからなければ、インストールする必要があります。REHL系であれば、httpd-develというRPMをインストールしましょう。
root@ume# yum install -y httpd-devel
Loaded plugins: refresh-packagekit
(略)
●雛形のモジュールを生成
apxsはapacheモジュール開発者向けのビルド&インストールツールですが、モジュールの雛形を生成する機能があります。
kt@ume% apxs -g -n hello
Creating [DIR] hello
Creating [FILE] hello/Makefile
Creating [FILE] hello/modules.mk
Creating [FILE] hello/mod_hello.c
Creating [FILE] hello/.deps
上記の -g オプションが雛形生成の指示、-nの引数が新しいモジュールの名前になります。
生成された hello/mod_hello.c の中程に ap_rputs() を呼び出している箇所がありますので、その中の第一引数を書き換えます。
例えば以下のように編集します。
kt@ume% cd hello
kt@ume% vi mod_hello.c
kt@ume% diff -u mod_hello.c.orig mod_hello.c
--- mod_hello.c.orig 2009-08-23 03:37:25.000000000 +0900
+++ mod_hello.c 2009-08-23 03:39:34.000000000 +0900
@@ -51,7 +51,7 @@
r->content_type = "text/html";
if (!r->header_only)
- ap_rputs("The sample page from mod_hello.c\n", r);
+ ap_rputs("hello world!\n", r);
return OK;
}
●コンパイル
編集が終わったら makeでコンパイルしましょう。
kt@ume% make
/usr/lib64/apr-1/build/libtool --silent --mode=compile gcc -pthread -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -DLINUX=2 -D_REENTRANT -D_GNU_SOURCE -I/usr/include/httpd -I. -I/usr/include/apr-1 -I/usr/kerberos/include -prefer-pic -c mod_hello.c && touch mod_hello.slo
/usr/lib64/apr-1/build/libtool --silent --mode=link gcc -pthread -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -L/usr/kerberos/lib64 -Wl,-z,relro -o mod_hello.la -rpath /usr/lib64/httpd/modules -module -avoid-version mod_hello.lo
エラーになってしまった場合は、apxs -cを手動で実行しましょう。
(私の環境ではFreeBSD上で生成してmakeするとエラーになってしまいました)
kt@matsu% apxs -c mod_hello.c
/usr/local/build-1/libtool --silent --mode=compile cc -prefer-pic -O2 -fno-strict-aliasing -pipe -I/usr/local/include/mysql -DHAVE_MYSQL_H -I/usr/include -DLDAP_DEPRECATED -I/usr/local/include/apache22 -I/usr/local/include/apr-1 -I/usr/local/include/apr-1 -I/usr/local/include -c -o mod_hello.lo mod_hello.c && touch mod_hello.slo
/usr/local/build-1/libtool --silent --mode=link cc -o mod_hello.la -rpath /usr/local/libexec/apache22 -module -avoid-version mod_hello.lo
●インストール
コンパイルできたら root で make install します。
kt@ume% su -
=====================================================================================================================
>> Welcome to ume.local
=====================================================================================================================
There are 6 user(s) logged in.
root@ume# cd /home/kt/tmp/hello
root@ume# make install
make[1]: Entering directory `/a/fuji/home/kt/tmp/hello'
/usr/lib64/apr-1/build/libtool --silent --mode=install cp mod_hello.la /usr/lib64/httpd/modules/
make[1]: Leaving directory `/a/fuji/home/kt/tmp/hello'
/usr/lib64/apr-1/build/libtool --silent --mode=install cp mod_hello.la /usr/lib64/httpd/modules/
エラーになってしまう場合は、やはりapxs -i を実行してインストールを試してみてください。
kt@matsu% su -
=====================================================================================================================
>> Welcome to matsu.local
=====================================================================================================================
There are 2 user(s) logged in.
root@matsu# cd /home/kt/hello
root@matsu# apxs -i -a mod_hello.la
/usr/local/share/apache22/build/instdso.sh SH_LIBTOOL='/usr/local/build-1/libtool' mod_hello.la /usr/local/libexec/apache22
/usr/local/build-1/libtool --mode=install cp mod_hello.la /usr/local/libexec/apache22/
cp .libs/mod_hello.so /usr/local/libexec/apache22/mod_hello.so
cp .libs/mod_hello.lai /usr/local/libexec/apache22/mod_hello.la
cp .libs/mod_hello.a /usr/local/libexec/apache22/mod_hello.a
chmod 644 /usr/local/libexec/apache22/mod_hello.a
ranlib /usr/local/libexec/apache22/mod_hello.a
----------------------------------------------------------------------
Libraries have been installed in:
/usr/local/libexec/apache22
If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
- add LIBDIR to the `LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the `LD_RUN_PATH' environment variable
during linking
- use the `-Wl,--rpath -Wl,LIBDIR' linker flag
See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
chmod 755 /usr/local/libexec/apache22/mod_hello.so
[activating module `hello' in /usr/local/etc/apache22/httpd.conf]
●設定&動作確認
インストールが終わったらhttpdの設定ファイルにmod_helloの設定を加えます。
設定すべき内容は、mod_hello.cの冒頭のコメント部分に記載されています。
root@ume# head -n 20 mod_hello.c
(中略)
** Then activate it in Apache's httpd.conf file for instance
** for the URL /hello in as follows:
**
** # httpd.conf
** LoadModule hello_module modules/mod_hello.so
** <Location /hello>
** SetHandler hello
** </Location>
**
** Then after restarting Apache via
RHEL系Linux であれば /etc/httpd/conf.d/hello.conf などに新しくmod_hello用の設定ファイルを置くのが良いでしょう。
FreeBSD の www/apache22 であれば、/usr/local/etc/apache22/Includes/hello.conf になります。
root@ume# cat > /etc/httpd/conf.d/hello.conf
LoadModule hello_module modules/mod_hello.so
<Location /hello>
SetHandler hello
</Location>
httpd をリスタートします。
root@ume# /etc/init.d/httpd restart
Stopping httpd: [ OK ]
Starting httpd: [ OK ]
これで作業は終了です。お好みのブラウザで設定したURLへアクセスしてみてください。
kt@ume% wget -q -O - http://ume.local/hello/
hello world!
このように「hello world!」と表示されたら成功です。
ね?簡単でしょ?
●おわりに
前回の記事を読んで、「いまさらWebサーバをスクラッチから書くやつなんていねーよ」と思ったあなた、今回のような apacheモジュールなどはいかがでしょうか?
これさえマスターしておけば、IT企業への就職活動などの場において「特技はプログラミング?ていうかapacheモジュール書いてました」と言い張れますね!
ただし、相手によっては「apacheモジュール?何それおいしいの?」となるので注意が必要です!
つづく!
0 件のコメント:
コメントを投稿