mod_example.c revision 43c3e6a4b559b76b750c245ee95e2782c15b4296
* static const char *handle_TAKE3(cmd_parms *cmd, void *mconfig, * char *word1, char *word2, char *word3); * Command handler for a TAKE12 directive. These can take either one or two * - word2 is a NULL pointer if no second argument was specified. * Declared in the command_rec list with * AP_INIT_TAKE12("directive", function, mconfig, where, help) * static const char *handle_TAKE12(cmd_parms *cmd, void *mconfig, * char *word1, char *word2); * Command handler for a TAKE123 directive. A TAKE123 directive can be given, * as might be expected, one, two, or three arguments. * - word2 is a NULL pointer if no second argument was specified. * - word3 is a NULL pointer if no third argument was specified. * Declared in the command_rec list with * AP_INIT_TAKE123("directive", function, mconfig, where, help) * static const char *handle_TAKE123(cmd_parms *cmd, void *mconfig, * char *word1, char *word2, char *word3); * Command handler for a TAKE13 directive. Either one or three arguments are * permitted - no two-parameters-only syntax is allowed. * - word2 and word3 are NULL pointers if only one argument was specified. * Declared in the command_rec list with * AP_INIT_TAKE13("directive", function, mconfig, where, help) * static const char *handle_TAKE13(cmd_parms *cmd, void *mconfig, * char *word1, char *word2, char *word3); * Command handler for a TAKE23 directive. At least two and as many as three * arguments must be specified. * - word3 is a NULL pointer if no third argument was specified. * Declared in the command_rec list with * AP_INIT_TAKE23("directive", function, mconfig, where, help) * static const char *handle_TAKE23(cmd_parms *cmd, void *mconfig, * char *word1, char *word2, char *word3); * Command handler for a ITERATE directive. * - Handler is called once for each of n arguments given to the directive. * - word1 points to each argument in turn. * Declared in the command_rec list with * AP_INIT_ITERATE("directive", function, mconfig, where, help) * static const char *handle_ITERATE(cmd_parms *cmd, void *mconfig, * Command handler for a ITERATE2 directive. * - Handler is called once for each of the second and subsequent arguments * given to the directive. * - word1 is the same for each call for a particular directive instance (the * - word2 points to each of the second and subsequent arguments in turn. * Declared in the command_rec list with * AP_INIT_ITERATE2("directive", function, mconfig, where, help) * static const char *handle_ITERATE2(cmd_parms *cmd, void *mconfig, * char *word1, char *word2); /*--------------------------------------------------------------------------*/ /* These routines are strictly internal to this module, and support its */ /* operation. They are not referenced by any external portion of the */ /*--------------------------------------------------------------------------*/ * Locate our directory configuration record for the current request. * Locate our server configuration record for the specified server. * Likewise for our configuration record for the specified request. * Likewise for our configuration record for a connection. * This routine sets up some module-wide cells if they haven't been already. * If we haven't already allocated our module-private pool, do so now. * This routine is used to add a trace of a callback to the list. We're * passed the server record (if available), the request record (if available), * a pointer to our private configuration record (if available) for the * environment to which the callback is supposed to apply, and some text. We * turn this into a textual representation and add it to the tail of the list. * The list can be displayed by the x_handler() routine. * If the call occurs within a request context (i.e., we're passed a request * record), we put the trace into the request apr_pool_t and attach it to the * request via the notes mechanism. Otherwise, the trace gets added * to the static (non-request-specific) list. * Note that the r->notes table is only for storing strings; if you need to * maintain per-request data of any other type, you need to use another * Make sure our pools and tables are set up - we need 'em. * Now, if we're in request-context, we use the request pool. * We're not in request context, so the trace gets attached to our * module-wide pool. We do the create/destroy every time we're called * in non-request context; this avoids leaking memory in some of * the subsequent calls that allocate memory only once (such as the * Make a new sub-pool and copy any existing trace to it. Point the * trace cell at the copied value. * Now, if we have a sub-pool from before, nuke it and replace with * the one we just allocated. * If we weren't passed a configuration record, we can't figure out to * what location this call applies. This only happens for co-routines * that don't operate in a particular directory or server context. If we * got a valid record, extract the location (directory or server) to which * Now, if we're not in request context, see if we've been called with * this particular combination before. The apr_table_t is allocated in the * module's private pool, which doesn't get destroyed. * First time for this combination of routine and environment - * log it so we don't do it again. " <dt><samp>",
note,
"</samp></dt>\n" " <dd><samp>[",
where,
"]</samp></dd>\n" * You *could* change the following if you wanted to see the calling * sequence reported in the server's error_log, but beware - almost all of * these co-routines are called for every single request, and the impact * on the size (and readability) of the error_log is considerable. /*--------------------------------------------------------------------------*/ /* We prototyped the various syntax for command handlers (routines that */ /* are called when the configuration parser detects a directive declared */ /* by our module) earlier. Now we actually declare a "real" routine that */ /* will be invoked by the parser when our "real" directive is */ /* If a command handler encounters a problem processing the directive, it */ /* signals this fact by returning a non-NULL pointer to a string */ /* describing the problem. */ /* The magic return value DECLINE_CMD is used to deal with directives */ /* that might be declared by multiple modules. If the command handler */ /* returns NULL, the directive was processed; if it returns DECLINE_CMD, */ /* the next module (if any) that declares the directive is given a chance */ /* at it. If it returns any other value, it's treated as the text of an */ /*--------------------------------------------------------------------------*/ * Command handler for the NO_ARGS "Example" directive. All we do is mark the * call in the trace log, and flag the applicability of the directive to the * current location in that location's configuration record. /*--------------------------------------------------------------------------*/ /* Now we declare our content handlers, which are invoked when the server */ /* encounters a document which our module is supposed to have a chance to */ /* see. (See mod_mime's SetHandler and AddHandler directives, and the */ /* mod_info and mod_status examples, for more details.) */ /* Since content handlers are dumping data directly into the connection */ /* (using the r*() routines, such as rputs() and rprintf()) without */ /* intervention by other parts of the server, they need to make */ /* sure any accumulated HTTP headers are sent first. This is done by */ /* calling send_http_header(). Otherwise, no header will be sent at all, */ /* and the output sent to the client will actually be HTTP-uncompliant. */ /*--------------------------------------------------------------------------*/ * Sample content handler. All this does is display the call list that has * The return value instructs the caller concerning what happened and what to * OK ("we did our thing") * DECLINED ("this isn't something with which we want to get involved") * HTTP_mumble ("an error status should be reported") * We're about to start sending content, so we need to force the HTTP * headers to be sent at this point. Otherwise, no headers will be sent * at all. We can set any we like first, of course. **NOTE** Here's * where you set the "Content-type" header, and you do so by putting it in * r->content_type, *not* r->headers_out("Content-type"). If you don't * set it, it will be filled in with the server's default type (typically * "text/plain"). You *must* also ensure that r->content_type is lower * We also need to start a timer so the server can know if the connexion * If we're only supposed to send header information (HEAD request), we're * Now send our actual output. Since we tagged this as being * "text/html", we need to embed any HTML. ap_rputs(
" <TITLE>mod_example Module Content-Handler Output\n", r);
ap_rputs(
" <H1><SAMP>mod_example</SAMP> Module Content-Handler Output\n", r);
ap_rprintf(r,
" Apache HTTP Server version: \"%s\"\n",
ap_rputs(
" The format for the callback trace is:\n", r);
ap_rputs(
" <DT><EM>n</EM>.<SAMP><routine-name>", r);
ap_rputs(
"(<routine-data>)</SAMP>\n", r);
ap_rputs(
" <DD><SAMP>[<applies-to>]</SAMP>\n", r);
ap_rputs(
" The <SAMP><routine-data></SAMP> is supplied by\n", r);
ap_rputs(
" the routine when it requests the trace,\n", r);
ap_rputs(
" and the <SAMP><applies-to></SAMP> is extracted\n", r);
ap_rputs(
" from the configuration record at the time of the trace.\n", r);
ap_rputs(
" <STRONG>SVR()</STRONG> indicates a server environment\n", r);
ap_rputs(
" (blank means the main or default server, otherwise it's\n", r);
ap_rputs(
" the name of the VirtualHost); <STRONG>DIR()</STRONG>\n", r);
ap_rputs(
" indicates a location in the URL or filesystem\n", r);
ap_rprintf(r,
" <H2>Static callbacks so far:</H2>\n <OL>\n%s </OL>\n",
ap_rputs(
" <H2>Request-specific callbacks so far:</H2>\n", r);
ap_rputs(
" <H2>Environment for <EM>this</EM> call:</H2>\n", r);
ap_rprintf(r,
" <LI>\"Example\" directive declared here: %s\n </LI>\n",
ap_rprintf(r,
" <LI>\"Example\" inherited: %s\n </LI>\n",
* We're all done, so cancel the timeout we set. Since this is probably * the end of the request we *could* assume this would be done during * post-processing - but it's possible that another handler might be * called and inherit our outstanding timer. Not good; to each its own. * We did what we wanted to do, so tell the rest of the server we /*--------------------------------------------------------------------------*/ /* Now let's declare routines for each of the callback phase in order. */ /* (That's the order in which they're listed in the callback list, *not */ /* the order in which the server calls them! See the command_rec */ /* declaration near the bottom of this file.) Note that these may be */ /* called for situations that don't relate primarily to our function - in */ /* other words, the fixup handler shouldn't assume that the request has */ /* to do with "example" stuff. */ /* With the exception of the content handler, all of our routines will be */ /* called for each request, unless an earlier handler from another module */ /* aborted the sequence. */ /* Handlers that are declared as "int" can return the following: */ /* OK Handler accepted the request and did its thing with it. */ /* DECLINED Handler took no action. */ /* HTTP_mumble Handler looked at request and found it wanting. */ /* What the server does after calling a module handler depends upon the */ /* handler's return value. In all cases, if the handler returns */ /* DECLINED, the server will continue to the next module with an handler */ /* for the current phase. However, if the handler return a non-OK, */ /* non-DECLINED status, the server aborts the request right there. If */ /* the handler returns OK, the server's next action is phase-specific; */ /* see the individual handler comments below for details. */ /*--------------------------------------------------------------------------*/ * This function is called during server initialisation. Any information * that needs to be recorded must be in static cells, since there's no * There is no return value. * This function is called when an heavy-weight process (such as a child) is * being run down or destroyed. As with the child initialisation function, * any information that needs to be recorded must be in static cells, since * there's no configuration record. * There is no return value. * This function is called during server initialisation when an heavy-weight * process (such as a child) is being initialised. As with the * module initialisation function, any information that needs to be recorded * must be in static cells, since there's no configuration record. * There is no return value. * This function gets called to create a per-directory configuration * record. This will be called for the "default" server environment, and for * each directory for which the parser finds any of our directives applicable. * If a directory doesn't have any of our directives involved (i.e., they * aren't in the .htaccess file, or a <Location>, <Directory>, or related * block), this routine will *not* be called - the configuration for the * closest ancestor is used. * The return value is a pointer to the created module-specific * Allocate the space for our record from the pool supplied. * Now fill in the defaults. If there are any `parent' configuration * records, they'll get merged as part of a separate callback. * Finally, add our trace to the callback list. * This function gets called to merge two per-directory configuration * records. This is typically done to cope with things like .htaccess files * or <Location> directives for directories that are beneath one for which a * configuration record was already created. The routine has the * responsibility of creating a new record and merging the contents of the * other two into it appropriately. If the module doesn't declare a merge * routine, the record for the closest ancestor location (that has one) is * The routine MUST NOT modify any of its arguments! * The return value is a pointer to the created module-specific structure * containing the merged values. * Some things get copied directly from the more-specific record, rather * Others, like the setting of the `congenital' flag, get ORed in. The * setting of that particular flag, for instance, is TRUE if it was ever * true anywhere in the upstream configuration. * If we're merging records for two different types of environment (server * and directory), mark the new record appropriately. Otherwise, inherit * Now just record our being called in the trace list. Include the * locations we were asked to merge. * This function gets called to create a per-server configuration * record. It will always be called for the "default" server. * The return value is a pointer to the created module-specific * As with the x_create_dir_config() reoutine, we allocate and fill * Note that we were called in the trace list. * This function gets called to merge two per-server configuration * records. This is typically done to cope with things like virtual hosts and * the default server configuration The routine has the responsibility of * creating a new record and merging the contents of the other two into it * appropriately. If the module doesn't declare a merge routine, the more * specific existing record is used exclusively. * The routine MUST NOT modify any of its arguments! * The return value is a pointer to the created module-specific structure * containing the merged values. * Our inheritance rules are our own, and part of our module's semantics. * Basically, just note whence we came. * Trace our call, including what we were asked to merge. * This routine is called before the server processes the configuration * files. There is no return value. * This routine is called to perform any module-specific fixing of header * fields, et cetera. It is invoked just before any content-handler. * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, the * server will still call any remaining modules with an handler for this * This routine is called to perform any module-specific log file * openings. It is invoked just before the post_config phase * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, the * server will still call any remaining modules with an handler for this * All our process-death routine does is add its trace to the log. * The arbitrary text we add to our trace entry indicates for which server * All our process initialiser does is add its trace to the log. * Set up any module cells that ought to be initialised. * The arbitrary text we add to our trace entry indicates for which server * XXX: This routine is called XXX * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, the * server will still call any remaining modules with an handler for this * XXX: This routine is called XXX * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, the * server will still call any remaining modules with an handler for this * XXX: This routine is called XXX * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, the * server will still call any remaining modules with an handler for this * XXX: This routine is called XXX * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, the * server will still call any remaining modules with an handler for this * This routine is called just after the server accepts the connection, * but before it is handed off to a protocol module to be served. The point * of this hook is to allow modules an opportunity to modify the connection * as soon as possible. The core server uses this phase to setup the * connection record based on the type of connection that is being used. * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, the * server will still call any remaining modules with an handler for this /* This routine is used to actually process the connection that was received. * Only protocol modules should implement this hook, as it gives them an * opportunity to replace the standard HTTP processing with processing for * some other protocol. Both echo and POP3 modules are available as * The return VALUE is OK, DECLINED, or HTTP_mumble. If we return OK, no * further modules are called for this phase. * This routine is called after the request has been read but before any other * phases have been processed. This allows us to make decisions based upon * the input header fields. * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, no * further modules are called for this phase. * We don't actually *do* anything here, except note the fact that we were * This routine gives our module an opportunity to translate the URI into an * actual filename. If we don't do anything special, the server's default * rules (Alias directives and the like) will continue to be followed. * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, no * further modules are called for this phase. * We don't actually *do* anything here, except note the fact that we were * This routine maps r->filename to a physical file on disk. Useful for * overriding default core behavior, including skipping mapping for * requests that are not file based. * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, no * further modules are called for this phase. * We don't actually *do* anything here, except note the fact that we were * this routine gives our module another chance to examine the request * headers and to take special action. This is the first phase whose * hooks' configuration directives can appear inside the <Directory> * and similar sections, because at this stage the URI has been mapped * to the filename. For example this phase can be used to block evil * clients, while little resources were wasted on these. * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, * the server will still call any remaining modules with an handler * We don't actually *do* anything here, except note the fact that we were * This routine is called to check the authentication information sent with * the request (such as looking up the user in a database and verifying that * the [encrypted] password sent matches the one in the database). * The return value is OK, DECLINED, or some HTTP_mumble error (typically * HTTP_UNAUTHORIZED). If we return OK, no other modules are given a chance * at the request during this phase. * Don't do anything except log the call. * This routine is called to check to see if the resource being requested * requires authorisation. * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, no * other modules are called during this phase. * If *all* modules return DECLINED, the request is aborted with a server * Log the call and return OK, or access will be denied (even though we * didn't actually do anything). * This routine is called to check for any module-specific restrictions placed * upon the requested resource. (See the mod_access module for an example.) * The return value is OK, DECLINED, or HTTP_mumble. All modules with an * handler for this phase are called regardless of whether their predecessors * return OK or DECLINED. The first one to return any other status, however, * will abort the sequence (and the request) as usual. * This routine is called to determine and/or set the various document type * information bits, like Content-type (via r->content_type), language, et * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, no * further modules are given a chance at the request for this phase. * Log the call, but don't do anything else - and report truthfully that * This routine is called to perform any module-specific fixing of header * fields, et cetera. It is invoked just before any content-handler. * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, the * server will still call any remaining modules with an handler for this * This routine is called to perform any module-specific logging activities * over and above the normal server things. * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, any * remaining modules with an handler for this phase will still be called. /*--------------------------------------------------------------------------*/ /* Which functions are responsible for which hooks in the server. */ /*--------------------------------------------------------------------------*/ * Each function our module provides to handle a particular hook is * specified here. The functions are registered using * ap_hook_foo(name, predecessors, successors, position) * where foo is the name of the hook. * The args are as follows: * name -> the name of the function to call. * predecessors -> a list of modules whose calls to this hook must be * invoked before this module. * successors -> a list of modules whose calls to this hook must be * invoked after this module. * position -> The relative position of this module. One of * APR_HOOK_FIRST, APR_HOOK_MIDDLE, or APR_HOOK_LAST. * Most modules will use APR_HOOK_MIDDLE. If multiple * modules use the same relative position, Apache will * determine which to call first. * If your module relies on another module to run first, * or another module running after yours, use the * predecessors and/or successors. * The number in brackets indicates the order in which the routine is called * during request processing. Note that not all routines are necessarily * called (such as if a resource doesn't have access restrictions). * The actual delivery of content to the browser [9] is not handled by * a hook; see the handler declarations below. /* [1] post read_request handling */ /*--------------------------------------------------------------------------*/ /* All of the routines have been declared now. Here's the list of */ /* directives specific to our module, and information about where they */ /* may appear and how the command parser should pass them to us for */ /* processing. Note that care must be taken to ensure that there are NO */ /* collisions of directive names between modules. */ /*--------------------------------------------------------------------------*/ * List of directives specific to our module. "Example",
/* directive name */ NULL,
/* argument to include in call */ "Example directive - no arguments" /* directive description */ /*--------------------------------------------------------------------------*/ /* Finally, the list of callback routines and data structures that provide */ /* the static hooks into our module from the other parts of the server. */ /*--------------------------------------------------------------------------*/ * Module definition for configuration. If a particular callback is not * needed, replace its routine name below with the word NULL.