こんにちは。
普段まだまだ業務でも使う機会の多い Apache ですが、そういえばモジュール周りってどういう風に実装されているんだろうと調べてみた備忘録です。
雛型自体は apxs コマンドで自動的に生成されるそうなので、接続元 IP アドレスの JSON を返すだけの API みたいなよく分からない Apache モジュールを作ってみます。
※ PHP だったら下記2行で終わるんですけどね。
<?php $json = ['remote_ip' => $_SERVER["REMOTE_ADDR"]]; echo json_encode($json);
環境構築
はい、勿論Apacheのモジュールなんで、Apacheの本体と、apxsコマンドを使うので開発ツールを導入します。
ただそれだけ~。
yum groupinstall "Development tools" yum install httpd httpd-devel
apxsコマンドで雛型を作ります。
cd /usr/local/src apxs -g -n info cd info/
下記みたいなディレクトリとファイルが生成されるんで、mod_info.c に処理を書いていきます。
[root@test-server1-1 src]# tree . └── info ├── Makefile ├── mod_info.c └── modules.mk 1 directory, 3 files
コード
はい、雛型に1行加えただけです…
#include "httpd.h" #include "http_config.h" #include "http_protocol.h" #include "ap_config.h" /* The sample content handler */ static int info_handler(request_rec *r) { if (strcmp(r->handler, "info")) { return DECLINED; } r->content_type = "text/html"; if (!r->header_only) { /* 接続元IPを表示する */ ap_rprintf(r,"{\"client_ip\":\"%s\"}\n",r->connection->client_ip); } return OK; } static void info_register_hooks(apr_pool_t *p) { ap_hook_handler(info_handler, NULL, NULL, APR_HOOK_MIDDLE); } /* Dispatch list for API hooks */ module AP_MODULE_DECLARE_DATA info_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 */ info_register_hooks /* register hooks */ };
接続元 IP は構造体のポインタ r , connection のメンバである client_ip に格納されているので、ap_rprintf 関数でこれを表示させます。
/** *Output data to the client in a printf format * *@Parameters * r The current request * fmt The format string * ... The arguments to use to fill out the format string * *@Returns * The number of bytes sent */ int ap_rprintf( request_rec * r, const char * fmt, ... )
コンパイル
こちらも apxs コマンドでモジュールのコンパイルと Apache へのモジュールのロード設定まで自動で完了します。
# ディレクトリ移動&コンパイル cd /usr/local/src/info apxs -c -i -a mod_info.c # Apache設定追加 cat >> /etc/httpd/conf/httpd.conf << EOF <Location "/info"> SetHandler info </Location> EOF # Apache起動 systemctl start httpd
curl で叩いたら json が返ってきますね。OKです。
keisuke@DESKTOP-MOGIJIA:~$ curl http://192.168.33.10/info {"client_ip":"192.168.33.1"}