Perhaps the most important part of an Apache module is the
module
structure. This is defined in
http_config.h, so all modules should start
(apart from copyright notices, etc.) with the following lines:
#include "httpd.h" #include "http_config.h"
Note that httpd.h is required for all Apache source code.
What is the module
structure for? Simple: it
provides the glue between the Apache core and the
module’s code. It contains pointers (to functions,
lists, and so on) that are used by components of the core at the
correct moments. The core knows about the various
module
structures because they are listed in
modules.c, which is generated by the
Configure script from the
Configuration file.[2]
Traditionally, each module ends with its module
structure. Here is a particularly trivial example, from
mod_asis.c (1.3):
module asis_module = { STANDARD_MODULE_STUFF, NULL, /* initializer */ NULL, /* create per-directory config structure */ NULL, /* merge per-directory config structures */ NULL, /* create per-server config structure */ NULL, /* merge per-server config structures */ NULL, /* command table */ asis_handlers, /* handlers */ NULL, /* translate_handler */ NULL, /* check_user_id */ NULL, /* check auth */ NULL, /* check access */ NULL, /* type_checker */ NULL, /* prerun fixups */ NULL /* logger */ NULL, /* header parser */ NULL, /* child_init */ NULL, /* child_exit */ NULL /* post read request */ };
The first entry, STANDARD_MODULE_STUFF
, must
appear in all module
structures. It initializes
some structure elements that the core uses to manage modules.
Currently, these are the API version number,[3] the index of the module in various
vectors, the name of the module (actually, its filename), and a
pointer to the next module
structure in a linked
list of all modules.[4]
The only other entry is for
handlers
. We will look at this in more detail
further on. Suffice it to say, for now, that this entry points to a
list of strings and functions that define the relationship between
MIME or handler types and the functions that handle them. All the
other entries are defined to NULL
, which simply
means that the module does not use those particular hooks.
The equivalent structure in 2.0 looks like this:
static void register_hooks(apr_pool_t *p) { ap_hook_handler(asis_handler,NULL,NULL,APR_HOOK_MIDDLE); } module AP_MODULE_DECLARE_DATA asis_module = { STANDARD20_MODULE_STUFF, NULL, /* create per-directory config structure */ NULL, /* merge per-directory config structures */ NULL, /* create per-server config structure */ NULL, /* merge per-server config structures */ NULL, /* command apr_table_t */ register_hooks /* register hooks */ };
Note that we have to show the register_hooks()
function to match the functionality of the 1.3 module structure. Once
more, STANDARD20_MODULE_STUFF
is required for all
module structures, and the register_hooks()
function replaces most of the rest of the old 1.3 structure. How this
works is explained in detail in the next section.
[2] This means, of course, that one should not edit modules.c by hand. Rather, the Configuration file should be edited; see Chapter 1.
[3] This is used, in theory, to adapt to old precompiled modules that used an earlier version of the API. We say “in theory”; because it is not used this way in practice.
[4] The head of this list is
top_module
. This is occasionally useful to know.
The list is actually set up at runtime.