Show Contents Previous Page Next Page Chapter 2 - A First Module In this section...
In this section we will create the same "Hello World" module using the C API. This will show you how closely related the two APIs really are. Many of the details in this section are specific for Unix versions of Apache. For differences relating to working in Win32 environments, be sure to read the section "Building C Modules in the Windows Environment." The preparation for writing C API modules is somewhat simpler than that for
the Perl modules. You just need to create a subdirectory in the Apache source
tree to hold your site-specific source code. We recommend creating a directory
named To have this new subdirectory participate in the server build process, create
a file within it named The next step is to create the module itself. Example 2-2
shows the source for Example 2-2. A First C-Language Module #include "httpd.h" #include "http_config.h" #include "http_core.h" #include "http_log.h" #include "http_protocol.h" /* file: mod_hello.c */ /* here's the content handler */ static int hello_handler(request_rec *r) { const char* hostname; r->content_type = "text/html"; ap_send_http_header(r); hostname = ap_get_remote_host(r->connection,r->per_dir_config,REMOTE_NAME); ap_rputs("<HTML>\n" ,r); ap_rputs("<HEAD>\n" ,r); ap_rputs("<TITLE>Hello There</TITLE>\n" ,r); ap_rputs("</HEAD>\n" ,r); ap_rputs("<BODY>\n" ,r); ap_rprintf(r,"<H1>Hello %s</H1>\n" ,hostname); ap_rputs("Who would take this book seriously if the first example didn't\n",r); ap_rputs("say \"hello world\"?\n" ,r); ap_rputs("</BODY>\n" ,r); ap_rputs("</HTML>\n" ,r); return OK; } /* Make the name of the content handler known to Apache */ static handler_rec hello_handlers[] = { {"hello-handler", hello_handler}, {NULL} }; /* Tell Apache what phases of the transaction we handle */ module MODULE_VAR_EXPORT hello_module = { STANDARD_MODULE_STUFF, NULL, /* module initializer */ NULL, /* per-directory config creator */ NULL, /* dir config merger */ NULL, /* server config creator */ NULL, /* server config merger */ NULL, /* command table */ hello_handlers, /* [9] content handlers */ NULL, /* [2] URI-to-filename translation */ NULL, /* [5] check/validate user_id */ NULL, /* [6] check user_id is valid *here* */ NULL, /* [4] check access by host address */ NULL, /* [7] MIME type checker/setter */ NULL, /* [8] fixups */ NULL, /* [10] logger */ NULL, /* [3] header parser */ NULL, /* process initialization */ NULL, /* process exit/cleanup */ NULL /* [1] post read_request handling */ }; We'll go into the sordid details on how this module works later. Essentially, all the real work is done in the content handler subroutine hello_handler() which accepts an Apache request record pointer as its argument and returns an integer result code. The subroutine first changes the content_type field of the request record to text/html, promising the remote browser that we will be producing an HTML document. It then calls the Apache ap_send_http_header() subroutine to send the HTTP header off. The hello_handler() subroutine now fetches the DNS name
of the remote host by calling the ap_get_remote_host() function. It
passes various parts of the request record to the function and specifies that
our preference is to retrieve the remote host's DNS using a single DNS lookup
rather than a more secure (but slower) double lookup.7
We now build the HTML document using a series of calls to ap_rputs()
and ap_rprintf(). These subroutines act just like puts() and
printf(), but their output is funneled to the browser by way of the
Apache server. When the document is finished, we return a status code of The rest of this module consists of bookkeeping. First we create a After this is another data structure created using the module type definition. This data structure is essentially a list of the various phases of the Apache HTTP transaction (described in the next chapter), with empty slots where you can place your handlers for those phases. In mod_hello we're only interested in handling the content generation
part of the transaction, which happens to be the seventh slot in the structure
but is the ninth phase to run. There's no rhyme or reason in order of the slots
because new transaction phases were invented over time. The bracketed numbers
in the slot comments indicate the order in which the handlers run, although
as we explain in the next chapter, not all handlers are run for all transactions.
We leave all the slots Now the new module needs to be configured with Apache. This can be accomplished
with little effort thanks to Apache's configure script. The --activate-module
argument is used to add third-party modules to the server, that is, modules
not included with the Apache distribution. Its value is the path to the source
or object file of the module to be included, in this case % ./configure --activate-module=src/modules/site/mod_hello.c \ --enable-module=hello Configuring for Apache, Version 1.3.3 + activated hello module (modules/site/mod_hello.c) Creating Makefile Creating Configuration.apaci in src Creating Makefile in src + configured for Linux platform + setting C compiler to gcc + adding selected modules + checking for system header files + doing sanity check on compiler and options Creating Makefile in src/support Creating Makefile in src/main Creating Makefile in src/ap Creating Makefile in src/regex Creating Makefile in src/os/unix Creating Makefile in src/modules/standard You can now run make and a new To test the module, you'll need to associate it with a URI. The simplest way to do this is to use SetHandler to map it to a part of the document tree. Add a <Location> directive to perl.conf (or one of the other configuration files) that looks like this: <Location /hey/there> SetHandler hello-handler </Location> Stop the Apache server if it is already running, and launch the new When you want to make changes to the Copyright © 1999 by O'Reilly & Associates, Inc. |
HIVE: All information for read only. Please respect copyright! |