Yesterday, in trying to convey how to implement a module, I developed a "hello world" example module that has a "handler" hook that responds with a canned message to all requests. (It demonstrates hooks, and I have a slightly more complex example showing how to read per-directory configurations.)
I would have found a barebones example immensely useful and would have saved me much time and code-grepping.
Anyways, I've attached my "hello world" module. Please comment/correct/chastise as you see fit, I am by no means an expert. ;^>
/* mod_hello_world.c * Written by Chris Knight, NASA Ames Research Center * [EMAIL PROTECTED] * * Build using: * $APACHE_HOME/build/libtool gcc -c -I$APACHE_HOME/include mod_hello_world.c * * followed by: * $APACHE_HOME/build/libtool --mode=link $(CC) -o $@ -fPIC $(INCLUDE) \ * hello_world.lo $(LIBS) $(APACHE_CFLAGS) -rpath /usr/lib -avoid-version */ #include "httpd.h" #include "http_core.h" #include "http_config.h" #include "ap_config.h" #include "http_log.h"
// Forward declaration of the module, see the bottom of this document for
// details.
module AP_MODULE_DECLARE_DATA hello_world_module;
// A struct to hold this module's configuration parameters.
typedef struct conf {
apr_pool_t *p;
char *message;
} conf;
/**
* Instantiate this module's configuration structure.
* This function is called by Apache for each configuration section and is
* passed by Apache to other module functions.
* @param p The memory pool to be used by this module.
* @param d The directory/location for this section?
* @return The configuration block's pointer.
*/
static void *create_conf(apr_pool_t *p, char *d) {
conf *c = apr_pcalloc(p, sizeof(conf));
c->p = p;
c->message = NULL;
return c;
}
/**
* Set the message in this module's configuration. This is called when
* the HelloWorldMsg directive is encountered in a configuration section.
* @param cmd The directive parameters ???
* @param config The section's configuration
* @param arg1 The message.
* @return The error message if there is an error with this directive.
*/
static const char *set_message(cmd_parms *cmd, void *config, const char *arg1) {
conf *c = (conf *)config;
c->message = (char *)apr_pstrdup(c->p, arg1);
return NULL;
}
/**
* Provide the response to the request.
* @param r The request record. (Containing all of the details of the request.)
* @return Flag indicating successful handling of the request.
*/
int handle(request_rec *r) {
conf *conf = ap_get_module_config(r->per_dir_config, &hello_world_module);
// if there is no message declared for this URI (no matching <Location>,
// <Directory>, etc) then let another hook handle the request.
if (conf == NULL || conf->message == NULL) return DECLINED;
// otherwise, send our message to the client
ap_rprintf(r, conf->message);
// and tell Apache that we've handled the request
return OK;
}
/**
* Connect hook functions to Apache so that Apache will call them at the
* appropriate time.
* @param p The memory pool to use.
*/
static void register_hooks(apr_pool_t *p) {
// The handler hooks are used to provide the response's contents for a
// successful request.
ap_hook_handler(handle, NULL, NULL, APR_HOOK_MIDDLE);
}
// This list details which configuration directives this module understands.
static const command_rec cmds[] = {
// The HelloWorldMsg directive takes one argument, the message to send.
AP_INIT_TAKE1("HelloWorldMsg", set_message, NULL, OR_AUTHCFG,
"specify the message to send clients"),
// Indicates the end of the list of directives.
{NULL}
};
// This module declaration tells Apache which configuration directives this
// module understands and which methods to call to connect the hook functions.
module AP_MODULE_DECLARE_DATA hello_world_module = {
STANDARD20_MODULE_STUFF, // always need this
create_conf, // called for each configuration section
NULL, // called for nested configuration sections (?)
NULL, // called once per server configuration
NULL, // ?
cmds, // which configuration directives do I handle?
register_hooks // function to be called at bind-time
};
