Apache HTTP Server Version 2.0

Intro Apache Mod

Credits: This document was written by Terrance Davis at the request of emWare, Inc.  (www.emware.com was a device networking company), and released with permission to the Apache community in 2002.

This seems to be accurate as of Apache 2.0.39. At least it will give a good starting point into what has traditionally been a sparsely documented area of Apache. This document is written from the Unix perspective, but should not need much modification to work under other platforms.

In the past it was been very difficult for coders unfamiliar with the guts of Apache to get a start on making custom mods. Currently (July 2002) this is even more difficult because, though Apache 2.0 is shaping up nicely, the documentation available to the public has not caught up. I spent a lot of time reading comments in the Apache source code while researching this document.

Let’s start by jumping into the friged waters head first. Let’s make a mod.

You can include custom mods in apache in two ways. The first way is to build them into apache. That is nice for a production quality mod, but when you’re still developing the mod, it is generally a pain to rebuild all of apache for every little change/addition you make to your mod.

The second way to include a mod is to build Apache to load mods at start up. I build them with the following commands (detailed more fully at http://httpd.apache.org/docs-2.0/install.html):

>./configure --prefix=PREFIX --enable-so

>make

>make install

Then I, for simplicity, make the user and group in httpd.conf match my own. They will look something like this:

User billyboebob

Group billyboebob

 

Hello World

Next you need a mod to run. Here is the code for a Hello World. We’ll look at what it does in more detail shortly.

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

#include "ap_compat.h"

static void register_hooks(apr_pool_t *p);
static int helloworld2_handler(request_rec *r);

static void register_hooks(apr_pool_t *p)
{
   ap_hook_handler(helloworld2_handler, NULL, NULL, APR_HOOK_MIDDLE);
}

static int helloworld2_handler(request_rec *r)
{
   r->content_type = "text/html"
   ap_send_http_header(r);

   ap_rputs("<H1>Hello <i>Apache 2.0</i> World!</H1>" ,r);

   return OK;
}

module AP_MODULE_DECLARE_DATA helloworld2_module =
{
   STANDARD20_MODULE_STUFF, /* stuff that needs to be declared in every 2.0 mod */
   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 */
};

Take this c code name it mod_helloworld2.c and save it. Now you can compile it using an apache tool called apxs. apxs is located in the bin directory of the apache 2.0.x build. The command that I used to compile this mod is apxs –c –i –a mod_helloworld2.c. This will build our mod and install it.

What good is the code if you don’t see it doing anything? cd to the conf directory. In this directory is the file httpd.conf. Add these lines where it seems appropriate:

<Location /ourmap>
SetHandler helloworld2-handler
</Location>

I added it to line 965, but all conf files are different. If you add it somewhere else, and it doesn’t map the mod properly, just try a different location.

Now you should be able to restart apache and see our mod’s message from the url http://www.yoururl.com/ourmap

What did you do?!

module definition

Every standard Apache mod needs an initial module to describe it. By convention this is the last thing in the module. To define it use:

module AP_MODULE_DECLARE_DATA foobar_module =

Replace foobar with the name of the module (the file name minus any extensions).

STANDARD_MODULE_STUFF

 


There are 14 slots in a standard Apache 2.0 module. We’re fortunate though. The macro STANDARD20_MODULE_STUFF predefines the first eight of these for us. The macro is defined in http_config.h if you desire to take a closer look at it. It mostly contains bookkeeping items such as the major and minor magic numbers for the Apache release.

Note that in Apache 1.3 modules the macro was defined as STANDARD_MODULE_STUFF. This will intentionally cause an error if used in a 2.0 mod. STANDARD_MODULE_STUFF is defined as this_module_needs_to_be_ported_to_apache_2_0 in Apache 2.0.

Config slots

The next four slots we do not use, so let’s skip them. They have to do with host wide and directory wide configurations and access.

Commands

Special commands sent to the Apache server in the HTTP Header can be captured and handled with the function pointed to by this slot. These are typically used to configure the module before the associated registered hooks are called.

Register hooks

This is a pointer to a function that details the hooks that this module handles. The convention is for the function to be called, of all things, register_hooks. There are lots and lots of potential hooks. We only needed one type, the ap_hook_handler.

In the ap_hook_handler is defined in the register_hooks function. A pointer to the actual handler, hellowworld2_handler, is provided. There may be multiple ap_hook_handler’s so we give our hook an priority number in the form of the macro HOOK_MIDDLE. HOOK_MIDDLE could be replaced with HOOK_FIRST or HOOK_LAST or in rare cases HOOK_REALLY_FIRST or HOOK_REALLY_LAST.

helloworld2_handler

Our actual handler takes the form of:

static int foobar_handler(request_rec *r)

Where foobar is replaced with the name of the handler. Our first action in the handler is to set the return messages content type to “text/html”. We send the return header with:

ap_send_http_header(r);

Now we can send some text. In our case this is the “Hello”. We finish up by sending the macro OK.

(Written for use with Apache HTTP Server Version 2.0)