アプリケーション開発ポータルサイト
ServerNote.NET
Amazon.co.jpでPC関連商品タイムセール開催中!
カテゴリー【ApacheDebianC/C++RedisPostgreSQL
DebianでApache2.4モジュールを自作してRedis/PostgreSQLに接続する
POSTED BY
2023-07-24

前回はまず何もいじらないでそのままテンプレートモジュールを動かしたが、当然ながら実践ではmod_mytest.cのなかで、様々な外部ライブラリと連携した処理を書くことになる。

今回、そのなかでRedisのC言語ライブラリhiredis、PostgreSQLのC言語ライブラリlibpqを組み込んで接続、切断をしてみる。これができれば似た他のすべての処理を自作モジュールのなかで行えるはずである。

hiredisをソースコードからインストールすると、ヘッダファイルは/usr/local/include/hiredisに、ライブラリファイルは/usr/local/lib/libhiredis.soとなる。何もせずに自作Apacheモジュールでこれを使おうとすると、Apache再起動時のモジュール読み込み時にUndefined Symbolとなってしまう。

これはapxs2コマンドでビルドするとき、パスを指定してあげれば解決する。

ひとまず、以下のように、redis,postgresql両方に接続して、そのまま切断するmod_mytest.cに改造した。

C/C++mod_mytest.cGitHub Source
/* 
**  mod_mytest.c -- Apache sample mytest module
**  [Autogenerated via ``apxs -n mytest -g'']
**
**  To play with this sample module first compile it into a
**  DSO file and install it into Apache's modules directory 
**  by running:
**
**    $ apxs -c -i mod_mytest.c
**
**  Then activate it in Apache's apache2.conf file for instance
**  for the URL /mytest in as follows:
**
**    #   apache2.conf
**    LoadModule mytest_module modules/mod_mytest.so
**    <Location /mytest>
**    SetHandler mytest
**    </Location>
**
**  Then after restarting Apache via
**
**    $ apachectl restart
**
**  you immediately can request the URL /mytest and watch for the
**  output of this module. This can be achieved for instance via:
**
**    $ lynx -mime_header http://localhost/mytest 
**
**  The output should be similar to the following one:
**
**    HTTP/1.1 200 OK
**    Date: Tue, 31 Mar 1998 14:42:22 GMT
**    Server: Apache/1.3.4 (Unix)
**    Connection: close
**    Content-Type: text/html
**  
**    The sample page from mod_mytest.c
*/ 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <hiredis/hiredis.h>
#include <postgresql/libpq-fe.h>

#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"
#include "ap_config.h"
#include "http_log.h"

/* The sample content handler */
static int mytest_handler(request_rec *r)
{
  redisContext *rdconn;
  PGconn *pgconn;

    if (strcmp(r->handler, "mytest")) {
        return DECLINED;
    }
    r->content_type = "text/html";      

    if (!r->header_only){
        ap_rputs("The sample page from mod_mytest.c\n", r);

    rdconn = redisConnect("127.0.0.1", 6379);
    if (!rdconn) {
      ap_rputs("redisConnect error\n", r);
      return OK;
     }
    if (rdconn->err) {
      ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r,"%s", rdconn->errstr);
      ap_rputs("redisConnect error\n", r);
      redisFree(rdconn);
      return OK;
    }

    pgconn = PQconnectdb( "host=127.0.0.1 port=5432 dbname=ekidb" );
    if(!pgconn || PQstatus( pgconn ) == CONNECTION_BAD ){
      ap_rputs("PQconnectdb error\n", r);
      if(pgconn){
        PQfinish(pgconn);
      }
      redisFree(rdconn);
      return OK;
    }

    ap_rputs("redisConnect/PQconnectdb SUCCESS\n", r);

    PQfinish(pgconn);
    redisFree(rdconn);
  }

    return OK;
}

static void mytest_register_hooks(apr_pool_t *p)
{
    ap_hook_handler(mytest_handler, NULL, NULL, APR_HOOK_MIDDLE);
}

/* Dispatch list for API hooks */
module AP_MODULE_DECLARE_DATA mytest_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       */
    mytest_register_hooks  /* register hooks                      */
};

redisConnectの詳細エラーログがある場合Apacheのログに出すようにしている。
それ以外はブラウザへ返す文字列にエラーまたは成功を追記して終了。

以下のようにコンパイルするのがポイント。

apxs2 -I/usr/local/include -L/usr/local/lib -lhiredis -lpq -c mod_mytest.c

/usr/local/libにライブラリパスを通して使用ライブラリを宣言してコンパイルする。

インストール、Apache再起動に変更はなし。

sudo apxs2 -i -a -n 'mytest' mod_mytest.la

sudo /etc/init.d/apache2 restart

エラーが出なければ、ちゃんと/usr/local/lib/libhiredis.soが組み込まれている。

あとは前回と変更なく下記URI設定になっているとして、

<VirtualHost *:80>
(中略)
    <Location "/mytest">
        SetHandler mytest
    </Location>
</VirtualHost>

http://192.168.1.55/mytest

などと打って

The sample page from mod_mytest.c redisConnect/PQconnectdb SUCCESS

と表示されれば、自作モジュールでredisConnect、PQconnectdbができており、あらゆる処理ができることとなる。

※本記事は当サイト管理人の個人的な備忘録です。本記事の参照又は付随ソースコード利用後にいかなる損害が発生しても当サイト及び管理人は一切責任を負いません。
※本記事内容の無断転載を禁じます。
【WEBMASTER/管理人】
自営業プログラマーです。お仕事ください!
ご連絡は以下アドレスまでお願いします★

☆ServerNote.NETショッピング↓
ShoppingNote / Amazon.co.jp
☆お仲間ブログ↓
一人社長の不動産業務日誌
【キーワード検索】