Compiler et installer un module custom en C pour Apache2 sous Debian
Pour réaliser un module Apache, le plus simple est de créer un module dynamique (DSO, pour Dynamic Shared Object), un poil moins efficace qu'un module statique mais pour la phase de mise au point c'est tout de même largement plus cool, et je dirais même pour la suite, plus facile à installer; tout ça reste au final une question de goût.
Notre principal outil sera l'utilitaire Apxs (Apxs2 pour Apache2) qui s'occupera de générer notre module au bon format, à partir de notre fichier source en C.
Pour installer apxs/apxs2:
apt-get install apache2-dev
apxs et apxs2 sont installés dans /usr/bin
Vérifions que le module "so" est bien chargé dans notre Apache2, avec la commande suivante:
apache2ctl -M
Si on voit bien "so_module", tout va bien. Sinon, il va falloir l'activer mais on sortirait du cadre de ce tuto, normalement ce module est de toutes manières activé par défaut.
Comme Apxs2 est super cool, on peut lui demander de nous générer un template déjà tout prêt pour démarrer notre nouveau module. J'aimerais créer un module pour interpréter les fichiers avec l'extension '.page', j'appelle donc mon module 'page', dont le fichier final sera 'mod_page.so':
/usr/bin/apxs2 -g -n page
Un nouveau répertoire est créé dans le répertoire courant, avec tous les fichiers nécessaires:
Creating [DIR]  page
Creating [FILE] page/Makefile
Creating [FILE] page/modules.mk
Creating [FILE] page/mod_page.c
Creating [FILE] page/.deps
Voyons un peu le source de notre template prêt-à-compiler:
/*
**  mod_page.c -- Apache sample page module
**  [Autogenerated via ``apxs -n page -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_page.c
**
**  Then activate it in Apache's apache2.conf file for instance
**  for the URL /page in as follows:
**
**    #   apache2.conf
**    LoadModule page_module modules/mod_page.so
**    <Location /page>
**    SetHandler page
**    </Location>
**
**  Then after restarting Apache via
**
**    $ apachectl restart
**
**  you immediately can request the URL /page and watch for the
**  output of this module. This can be achieved for instance via:
**
**    $ lynx -mime_header http://localhost/page
**
**  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_page.c
*/

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

/* The sample content handler */
static int page_handler(request_rec *r)
{
    if (strcmp(r->handler, "page")) {
        return DECLINED;
    }
    r->content_type = "text/html";

    if (!r->header_only)
        ap_rputs("The sample page from mod_page.c\n", r);
    return OK;
}

static void page_register_hooks(apr_pool_t *p)
{
    ap_hook_handler(page_handler, NULL, NULL, APR_HOOK_MIDDLE);
}

/* Dispatch list for API hooks */
module AP_MODULE_DECLARE_DATA page_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       */
    page_register_hooks  /* register hooks                      */
};
Voyons un peu si tout se passe bien, on entre dans le nouveau répertoire et on lance une compilation:
cd page
apxs2 -c -i mod_page.c
Voyons le résultat:
root@lorien:~/page# apxs2 -c -i mod_page.c
/usr/share/apr-1.0/build/libtool --silent --mode=compile --tag=disable-static x8
6_64-linux-gnu-gcc -std=gnu99 -prefer-pic -pipe -g -O2 -fstack-protector-strong
-Wformat -Werror=format-security  -D_FORTIFY_SOURCE=2   -DLINUX -D_REENTRANT -D_
GNU_SOURCE  -pthread  -I/usr/include/apache2  -I/usr/include/apr-1.0   -I/usr/in
clude/apr-1.0 -I/usr/include  -c -o mod_page.lo mod_page.c && touch mod_page.slo
/usr/share/apr-1.0/build/libtool --silent --mode=link --tag=disable-static x86_6
4-linux-gnu-gcc -std=gnu99 -Wl,--as-needed -Wl,-z,relro -Wl,-z,now    -o mod_pag
e.la  -rpath /usr/lib/apache2/modules -module -avoid-version    mod_page.lo
/usr/share/apache2/build/instdso.sh SH_LIBTOOL='/usr/share/apr-1.0/build/libtool
' mod_page.la /usr/lib/apache2/modules
/usr/share/apr-1.0/build/libtool --mode=install install mod_page.la /usr/lib/apa
che2/modules/
libtool: install: install .libs/mod_page.so /usr/lib/apache2/modules/mod_page.so
libtool: install: install .libs/mod_page.lai /usr/lib/apache2/modules/mod_page.l
a
libtool: finish: PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/
bin:/sbin" ldconfig -n /usr/lib/apache2/modules
----------------------------------------------------------------------
Libraries have been installed in:
   /usr/lib/apache2/modules

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
   - have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
chmod 644 /usr/lib/apache2/modules/mod_page.so
Comme on peut le voir, notre nouveau module a été directement installé par Apxs2 dans la hiérarchie de fichiers Apache2.
Il faut maintenant dire à Apache2 comment utiliser notre module. Créons pour cela un fichier de configuration "/etc/apache2/conf-available/page_module.conf":
LoadModule page_module "/usr/lib/apache2/modules/mod_page.so"
AddHandler page_module .page
Et activons-le par la commande a2enconf:
a2enconf page_module.conf
Et on relance Apache2 pour lui faire prendre en compte tout ça:
service apache2 restart
Voilà, appelons une url sur notre serveur avec une extension en .page et l'on obtient bien:
The sample page from mod_page.c
Il ne reste qu'à développer notre module custom réel à partir de ce point de départ, mais cela est une autre histoire.