mod_example.c revision fc9b2e8809c305f340d86a789566f8abb1ca8a19
2d2eda71267231c2526be701fe655db125852c1ffielding/* ====================================================================
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * Copyright (c) 1995-1999 The Apache Group. All rights reserved.
b99dbaab171d91e1b664397cc40e039d0c087c65fielding * Redistribution and use in source and binary forms, with or without
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * modification, are permitted provided that the following conditions
2d2eda71267231c2526be701fe655db125852c1ffielding * 1. Redistributions of source code must retain the above copyright
2d2eda71267231c2526be701fe655db125852c1ffielding * notice, this list of conditions and the following disclaimer.
2d2eda71267231c2526be701fe655db125852c1ffielding * 2. Redistributions in binary form must reproduce the above copyright
2d2eda71267231c2526be701fe655db125852c1ffielding * notice, this list of conditions and the following disclaimer in
2d2eda71267231c2526be701fe655db125852c1ffielding * the documentation and/or other materials provided with the
2d2eda71267231c2526be701fe655db125852c1ffielding * distribution.
2d2eda71267231c2526be701fe655db125852c1ffielding * 3. All advertising materials mentioning features or use of this
2d2eda71267231c2526be701fe655db125852c1ffielding * software must display the following acknowledgment:
2d2eda71267231c2526be701fe655db125852c1ffielding * "This product includes software developed by the Apache Group
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * for use in the Apache HTTP server project (http://www.apache.org/)."
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * 4. The names "Apache Server" and "Apache Group" must not be used to
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * endorse or promote products derived from this software without
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * prior written permission. For written permission, please contact
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * apache@apache.org.
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * 5. Products derived from this software may not be called "Apache"
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * nor may "Apache" appear in their names without prior written
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * permission of the Apache Group.
2d2eda71267231c2526be701fe655db125852c1ffielding * 6. Redistributions of any form whatsoever must retain the following
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * acknowledgment:
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * "This product includes software developed by the Apache Group
64185f9824e42f21ca7b9ae6c004484215c031a7rbb * for use in the Apache HTTP server project (http://www.apache.org/)."
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
2d2eda71267231c2526be701fe655db125852c1ffielding * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * OF THE POSSIBILITY OF SUCH DAMAGE.
2d2eda71267231c2526be701fe655db125852c1ffielding * ====================================================================
2d2eda71267231c2526be701fe655db125852c1ffielding * This software consists of voluntary contributions made by many
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * individuals on behalf of the Apache Group and was originally based
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * on public domain software written at the National Center for
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * Supercomputing Applications, University of Illinois, Urbana-Champaign.
2d2eda71267231c2526be701fe655db125852c1ffielding * For more information on the Apache Group and the Apache HTTP server
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * project, please see <http://www.apache.org/>.
2d2eda71267231c2526be701fe655db125852c1ffielding * Apache example module. Provide demonstrations of how modules do things.
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/*--------------------------------------------------------------------------*/
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* Data declarations. */
2d2eda71267231c2526be701fe655db125852c1ffielding/* Here are the static cells and structure declarations private to our */
2d2eda71267231c2526be701fe655db125852c1ffielding/* module. */
2d2eda71267231c2526be701fe655db125852c1ffielding/*--------------------------------------------------------------------------*/
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * Sample configuration record. Used for both per-directory and per-server
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * configuration data.
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * It's perfectly reasonable to have two different structures for the two
2d2eda71267231c2526be701fe655db125852c1ffielding * different environments. The same command handlers will be called for
2d2eda71267231c2526be701fe655db125852c1ffielding * both, though, so the handlers need to be able to tell them apart. One
bfb62a96023822c56c9120e4ee627d4091cc59c2rbb * possibility is for both structures to start with an int which is zero for
bfb62a96023822c56c9120e4ee627d4091cc59c2rbb * one and 1 for the other.
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * Note that while the per-directory and per-server configuration records are
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * available to most of the module handlers, they should be treated as
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * READ-ONLY by all except the command and merge handlers. Sometimes handlers
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * are handed a record that applies to the current location by implication or
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * inheritance, and modifying it will change the rules for other locations.
2d2eda71267231c2526be701fe655db125852c1ffieldingtypedef struct excfg {
61fd0cab072a05b855cbef9c585702401ac5ae29rbb int cmode; /* Environment to which record applies (directory,
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * server, or combination).
61fd0cab072a05b855cbef9c585702401ac5ae29rbb int local; /* Boolean: "Example" directive declared here? */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb int congenital; /* Boolean: did we inherit an "Example"? */
2d2eda71267231c2526be701fe655db125852c1ffielding char *loc; /* Location to which this record applies. */
2d2eda71267231c2526be701fe655db125852c1ffielding * Let's set up a module-local static cell to point to the accreting callback
2d2eda71267231c2526be701fe655db125852c1ffielding * trace. As each API callback is made to us, we'll tack on the particulars
000b67449410515eac43e76ef6667915bfd4d2abgstein * to whatever we've already recorded. To avoid massive memory bloat as
2d2eda71267231c2526be701fe655db125852c1ffielding * directories are walked again and again, we record the routine/environment
2d2eda71267231c2526be701fe655db125852c1ffielding * the first time (non-request context only), and ignore subsequent calls for
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * To avoid leaking memory from pools other than the per-request one, we
7bdef86e15d47d16dcbe7a5611683191774bd5fbgstein * allocate a module-private pool, and then use a sub-pool of that which gets
7bdef86e15d47d16dcbe7a5611683191774bd5fbgstein * freed each time we modify the trace. That way previous layers of trace
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * data don't get lost.
3d96ee83babeec32482c9082c9426340cee8c44dwrowe * Declare ourselves so the configuration routines can find and know us.
7bdef86e15d47d16dcbe7a5611683191774bd5fbgstein * We'll fill it in at the end of the module.
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/*--------------------------------------------------------------------------*/
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* The following pseudo-prototype declarations illustrate the parameters */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* passed to command handlers for the different types of directive */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* syntax. If an argument was specified in the directive definition */
3d96ee83babeec32482c9082c9426340cee8c44dwrowe/* (look for "command_rec" below), it's available to the command handler */
7bdef86e15d47d16dcbe7a5611683191774bd5fbgstein/* via the (void *) info field in the cmd_parms argument passed to the */
c9a95767fbf0f5fb0976a06b97a256033925e433rbb/* handler (cmd->info for the examples below). */
c9a95767fbf0f5fb0976a06b97a256033925e433rbb/*--------------------------------------------------------------------------*/
c9a95767fbf0f5fb0976a06b97a256033925e433rbb * Command handler for a NO_ARGS directive.
c9a95767fbf0f5fb0976a06b97a256033925e433rbb * static const char *handle_NO_ARGS(cmd_parms *cmd, void *mconfig);
c9a95767fbf0f5fb0976a06b97a256033925e433rbb * Command handler for a RAW_ARGS directive. The "args" argument is the text
c9a95767fbf0f5fb0976a06b97a256033925e433rbb * of the commandline following the directive itself.
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * static const char *handle_RAW_ARGS(cmd_parms *cmd, void *mconfig,
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * const char *args);
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * Command handler for a FLAG directive. The single parameter is passed in
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * "bool", which is either zero or not for Off or On respectively.
3d96ee83babeec32482c9082c9426340cee8c44dwrowe * static const char *handle_FLAG(cmd_parms *cmd, void *mconfig, int bool);
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * Command handler for a TAKE1 directive. The single parameter is passed in
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * "word1".
3d96ee83babeec32482c9082c9426340cee8c44dwrowe * static const char *handle_TAKE1(cmd_parms *cmd, void *mconfig,
7bdef86e15d47d16dcbe7a5611683191774bd5fbgstein * char *word1);
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * Command handler for a TAKE2 directive. TAKE2 commands must always have
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * exactly two arguments.
7bdef86e15d47d16dcbe7a5611683191774bd5fbgstein * static const char *handle_TAKE2(cmd_parms *cmd, void *mconfig,
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * char *word1, char *word2);
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * Command handler for a TAKE3 directive. Like TAKE2, these must have exactly
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * three arguments, or the parser complains and doesn't bother calling us.
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * static const char *handle_TAKE3(cmd_parms *cmd, void *mconfig,
3d96ee83babeec32482c9082c9426340cee8c44dwrowe * char *word1, char *word2, char *word3);
2d2eda71267231c2526be701fe655db125852c1ffielding * Command handler for a TAKE12 directive. These can take either one or two
2d2eda71267231c2526be701fe655db125852c1ffielding * arguments.
2d2eda71267231c2526be701fe655db125852c1ffielding * - word2 is a NULL pointer if no second argument was specified.
2d2eda71267231c2526be701fe655db125852c1ffielding * static const char *handle_TAKE12(cmd_parms *cmd, void *mconfig,
2d2eda71267231c2526be701fe655db125852c1ffielding * char *word1, char *word2);
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * Command handler for a TAKE123 directive. A TAKE123 directive can be given,
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * as might be expected, one, two, or three arguments.
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * - word2 is a NULL pointer if no second argument was specified.
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * - word3 is a NULL pointer if no third argument was specified.
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * static const char *handle_TAKE123(cmd_parms *cmd, void *mconfig,
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * char *word1, char *word2, char *word3);
3d96ee83babeec32482c9082c9426340cee8c44dwrowe * Command handler for a TAKE13 directive. Either one or three arguments are
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm * permitted - no two-parameters-only syntax is allowed.
7bdef86e15d47d16dcbe7a5611683191774bd5fbgstein * - word2 and word3 are NULL pointers if only one argument was specified.
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * static const char *handle_TAKE13(cmd_parms *cmd, void *mconfig,
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * char *word1, char *word2, char *word3);
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * Command handler for a TAKE23 directive. At least two and as many as three
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * arguments must be specified.
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * - word3 is a NULL pointer if no third argument was specified.
3d96ee83babeec32482c9082c9426340cee8c44dwrowe * static const char *handle_TAKE23(cmd_parms *cmd, void *mconfig,
2d2eda71267231c2526be701fe655db125852c1ffielding * char *word1, char *word2, char *word3);
62db15de4c1f335a64d45821796ae197cff94ef8rbb * Command handler for a ITERATE directive.
62db15de4c1f335a64d45821796ae197cff94ef8rbb * - Handler is called once for each of n arguments given to the directive.
62db15de4c1f335a64d45821796ae197cff94ef8rbb * - word1 points to each argument in turn.
62db15de4c1f335a64d45821796ae197cff94ef8rbb * static const char *handle_ITERATE(cmd_parms *cmd, void *mconfig,
62db15de4c1f335a64d45821796ae197cff94ef8rbb * char *word1);
62db15de4c1f335a64d45821796ae197cff94ef8rbb * Command handler for a ITERATE2 directive.
62db15de4c1f335a64d45821796ae197cff94ef8rbb * - Handler is called once for each of the second and subsequent arguments
62db15de4c1f335a64d45821796ae197cff94ef8rbb * given to the directive.
62db15de4c1f335a64d45821796ae197cff94ef8rbb * - word1 is the same for each call for a particular directive instance (the
62db15de4c1f335a64d45821796ae197cff94ef8rbb * first argument).
62db15de4c1f335a64d45821796ae197cff94ef8rbb * - word2 points to each of the second and subsequent arguments in turn.
62db15de4c1f335a64d45821796ae197cff94ef8rbb * static const char *handle_ITERATE2(cmd_parms *cmd, void *mconfig,
62db15de4c1f335a64d45821796ae197cff94ef8rbb * char *word1, char *word2);
62db15de4c1f335a64d45821796ae197cff94ef8rbb/*--------------------------------------------------------------------------*/
62db15de4c1f335a64d45821796ae197cff94ef8rbb/* These routines are strictly internal to this module, and support its */
62db15de4c1f335a64d45821796ae197cff94ef8rbb/* operation. They are not referenced by any external portion of the */
62db15de4c1f335a64d45821796ae197cff94ef8rbb/* server. */
62db15de4c1f335a64d45821796ae197cff94ef8rbb/*--------------------------------------------------------------------------*/
62db15de4c1f335a64d45821796ae197cff94ef8rbb * Locate our directory configuration record for the current request.
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar return (excfg *) ap_get_module_config(r->per_dir_config, &example_module);
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar * Locate our server configuration record for the specified server.
3d96ee83babeec32482c9082c9426340cee8c44dwrowe return (excfg *) ap_get_module_config(s->module_config, &example_module);
a19698aebe10b9d41574e4a73794ba7d4cecd78btrawick * Likewise for our configuration record for the specified request.
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar return (excfg *) ap_get_module_config(r->request_config, &example_module);
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar * This routine sets up some module-wide cells if they haven't been already.
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar * If we haven't already allocated our module-private pool, do so now.
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar * Likewise for the ap_table_t of routine/environment pairs we visit outside of
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar * request context.
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar * This routine is used to add a trace of a callback to the list. We're
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar * passed the server record (if available), the request record (if available),
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar * a pointer to our private configuration record (if available) for the
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar * environment to which the callback is supposed to apply, and some text. We
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar * turn this into a textual representation and add it to the tail of the list.
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar * The list can be displayed by the example_handler() routine.
3d96ee83babeec32482c9082c9426340cee8c44dwrowe * If the call occurs within a request context (i.e., we're passed a request
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar * record), we put the trace into the request ap_context_t and attach it to the
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar * request via the notes mechanism. Otherwise, the trace gets added
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar * to the static (non-request-specific) list.
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar * Note that the r->notes ap_table_t is only for storing strings; if you need to
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar * maintain per-request data of any other type, you need to use another
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar * mechanism.
2d2eda71267231c2526be701fe655db125852c1ffieldingstatic void trace_add(server_rec *s, request_rec *r, excfg *mconfig,
2d2eda71267231c2526be701fe655db125852c1ffielding const char *note)
61fd0cab072a05b855cbef9c585702401ac5ae29rbb const char *sofar;
61fd0cab072a05b855cbef9c585702401ac5ae29rbb const char *trace_copy;
3d96ee83babeec32482c9082c9426340cee8c44dwrowe * Make sure our pools and tables are set up - we need 'em.
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * Now, if we're in request-context, we use the request pool.
61fd0cab072a05b855cbef9c585702401ac5ae29rbb if (r != NULL) {
61fd0cab072a05b855cbef9c585702401ac5ae29rbb if ((trace_copy = ap_table_get(r->notes, TRACE_NOTE)) == NULL) {
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * We're not in request context, so the trace gets attached to our
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * module-wide pool. We do the create/destroy every time we're called
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * in non-request context; this avoids leaking memory in some of
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * the subsequent calls that allocate memory only once (such as the
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * key formation below).
a6b9ed64fdf548c61de9714e2cfb999ec59d149cgstein * Make a new sub-pool and copy any existing trace to it. Point the
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * trace cell at the copied value.
3d96ee83babeec32482c9082c9426340cee8c44dwrowe * Now, if we have a sub-pool from before, nuke it and replace with
a6b9ed64fdf548c61de9714e2cfb999ec59d149cgstein * the one we just allocated.
3d96ee83babeec32482c9082c9426340cee8c44dwrowe * If we weren't passed a configuration record, we can't figure out to
a6b9ed64fdf548c61de9714e2cfb999ec59d149cgstein * what location this call applies. This only happens for co-routines
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * that don't operate in a particular directory or server context. If we
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * got a valid record, extract the location (directory or server) to which
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * it applies.
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * Now, if we're not in request context, see if we've been called with
3d96ee83babeec32482c9082c9426340cee8c44dwrowe * this particular combination before. The ap_table_t is allocated in the
2d2eda71267231c2526be701fe655db125852c1ffielding * module's private pool, which doesn't get destroyed.
61fd0cab072a05b855cbef9c585702401ac5ae29rbb if (r == NULL) {
2d2eda71267231c2526be701fe655db125852c1ffielding * Been here, done this.
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * First time for this combination of routine and environment -
2d2eda71267231c2526be701fe655db125852c1ffielding * log it so we don't do it again.
d839a9822ee53ce00da24c15f2d9fe054233d342gstein addon = ap_pstrcat(p, " <LI>\n", " <DL>\n", " <DT><SAMP>",
3d96ee83babeec32482c9082c9426340cee8c44dwrowe if (r != NULL) {
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * You *could* change the following if you wanted to see the calling
346029f34d03eb20d84fc35664426d3874b00f9ewrowe * sequence reported in the server's error_log, but beware - almost all of
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * these co-routines are called for every single request, and the impact
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * on the size (and readability) of the error_log is considerable.
61fd0cab072a05b855cbef9c585702401ac5ae29rbb ap_log_error(APLOG_MARK, APLOG_DEBUG, s, "mod_example: %s", note);
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/*--------------------------------------------------------------------------*/
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* We prototyped the various syntax for command handlers (routines that */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* are called when the configuration parser detects a directive declared */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* by our module) earlier. Now we actually declare a "real" routine that */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* will be invoked by the parser when our "real" directive is */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* encountered. */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* If a command handler encounters a problem processing the directive, it */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* signals this fact by returning a non-NULL pointer to a string */
3d96ee83babeec32482c9082c9426340cee8c44dwrowe/* describing the problem. */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* The magic return value DECLINE_CMD is used to deal with directives */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* that might be declared by multiple modules. If the command handler */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* returns NULL, the directive was processed; if it returns DECLINE_CMD, */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* the next module (if any) that declares the directive is given a chance */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* at it. If it returns any other value, it's treated as the text of an */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* error message. */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/*--------------------------------------------------------------------------*/
11a7b0dff22d26770b532c174d1cf2e7b56ec244wrowe * Command handler for the NO_ARGS "Example" directive. All we do is mark the
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * call in the trace log, and flag the applicability of the directive to the
11a7b0dff22d26770b532c174d1cf2e7b56ec244wrowe * current location in that location's configuration record.
61fd0cab072a05b855cbef9c585702401ac5ae29rbbstatic const char *cmd_example(cmd_parms *cmd, void *mconfig)
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * "Example Wuz Here"
a6b9ed64fdf548c61de9714e2cfb999ec59d149cgstein/*--------------------------------------------------------------------------*/
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* Now we declare our content handlers, which are invoked when the server */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* encounters a document which our module is supposed to have a chance to */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* see. (See mod_mime's SetHandler and AddHandler directives, and the */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* mod_info and mod_status examples, for more details.) */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* Since content handlers are dumping data directly into the connexion */
3d96ee83babeec32482c9082c9426340cee8c44dwrowe/* (using the r*() routines, such as rputs() and rprintf()) without */
a6b9ed64fdf548c61de9714e2cfb999ec59d149cgstein/* intervention by other parts of the server, they need to make */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* sure any accumulated HTTP headers are sent first. This is done by */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* calling send_http_header(). Otherwise, no header will be sent at all, */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/* and the output sent to the client will actually be HTTP-uncompliant. */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb/*--------------------------------------------------------------------------*/
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * Sample content handler. All this does is display the call list that has
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * been built up so far.
a6b9ed64fdf548c61de9714e2cfb999ec59d149cgstein * The return value instructs the caller concerning what happened and what to
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * do next:
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * OK ("we did our thing")
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * DECLINED ("this isn't something with which we want to get involved")
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * HTTP_mumble ("an error status should be reported")
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * We're about to start sending content, so we need to force the HTTP
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * headers to be sent at this point. Otherwise, no headers will be sent
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * at all. We can set any we like first, of course. **NOTE** Here's
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * where you set the "Content-type" header, and you do so by putting it in
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * r->content_type, *not* r->headers_out("Content-type"). If you don't
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * set it, it will be filled in with the server's default type (typically
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * "text/plain"). You *must* also ensure that r->content_type is lower
3d96ee83babeec32482c9082c9426340cee8c44dwrowe * We also need to start a timer so the server can know if the connexion
2d2eda71267231c2526be701fe655db125852c1ffielding * is broken.
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * If we're only supposed to send header information (HEAD request), we're
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * already there.
2d2eda71267231c2526be701fe655db125852c1ffielding * Now send our actual output. Since we tagged this as being
e351a4349a3dcc2e8d9c27bcdf72414bdde0942frbb * "text/html", we need to embed any HTML.
61fd0cab072a05b855cbef9c585702401ac5ae29rbb ap_rputs(" <TITLE>mod_example Module Content-Handler Output\n", r);
3d96ee83babeec32482c9082c9426340cee8c44dwrowe ap_rputs(" <H1><SAMP>mod_example</SAMP> Module Content-Handler Output\n", r);
344f3bc38dfccf6261d5bb8d689794cde113b3d6coar ap_rprintf(r, " Server built: \"%s\"\n", ap_get_server_built());
3d96ee83babeec32482c9082c9426340cee8c44dwrowe ap_rputs(" The format for the callback trace is:\n", r);
fd0edaa8e3d4dd67d0604ccef2e96b071db96643fielding ap_rputs(" <DT><EM>n</EM>.<SAMP><routine-name>", r);
fd0edaa8e3d4dd67d0604ccef2e96b071db96643fielding ap_rputs(" <DD><SAMP>[<applies-to>]</SAMP>\n", r);
61fd0cab072a05b855cbef9c585702401ac5ae29rbb ap_rputs(" The <SAMP><routine-data></SAMP> is supplied by\n", r);
61fd0cab072a05b855cbef9c585702401ac5ae29rbb ap_rputs(" the routine when it requests the trace,\n", r);
61fd0cab072a05b855cbef9c585702401ac5ae29rbb ap_rputs(" and the <SAMP><applies-to></SAMP> is extracted\n", r);
61fd0cab072a05b855cbef9c585702401ac5ae29rbb ap_rputs(" from the configuration record at the time of the trace.\n", r);
61fd0cab072a05b855cbef9c585702401ac5ae29rbb ap_rputs(" <STRONG>SVR()</STRONG> indicates a server environment\n", r);
61fd0cab072a05b855cbef9c585702401ac5ae29rbb ap_rputs(" (blank means the main or default server, otherwise it's\n", r);
42ce672c516baf6e4eaed18ccc1647de2d456d8edougm ap_rputs(" the name of the VirtualHost); <STRONG>DIR()</STRONG>\n", r);
a6b9ed64fdf548c61de9714e2cfb999ec59d149cgstein ap_rputs(" indicates a location in the URL or filesystem\n", r);
61fd0cab072a05b855cbef9c585702401ac5ae29rbb ap_rprintf(r, " <H2>Static callbacks so far:</H2>\n <OL>\n%s </OL>\n",
61fd0cab072a05b855cbef9c585702401ac5ae29rbb ap_rputs(" <H2>Request-specific callbacks so far:</H2>\n", r);
61fd0cab072a05b855cbef9c585702401ac5ae29rbb ap_rprintf(r, " <OL>\n%s </OL>\n", ap_table_get(r->notes, TRACE_NOTE));
61fd0cab072a05b855cbef9c585702401ac5ae29rbb ap_rputs(" <H2>Environment for <EM>this</EM> call:</H2>\n", r);
a6b9ed64fdf548c61de9714e2cfb999ec59d149cgstein ap_rprintf(r, " <LI>Applies-to: <SAMP>%s</SAMP>\n </LI>\n", dcfg->loc);
61fd0cab072a05b855cbef9c585702401ac5ae29rbb ap_rprintf(r, " <LI>\"Example\" directive declared here: %s\n </LI>\n",
61fd0cab072a05b855cbef9c585702401ac5ae29rbb ap_rprintf(r, " <LI>\"Example\" inherited: %s\n </LI>\n",
a6b9ed64fdf548c61de9714e2cfb999ec59d149cgstein * We're all done, so cancel the timeout we set. Since this is probably
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * the end of the request we *could* assume this would be done during
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * post-processing - but it's possible that another handler might be
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * called and inherit our outstanding timer. Not good; to each its own.
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * We did what we wanted to do, so tell the rest of the server we
42ce672c516baf6e4eaed18ccc1647de2d456d8edougm * succeeded.
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb/*--------------------------------------------------------------------------*/
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb/* Now let's declare routines for each of the callback phase in order. */
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb/* (That's the order in which they're listed in the callback list, *not */
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb/* the order in which the server calls them! See the command_rec */
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb/* declaration near the bottom of this file.) Note that these may be */
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb/* called for situations that don't relate primarily to our function - in */
8b7047e519340545e6807c9749576a40a76b6d3frbb/* other words, the fixup handler shouldn't assume that the request has */
8b7047e519340545e6807c9749576a40a76b6d3frbb/* to do with "example" stuff. */
6d00a43be9ab145c89e8cc22bad59e3aa746f761jwoolley/* With the exception of the content handler, all of our routines will be */
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb/* called for each request, unless an earlier handler from another module */
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb/* aborted the sequence. */
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb/* Handlers that are declared as "int" can return the following: */
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb/* OK Handler accepted the request and did its thing with it. */
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb/* DECLINED Handler took no action. */
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb/* HTTP_mumble Handler looked at request and found it wanting. */
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb/* What the server does after calling a module handler depends upon the */
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb/* handler's return value. In all cases, if the handler returns */
561e5f16a2f9fb397aac4c283aaa87a752520a4ddougm/* DECLINED, the server will continue to the next module with an handler */
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb/* for the current phase. However, if the handler return a non-OK, */
561e5f16a2f9fb397aac4c283aaa87a752520a4ddougm/* non-DECLINED status, the server aborts the request right there. If */
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb/* the handler returns OK, the server's next action is phase-specific; */
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb/* see the individual handler comments below for details. */
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb/*--------------------------------------------------------------------------*/
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb * This function is called during server initialisation. Any information
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb * that needs to be recorded must be in static cells, since there's no
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb * configuration record.
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb * There is no return value.
c9a95767fbf0f5fb0976a06b97a256033925e433rbb * All our module initialiser does is add its trace to the log.
c9a95767fbf0f5fb0976a06b97a256033925e433rbb * Set up any module cells that ought to be initialised.
2d2eda71267231c2526be701fe655db125852c1ffielding * The arbitrary text we add to our trace entry indicates for which server
2d2eda71267231c2526be701fe655db125852c1ffielding * we're being called.
2d2eda71267231c2526be701fe655db125852c1ffielding note = ap_pstrcat(p, "example_init(", sname, ")", NULL);
char *note;
char *note;
return (void *) cfg;
void *newloc_conf)
char *note;
return (void *) merged_config;
return (void *) cfg;
void *server2_conf)
char *note;
return (void *) merged_config;
return DECLINED;
return DECLINED;
return DECLINED;
return DECLINED;
return DECLINED;
return DECLINED;
return OK;
return DECLINED;
return DECLINED;
{NULL}
{NULL}