home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  

Writing Apache Modules with Perl and C
By:   Lincoln Stein and Doug MacEachern
Published:   O'Reilly & Associates, Inc.  - March 1999

Copyright 1999 by O'Reilly & Associates, Inc.


   Show Contents   Previous Page   Next Page

Chapter 2 - A First Module / "Hello World" with the C API
Building a Dynamically Loadable Module

It can be a pain to relink and reinstall the server executable every time you make a change to a custom module. As of Version 1.3, Apache offers a way to build dynamically loadable modules. You build the module as a shared object, place it somewhere handy, add a LoadModule directive to httpd.conf, and send the server a restart signal. After the module is loaded, it's indistinguishable from any other module.

Dynamic loading is available on most systems, including Linux, FreeBSD, Solaris, BSDI, AIX, and IRIX systems. To configure your server for dynamic loading, recompile it with the mod_so module installed. mod_so is a standard Apache module, found in src/modules/standard, but it is not compiled in by default. From within the Apache source tree, rerun the configure script, adding mod_so to the list of modules you wish to enable:

% ./configure --enable-module=so --enable-module=other_module ...

Now you must run a full make to rebuild the httpd. This is only for the purpose of installing the statically linked mod_so. You won't need to rebuild httpd to add new dynamically loadable modules. You can install and launch the new httpd now if you wish, or wait until the dynamically loadable hello_module is ready to go.

You now have an httpd with mod_so installed, but you still need to build mod_hello.so. This can be done in one of two ways. One way is to use the configure script to build a new dynamically loadable module. From the top of the Apache distribution (where the ABOUT_APACHE file is located) run the configure command again, replacing the --enable-module option with --enable-shared:

% ./configure --activate-module=src/modules/site/mod_hello.c \

When the --enable-shared argument is present, this implies that mod_so should be built with the server, so there's no need to use --enable-module=so.

Now you'll need to run make to create the file src/modules/site/mod_hello.so. When this is done, just copy the shared object file to Apache's libexec directory:

% cp src/modules/site/mod_hello.so ~www/libexec/

Open httpd.conf and add the following line:

LoadModule hello_module libexec/mod_hello.so

The LoadModule directive, available only when so_module is installed, takes two arguments. The first is the name of the module to load at runtime, and the second is the path to the shared object file to load. You can use a path relative to the server root, as shown here, or an absolute file path.

A second, and possibly easier way to build a module as a DSO is to use the apxs program, the "APache eXtenSion" tool. With a single command, our mod_hello module can be compiled, installed, and configured. The -c option specifies which module to compile. The -i option tells apxs to install the module and the -a option adds the LoadModule directive to your httpd.conf file.

% ~www/bin/apxs -c -i -a mod_hello.c
 gcc -DLINUX=2 -DHAS_BOOL -DUSE_HSREGEX -I/usr/local/apache/include
 -c mod_hello.c -o mod_hello.so mod_hello.o
 cp mod_hello.so /usr/local/apache/libexec/mod_hello.so
 chmod 644 /usr/local/apache/libexec/mod_hello.so
 [activating module 'hello' in /usr/local/apache/conf/httpd.conf]

The main advantage of apxs is that you do not need to store your C language module source files underneath the Apache source tree but can keep them anywhere you wish. apxs has numerous other options, the handiest of which are the -g and -n options, which together create a dummy "template" directory that you can use as a skeleton on which to build your own modules. The full details can be found in the apxs manual page, located in the man subdirectory under the server root.

Regardless of whether you built mod_hello using configure or apxs, you should now start or restart httpd and watch the error log for messages. Provided that LogLevel is set to debug (see Chapter 4, Content Handlers), you should see a message to this effect:

[Tue Mar 24 07:49:56 1998] [debug] mod_so.c(234): loaded module hello_module

You should now be able to fetch http://your.site/hey/there, and see the familiar page produced by this example script.

Building Large C Modules

   Show Contents   Go to Top   Previous Page   Next Page

If your C module consists of more than a single source file, or if it requires linking with shared libraries, see Appendix C, Building Multifile C API Modules.

Building C Modules in the Windows Environment

   Show Contents   Go to Top   Previous Page   Next Page

As of this writing, Apache does not provide any special support tools for building third-party modules in the Win32 environment. We'll show you how to build an Apache module DLL (Dynamic Link Library) using Microsoft Visual C++. The naming convention for module source files is the same in Win32 systems as it is in Unix, but the DLL library names generally replace the mod_ prefix with ApacheModule. In our example, we will build an ApacheModuleHello.dll from our mod_hello.c source file. The source file doesn't have to be changed in the slightest to compile under Win32.

To ensure that this procedure works, you'll have to compile everything on a Windows NT system (Windows 95/98 doesn't work, although you can run the resulting binaries on 95/98). You may also have to build Apache and Perl from source. The binary distributions are not guaranteed to interoperate correctly with modules you build yourself.

Here is the blow-by-blow procedure:

  1. Create a new project.

Select the File New menu to bring up the Projects window. Select "Win32 Dynamic-Link Library" and enter "ApacheModuleHello" as the project name and C:\build\ApacheModuleHello (or the build location of your choice) as its location. See Figure 2-2.

Figure 2-2. Select "Win32 Dynamic-Link Library" to create a new Apache module project.

  1. Add the module source files.

From the Project menu, select Add To Project Files. Add mod_hello.c to the list (Figure 2-3).

Figure 2-3. Add the module source files to the Visual C++ project.

  1. Add Apache Runtime Library.

Repeat the previous step, adding the Apache core library, C:\Apache\ApacheCore.lib (Figure 2-4).

Figure 2-4. Add the Apache runtime library to the build.

  1. Add the include directory for Apache header files.

From the Tools Options menu, select Directories. In the dialog box, choose Include files and add the path to the Apache include directory. This is located underneath the Apache source tree, in the directory src\include (Figure 2-5).

Figure 2-5. The Apache include path must be added to the project directories.

  1. Change the Active Configuration setting from Debug to Release.

From the Build Set Active Configuration menu, select Win32 Release. This will enable o ptimizations and turn off debugging code (Figure 2-6).

Figure2-6. Set the Active Configuration.

  1. Compile.

From the Build menu, select Build ApacheModuleHello.dll. The compiler will fire up and, if all goes well, create the DLL library. If you get any error messages during this process, go back and fix the problems.

  1. Install the DLL.

Copy ApacheModuleHello/Release/ApacheModuleHello.dll to the C:\Apache\modules directory.

  1. Configure httpd.

Add the following lines to httpd.conf:

LoadModule hello_module modules/ApacheModuleHello.dll
<Location /hi/there>
   SetHandler hello-handler

Fire up your favorite browser and request the URI http://your.site/hi/there. With luck, ApacheModuleHello will run and you'll see the page from Figure 2-1.


7 Note that if HostNameLookups is configured to be Off, the ap_get_remote_host() function will return the IP address of the client. See Chapter 8, Customizing the Apache Configuration Process, and Chapter 9, Perl API Reference Guide, for more details on the ap_get_remote_host() function.

   Show Contents   Go to Top   Previous Page   Next Page
Copyright 1999 by O'Reilly & Associates, Inc.