home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1999 April / PCO0499.ISO / filesbbs / os2 / apach134.arj / APACH134.ZIP / src / modules / example / mod_example.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-01  |  43.6 KB  |  1,150 lines

  1. /* ====================================================================
  2.  * Copyright (c) 1995-1999 The Apache Group.  All rights reserved.
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions
  6.  * are met:
  7.  *
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer. 
  10.  *
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in
  13.  *    the documentation and/or other materials provided with the
  14.  *    distribution.
  15.  *
  16.  * 3. All advertising materials mentioning features or use of this
  17.  *    software must display the following acknowledgment:
  18.  *    "This product includes software developed by the Apache Group
  19.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  20.  *
  21.  * 4. The names "Apache Server" and "Apache Group" must not be used to
  22.  *    endorse or promote products derived from this software without
  23.  *    prior written permission. For written permission, please contact
  24.  *    apache@apache.org.
  25.  *
  26.  * 5. Products derived from this software may not be called "Apache"
  27.  *    nor may "Apache" appear in their names without prior written
  28.  *    permission of the Apache Group.
  29.  *
  30.  * 6. Redistributions of any form whatsoever must retain the following
  31.  *    acknowledgment:
  32.  *    "This product includes software developed by the Apache Group
  33.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
  36.  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  37.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  38.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  41.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  43.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  44.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  45.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  46.  * OF THE POSSIBILITY OF SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Group and was originally based
  51.  * on public domain software written at the National Center for
  52.  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
  53.  * For more information on the Apache Group and the Apache HTTP server
  54.  * project, please see <http://www.apache.org/>.
  55.  *
  56.  */
  57.  
  58. /* 
  59.  * Apache example module.  Provide demonstrations of how modules do things.
  60.  *
  61.  */
  62.  
  63. #include "httpd.h"
  64. #include "http_config.h"
  65. #include "http_core.h"
  66. #include "http_log.h"
  67. #include "http_main.h"
  68. #include "http_protocol.h"
  69. #include "util_script.h"
  70.  
  71. #include <stdio.h>
  72.  
  73. /*--------------------------------------------------------------------------*/
  74. /*                                                                          */
  75. /* Data declarations.                                                       */
  76. /*                                                                          */
  77. /* Here are the static cells and structure declarations private to our      */
  78. /* module.                                                                  */
  79. /*                                                                          */
  80. /*--------------------------------------------------------------------------*/
  81.  
  82. /*
  83.  * Sample configuration record.  Used for both per-directory and per-server
  84.  * configuration data.
  85.  *
  86.  * It's perfectly reasonable to have two different structures for the two
  87.  * different environments.  The same command handlers will be called for
  88.  * both, though, so the handlers need to be able to tell them apart.  One
  89.  * possibility is for both structures to start with an int which is zero for
  90.  * one and 1 for the other.
  91.  *
  92.  * Note that while the per-directory and per-server configuration records are
  93.  * available to most of the module handlers, they should be treated as
  94.  * READ-ONLY by all except the command and merge handlers.  Sometimes handlers
  95.  * are handed a record that applies to the current location by implication or
  96.  * inheritance, and modifying it will change the rules for other locations.
  97.  */
  98. typedef struct excfg {
  99.     int cmode;                  /* Environment to which record applies (directory,
  100.                                  * server, or combination).
  101.                                  */
  102. #define CONFIG_MODE_SERVER 1
  103. #define CONFIG_MODE_DIRECTORY 2
  104. #define CONFIG_MODE_COMBO 3     /* Shouldn't ever happen. */
  105.     int local;                  /* Boolean: "Example" directive declared here? */
  106.     int congenital;             /* Boolean: did we inherit an "Example"? */
  107.     char *trace;                /* Pointer to trace string. */
  108.     char *loc;                  /* Location to which this record applies. */
  109. } excfg;
  110.  
  111. /*
  112.  * Let's set up a module-local static cell to point to the accreting callback
  113.  * trace.  As each API callback is made to us, we'll tack on the particulars
  114.  * to whatever we've already recorded.  To avoid massive memory bloat as
  115.  * directories are walked again and again, we record the routine/environment
  116.  * the first time (non-request context only), and ignore subsequent calls for
  117.  * the same routine/environment.
  118.  */
  119. static const char *trace = NULL;
  120. static table *static_calls_made = NULL;
  121.  
  122. /*
  123.  * To avoid leaking memory from pools other than the per-request one, we
  124.  * allocate a module-private pool, and then use a sub-pool of that which gets
  125.  * freed each time we modify the trace.  That way previous layers of trace
  126.  * data don't get lost.
  127.  */
  128. static pool *example_pool = NULL;
  129. static pool *example_subpool = NULL;
  130.  
  131. /*
  132.  * Declare ourselves so the configuration routines can find and know us.
  133.  * We'll fill it in at the end of the module.
  134.  */
  135. module example_module;
  136.  
  137. /*--------------------------------------------------------------------------*/
  138. /*                                                                          */
  139. /* The following pseudo-prototype declarations illustrate the parameters    */
  140. /* passed to command handlers for the different types of directive          */
  141. /* syntax.  If an argument was specified in the directive definition        */
  142. /* (look for "command_rec" below), it's available to the command handler    */
  143. /* via the (void *) info field in the cmd_parms argument passed to the      */
  144. /* handler (cmd->info for the examples below).                              */
  145. /*                                                                          */
  146. /*--------------------------------------------------------------------------*/
  147.  
  148. /*
  149.  * Command handler for a NO_ARGS directive.
  150.  *
  151.  * static const char *handle_NO_ARGS(cmd_parms *cmd, void *mconfig);
  152.  */
  153.  
  154. /*
  155.  * Command handler for a RAW_ARGS directive.  The "args" argument is the text
  156.  * of the commandline following the directive itself.
  157.  *
  158.  * static const char *handle_RAW_ARGS(cmd_parms *cmd, void *mconfig,
  159.  *                                    const char *args);
  160.  */
  161.  
  162. /*
  163.  * Command handler for a FLAG directive.  The single parameter is passed in
  164.  * "bool", which is either zero or not for Off or On respectively.
  165.  *
  166.  * static const char *handle_FLAG(cmd_parms *cmd, void *mconfig, int bool);
  167.  */
  168.  
  169. /*
  170.  * Command handler for a TAKE1 directive.  The single parameter is passed in
  171.  * "word1".
  172.  *
  173.  * static const char *handle_TAKE1(cmd_parms *cmd, void *mconfig,
  174.  *                                 char *word1);
  175.  */
  176.  
  177. /*
  178.  * Command handler for a TAKE2 directive.  TAKE2 commands must always have
  179.  * exactly two arguments.
  180.  *
  181.  * static const char *handle_TAKE2(cmd_parms *cmd, void *mconfig,
  182.  *                                 char *word1, char *word2);
  183.  */
  184.  
  185. /*
  186.  * Command handler for a TAKE3 directive.  Like TAKE2, these must have exactly
  187.  * three arguments, or the parser complains and doesn't bother calling us.
  188.  *
  189.  * static const char *handle_TAKE3(cmd_parms *cmd, void *mconfig,
  190.  *                                 char *word1, char *word2, char *word3);
  191.  */
  192.  
  193. /*
  194.  * Command handler for a TAKE12 directive.  These can take either one or two
  195.  * arguments.
  196.  * - word2 is a NULL pointer if no second argument was specified.
  197.  *
  198.  * static const char *handle_TAKE12(cmd_parms *cmd, void *mconfig,
  199.  *                                  char *word1, char *word2);
  200.  */
  201.  
  202. /*
  203.  * Command handler for a TAKE123 directive.  A TAKE123 directive can be given,
  204.  * as might be expected, one, two, or three arguments.
  205.  * - word2 is a NULL pointer if no second argument was specified.
  206.  * - word3 is a NULL pointer if no third argument was specified.
  207.  *
  208.  * static const char *handle_TAKE123(cmd_parms *cmd, void *mconfig,
  209.  *                                   char *word1, char *word2, char *word3);
  210.  */
  211.  
  212. /*
  213.  * Command handler for a TAKE13 directive.  Either one or three arguments are
  214.  * permitted - no two-parameters-only syntax is allowed.
  215.  * - word2 and word3 are NULL pointers if only one argument was specified.
  216.  *
  217.  * static const char *handle_TAKE13(cmd_parms *cmd, void *mconfig,
  218.  *                                  char *word1, char *word2, char *word3);
  219.  */
  220.  
  221. /*
  222.  * Command handler for a TAKE23 directive.  At least two and as many as three
  223.  * arguments must be specified.
  224.  * - word3 is a NULL pointer if no third argument was specified.
  225.  *
  226.  * static const char *handle_TAKE23(cmd_parms *cmd, void *mconfig,
  227.  *                                  char *word1, char *word2, char *word3);
  228.  */
  229.  
  230. /*
  231.  * Command handler for a ITERATE directive.
  232.  * - Handler is called once for each of n arguments given to the directive.
  233.  * - word1 points to each argument in turn.
  234.  *
  235.  * static const char *handle_ITERATE(cmd_parms *cmd, void *mconfig,
  236.  *                                   char *word1);
  237.  */
  238.  
  239. /*
  240.  * Command handler for a ITERATE2 directive.
  241.  * - Handler is called once for each of the second and subsequent arguments
  242.  *   given to the directive.
  243.  * - word1 is the same for each call for a particular directive instance (the
  244.  *   first argument).
  245.  * - word2 points to each of the second and subsequent arguments in turn.
  246.  *
  247.  * static const char *handle_ITERATE2(cmd_parms *cmd, void *mconfig,
  248.  *                                    char *word1, char *word2);
  249.  */
  250.  
  251. /*--------------------------------------------------------------------------*/
  252. /*                                                                          */
  253. /* These routines are strictly internal to this module, and support its     */
  254. /* operation.  They are not referenced by any external portion of the       */
  255. /* server.                                                                  */
  256. /*                                                                          */
  257. /*--------------------------------------------------------------------------*/
  258.  
  259. /*
  260.  * Locate our directory configuration record for the current request.
  261.  */
  262. static excfg *our_dconfig(request_rec *r)
  263. {
  264.  
  265.     return (excfg *) ap_get_module_config(r->per_dir_config, &example_module);
  266. }
  267.  
  268. #if 0
  269. /*
  270.  * Locate our server configuration record for the specified server.
  271.  */
  272. static excfg *our_sconfig(server_rec *s)
  273. {
  274.  
  275.     return (excfg *) ap_get_module_config(s->module_config, &example_module);
  276. }
  277.  
  278. /*
  279.  * Likewise for our configuration record for the specified request.
  280.  */
  281. static excfg *our_rconfig(request_rec *r)
  282. {
  283.  
  284.     return (excfg *) ap_get_module_config(r->request_config, &example_module);
  285. }
  286. #endif
  287.  
  288. /*
  289.  * This routine sets up some module-wide cells if they haven't been already.
  290.  */
  291. static void setup_module_cells()
  292. {
  293.     /*
  294.      * If we haven't already allocated our module-private pool, do so now.
  295.      */
  296.     if (example_pool == NULL) {
  297.         example_pool = ap_make_sub_pool(NULL);
  298.     };
  299.     /*
  300.      * Likewise for the table of routine/environment pairs we visit outside of
  301.      * request context.
  302.      */
  303.     if (static_calls_made == NULL) {
  304.         static_calls_made = ap_make_table(example_pool, 16);
  305.     };
  306. }
  307.  
  308. /*
  309.  * This routine is used to add a trace of a callback to the list.  We're
  310.  * passed the server record (if available), the request record (if available),
  311.  * a pointer to our private configuration record (if available) for the
  312.  * environment to which the callback is supposed to apply, and some text.  We
  313.  * turn this into a textual representation and add it to the tail of the list.
  314.  * The list can be displayed by the example_handler() routine.
  315.  *
  316.  * If the call occurs within a request context (i.e., we're passed a request
  317.  * record), we put the trace into the request pool and attach it to the
  318.  * request via the notes mechanism.  Otherwise, the trace gets added
  319.  * to the static (non-request-specific) list.
  320.  *
  321.  * Note that the r->notes table is only for storing strings; if you need to
  322.  * maintain per-request data of any other type, you need to use another
  323.  * mechanism.
  324.  */
  325.  
  326. #define TRACE_NOTE "example-trace"
  327.  
  328. static void trace_add(server_rec *s, request_rec *r, excfg *mconfig,
  329.                       const char *note)
  330. {
  331.  
  332.     const char *sofar;
  333.     char *addon;
  334.     char *where;
  335.     pool *p;
  336.     const char *trace_copy;
  337.  
  338.     /*
  339.      * Make sure our pools and tables are set up - we need 'em.
  340.      */
  341.     setup_module_cells();
  342.     /*
  343.      * Now, if we're in request-context, we use the request pool.
  344.      */
  345.     if (r != NULL) {
  346.         p = r->pool;
  347.         if ((trace_copy = ap_table_get(r->notes, TRACE_NOTE)) == NULL) {
  348.             trace_copy = "";
  349.         }
  350.     }
  351.     else {
  352.         /*
  353.          * We're not in request context, so the trace gets attached to our
  354.          * module-wide pool.  We do the create/destroy every time we're called
  355.          * in non-request context; this avoids leaking memory in some of
  356.          * the subsequent calls that allocate memory only once (such as the
  357.          * key formation below).
  358.          *
  359.          * Make a new sub-pool and copy any existing trace to it.  Point the
  360.          * trace cell at the copied value.
  361.          */
  362.         p = ap_make_sub_pool(example_pool);
  363.         if (trace != NULL) {
  364.             trace = ap_pstrdup(p, trace);
  365.         }
  366.         /*
  367.          * Now, if we have a sub-pool from before, nuke it and replace with
  368.          * the one we just allocated.
  369.          */
  370.         if (example_subpool != NULL) {
  371.             ap_destroy_pool(example_subpool);
  372.         }
  373.         example_subpool = p;
  374.         trace_copy = trace;
  375.     }
  376.     /*
  377.      * If we weren't passed a configuration record, we can't figure out to
  378.      * what location this call applies.  This only happens for co-routines
  379.      * that don't operate in a particular directory or server context.  If we
  380.      * got a valid record, extract the location (directory or server) to which
  381.      * it applies.
  382.      */
  383.     where = (mconfig != NULL) ? mconfig->loc : "nowhere";
  384.     where = (where != NULL) ? where : "";
  385.     /*
  386.      * Now, if we're not in request context, see if we've been called with
  387.      * this particular combination before.  The table is allocated in the
  388.      * module's private pool, which doesn't get destroyed.
  389.      */
  390.     if (r == NULL) {
  391.         char *key;
  392.  
  393.         key = ap_pstrcat(p, note, ":", where, NULL);
  394.         if (ap_table_get(static_calls_made, key) != NULL) {
  395.             /*
  396.              * Been here, done this.
  397.              */
  398.             return;
  399.         }
  400.         else {
  401.             /*
  402.              * First time for this combination of routine and environment -
  403.              * log it so we don't do it again.
  404.              */
  405.             ap_table_set(static_calls_made, key, "been here");
  406.         }
  407.     }
  408.     addon = ap_pstrcat(p, "   <LI>\n", "    <DL>\n", "     <DT><SAMP>",
  409.                     note, "</SAMP>\n", "     </DT>\n", "     <DD><SAMP>[",
  410.                     where, "]</SAMP>\n", "     </DD>\n", "    </DL>\n",
  411.                     "   </LI>\n", NULL);
  412.     sofar = (trace_copy == NULL) ? "" : trace_copy;
  413.     trace_copy = ap_pstrcat(p, sofar, addon, NULL);
  414.     if (r != NULL) {
  415.         ap_table_set(r->notes, TRACE_NOTE, trace_copy);
  416.     }
  417.     else {
  418.         trace = trace_copy;
  419.     }
  420.     /*
  421.      * You *could* change the following if you wanted to see the calling
  422.      * sequence reported in the server's error_log, but beware - almost all of
  423.      * these co-routines are called for every single request, and the impact
  424.      * on the size (and readability) of the error_log is considerable.
  425.      */
  426. #define EXAMPLE_LOG_EACH 0
  427.     if (EXAMPLE_LOG_EACH && (s != NULL)) {
  428.         ap_log_error(APLOG_MARK, APLOG_DEBUG, s, "mod_example: %s", note);
  429.     }
  430. }
  431.  
  432. /*--------------------------------------------------------------------------*/
  433. /* We prototyped the various syntax for command handlers (routines that     */
  434. /* are called when the configuration parser detects a directive declared    */
  435. /* by our module) earlier.  Now we actually declare a "real" routine that   */
  436. /* will be invoked by the parser when our "real" directive is               */
  437. /* encountered.                                                             */
  438. /*                                                                          */
  439. /* If a command handler encounters a problem processing the directive, it   */
  440. /* signals this fact by returning a non-NULL pointer to a string            */
  441. /* describing the problem.                                                  */
  442. /*                                                                          */
  443. /* The magic return value DECLINE_CMD is used to deal with directives       */
  444. /* that might be declared by multiple modules.  If the command handler      */
  445. /* returns NULL, the directive was processed; if it returns DECLINE_CMD,    */
  446. /* the next module (if any) that declares the directive is given a chance   */
  447. /* at it.  If it returns any other value, it's treated as the text of an    */
  448. /* error message.                                                           */
  449. /*--------------------------------------------------------------------------*/
  450. /* 
  451.  * Command handler for the NO_ARGS "Example" directive.  All we do is mark the
  452.  * call in the trace log, and flag the applicability of the directive to the
  453.  * current location in that location's configuration record.
  454.  */
  455. static const char *cmd_example(cmd_parms *cmd, void *mconfig)
  456. {
  457.  
  458.     excfg *cfg = (excfg *) mconfig;
  459.  
  460.     /*
  461.      * "Example Wuz Here"
  462.      */
  463.     cfg->local = 1;
  464.     trace_add(cmd->server, NULL, cfg, "cmd_example()");
  465.     return NULL;
  466. }
  467.  
  468. /*--------------------------------------------------------------------------*/
  469. /*                                                                          */
  470. /* Now we declare our content handlers, which are invoked when the server   */
  471. /* encounters a document which our module is supposed to have a chance to   */
  472. /* see.  (See mod_mime's SetHandler and AddHandler directives, and the      */
  473. /* mod_info and mod_status examples, for more details.)                     */
  474. /*                                                                          */
  475. /* Since content handlers are dumping data directly into the connexion      */
  476. /* (using the r*() routines, such as rputs() and rprintf()) without         */
  477. /* intervention by other parts of the server, they need to make             */
  478. /* sure any accumulated HTTP headers are sent first.  This is done by       */
  479. /* calling send_http_header().  Otherwise, no header will be sent at all,   */
  480. /* and the output sent to the client will actually be HTTP-uncompliant.     */
  481. /*--------------------------------------------------------------------------*/
  482. /* 
  483.  * Sample content handler.  All this does is display the call list that has
  484.  * been built up so far.
  485.  *
  486.  * The return value instructs the caller concerning what happened and what to
  487.  * do next:
  488.  *  OK ("we did our thing")
  489.  *  DECLINED ("this isn't something with which we want to get involved")
  490.  *  HTTP_mumble ("an error status should be reported")
  491.  */
  492. static int example_handler(request_rec *r)
  493. {
  494.  
  495.     excfg *dcfg;
  496.  
  497.     dcfg = our_dconfig(r);
  498.     trace_add(r->server, r, dcfg, "example_handler()");
  499.     /*
  500.      * We're about to start sending content, so we need to force the HTTP
  501.      * headers to be sent at this point.  Otherwise, no headers will be sent
  502.      * at all.  We can set any we like first, of course.  **NOTE** Here's
  503.      * where you set the "Content-type" header, and you do so by putting it in
  504.      * r->content_type, *not* r->headers_out("Content-type").  If you don't
  505.      * set it, it will be filled in with the server's default type (typically
  506.      * "text/plain").  You *must* also ensure that r->content_type is lower
  507.      * case.
  508.      *
  509.      * We also need to start a timer so the server can know if the connexion
  510.      * is broken.
  511.      */
  512.     r->content_type = "text/html";
  513.     ap_soft_timeout("send example call trace", r);
  514.     ap_send_http_header(r);
  515.     /*
  516.      * If we're only supposed to send header information (HEAD request), we're
  517.      * already there.
  518.      */
  519.     if (r->header_only) {
  520.         ap_kill_timeout(r);
  521.         return OK;
  522.     }
  523.  
  524.     /*
  525.      * Now send our actual output.  Since we tagged this as being
  526.      * "text/html", we need to embed any HTML.
  527.      */
  528.     ap_rputs("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n", r);
  529.     ap_rputs("<HTML>\n", r);
  530.     ap_rputs(" <HEAD>\n", r);
  531.     ap_rputs("  <TITLE>mod_example Module Content-Handler Output\n", r);
  532.     ap_rputs("  </TITLE>\n", r);
  533.     ap_rputs(" </HEAD>\n", r);
  534.     ap_rputs(" <BODY>\n", r);
  535.     ap_rputs("  <H1><SAMP>mod_example</SAMP> Module Content-Handler Output\n", r);
  536.     ap_rputs("  </H1>\n", r);
  537.     ap_rputs("  <P>\n", r);
  538.     ap_rprintf(r, "  Apache HTTP Server version: \"%s\"\n",
  539.         ap_get_server_version());
  540.     ap_rputs("  <BR>\n", r);
  541.     ap_rprintf(r, "  Server built: \"%s\"\n", ap_get_server_built());
  542.     ap_rputs("  </P>\n", r);;
  543.     ap_rputs("  <P>\n", r);
  544.     ap_rputs("  The format for the callback trace is:\n", r);
  545.     ap_rputs("  </P>\n", r);
  546.     ap_rputs("  <DL>\n", r);
  547.     ap_rputs("   <DT><EM>n</EM>.<SAMP><routine-name>", r);
  548.     ap_rputs("(<routine-data>)</SAMP>\n", r);
  549.     ap_rputs("   </DT>\n", r);
  550.     ap_rputs("   <DD><SAMP>[<applies-to>]</SAMP>\n", r);
  551.     ap_rputs("   </DD>\n", r);
  552.     ap_rputs("  </DL>\n", r);
  553.     ap_rputs("  <P>\n", r);
  554.     ap_rputs("  The <SAMP><routine-data></SAMP> is supplied by\n", r);
  555.     ap_rputs("  the routine when it requests the trace,\n", r);
  556.     ap_rputs("  and the <SAMP><applies-to></SAMP> is extracted\n", r);
  557.     ap_rputs("  from the configuration record at the time of the trace.\n", r);
  558.     ap_rputs("  <STRONG>SVR()</STRONG> indicates a server environment\n", r);
  559.     ap_rputs("  (blank means the main or default server, otherwise it's\n", r);
  560.     ap_rputs("  the name of the VirtualHost); <STRONG>DIR()</STRONG>\n", r);
  561.     ap_rputs("  indicates a location in the URL or filesystem\n", r);
  562.     ap_rputs("  namespace.\n", r);
  563.     ap_rputs("  </P>\n", r);
  564.     ap_rprintf(r, "  <H2>Static callbacks so far:</H2>\n  <OL>\n%s  </OL>\n",
  565.             trace);
  566.     ap_rputs("  <H2>Request-specific callbacks so far:</H2>\n", r);
  567.     ap_rprintf(r, "  <OL>\n%s  </OL>\n", ap_table_get(r->notes, TRACE_NOTE));
  568.     ap_rputs("  <H2>Environment for <EM>this</EM> call:</H2>\n", r);
  569.     ap_rputs("  <UL>\n", r);
  570.     ap_rprintf(r, "   <LI>Applies-to: <SAMP>%s</SAMP>\n   </LI>\n", dcfg->loc);
  571.     ap_rprintf(r, "   <LI>\"Example\" directive declared here: %s\n   </LI>\n",
  572.             (dcfg->local ? "YES" : "NO"));
  573.     ap_rprintf(r, "   <LI>\"Example\" inherited: %s\n   </LI>\n",
  574.             (dcfg->congenital ? "YES" : "NO"));
  575.     ap_rputs("  </UL>\n", r);
  576.     ap_rputs(" </BODY>\n", r);
  577.     ap_rputs("</HTML>\n", r);
  578.     /*
  579.      * We're all done, so cancel the timeout we set.  Since this is probably
  580.      * the end of the request we *could* assume this would be done during
  581.      * post-processing - but it's possible that another handler might be
  582.      * called and inherit our outstanding timer.  Not good; to each its own.
  583.      */
  584.     ap_kill_timeout(r);
  585.     /*
  586.      * We did what we wanted to do, so tell the rest of the server we
  587.      * succeeded.
  588.      */
  589.     return OK;
  590. }
  591.  
  592. /*--------------------------------------------------------------------------*/
  593. /*                                                                          */
  594. /* Now let's declare routines for each of the callback phase in order.      */
  595. /* (That's the order in which they're listed in the callback list, *not     */
  596. /* the order in which the server calls them!  See the command_rec           */
  597. /* declaration near the bottom of this file.)  Note that these may be       */
  598. /* called for situations that don't relate primarily to our function - in   */
  599. /* other words, the fixup handler shouldn't assume that the request has     */
  600. /* to do with "example" stuff.                                              */
  601. /*                                                                          */
  602. /* With the exception of the content handler, all of our routines will be   */
  603. /* called for each request, unless an earlier handler from another module   */
  604. /* aborted the sequence.                                                    */
  605. /*                                                                          */
  606. /* Handlers that are declared as "int" can return the following:            */
  607. /*                                                                          */
  608. /*  OK          Handler accepted the request and did its thing with it.     */
  609. /*  DECLINED    Handler took no action.                                     */
  610. /*  HTTP_mumble Handler looked at request and found it wanting.             */
  611. /*                                                                          */
  612. /* What the server does after calling a module handler depends upon the     */
  613. /* handler's return value.  In all cases, if the handler returns            */
  614. /* DECLINED, the server will continue to the next module with an handler    */
  615. /* for the current phase.  However, if the handler return a non-OK,         */
  616. /* non-DECLINED status, the server aborts the request right there.  If      */
  617. /* the handler returns OK, the server's next action is phase-specific;      */
  618. /* see the individual handler comments below for details.                   */
  619. /*                                                                          */
  620. /*--------------------------------------------------------------------------*/
  621. /* 
  622.  * This function is called during server initialisation.  Any information
  623.  * that needs to be recorded must be in static cells, since there's no
  624.  * configuration record.
  625.  *
  626.  * There is no return value.
  627.  */
  628.  
  629. /*
  630.  * All our module-initialiser does is add its trace to the log.
  631.  */
  632. static void example_init(server_rec *s, pool *p)
  633. {
  634.  
  635.     char *note;
  636.     char *sname = s->server_hostname;
  637.  
  638.     /*
  639.      * Set up any module cells that ought to be initialised.
  640.      */
  641.     setup_module_cells();
  642.     /*
  643.      * The arbitrary text we add to our trace entry indicates for which server
  644.      * we're being called.
  645.      */
  646.     sname = (sname != NULL) ? sname : "";
  647.     note = ap_pstrcat(p, "example_init(", sname, ")", NULL);
  648.     trace_add(s, NULL, NULL, note);
  649. }
  650.  
  651. /* 
  652.  * This function is called during server initialisation when an heavy-weight
  653.  * process (such as a child) is being initialised.  As with the
  654.  * module-initialisation function, any information that needs to be recorded
  655.  * must be in static cells, since there's no configuration record.
  656.  *
  657.  * There is no return value.
  658.  */
  659.  
  660. /*
  661.  * All our process-initialiser does is add its trace to the log.
  662.  */
  663. static void example_child_init(server_rec *s, pool *p)
  664. {
  665.  
  666.     char *note;
  667.     char *sname = s->server_hostname;
  668.  
  669.     /*
  670.      * Set up any module cells that ought to be initialised.
  671.      */
  672.     setup_module_cells();
  673.     /*
  674.      * The arbitrary text we add to our trace entry indicates for which server
  675.      * we're being called.
  676.      */
  677.     sname = (sname != NULL) ? sname : "";
  678.     note = ap_pstrcat(p, "example_child_init(", sname, ")", NULL);
  679.     trace_add(s, NULL, NULL, note);
  680. }
  681.  
  682. /* 
  683.  * This function is called when an heavy-weight process (such as a child) is
  684.  * being run down or destroyed.  As with the child-initialisation function,
  685.  * any information that needs to be recorded must be in static cells, since
  686.  * there's no configuration record.
  687.  *
  688.  * There is no return value.
  689.  */
  690.  
  691. /*
  692.  * All our process-death routine does is add its trace to the log.
  693.  */
  694. static void example_child_exit(server_rec *s, pool *p)
  695. {
  696.  
  697.     char *note;
  698.     char *sname = s->server_hostname;
  699.  
  700.     /*
  701.      * The arbitrary text we add to our trace entry indicates for which server
  702.      * we're being called.
  703.      */
  704.     sname = (sname != NULL) ? sname : "";
  705.     note = ap_pstrcat(p, "example_child_exit(", sname, ")", NULL);
  706.     trace_add(s, NULL, NULL, note);
  707. }
  708.  
  709. /*
  710.  * This function gets called to create up a per-directory configuration
  711.  * record.  This will be called for the "default" server environment, and for
  712.  * each directory for which the parser finds any of our directives applicable.
  713.  * If a directory doesn't have any of our directives involved (i.e., they
  714.  * aren't in the .htaccess file, or a <Location>, <Directory>, or related
  715.  * block), this routine will *not* be called - the configuration for the
  716.  * closest ancestor is used.
  717.  *
  718.  * The return value is a pointer to the created module-specific
  719.  * structure.
  720.  */
  721. static void *example_create_dir_config(pool *p, char *dirspec)
  722. {
  723.  
  724.     excfg *cfg;
  725.     char *dname = dirspec;
  726.  
  727.     /*
  728.      * Allocate the space for our record from the pool supplied.
  729.      */
  730.     cfg = (excfg *) ap_pcalloc(p, sizeof(excfg));
  731.     /*
  732.      * Now fill in the defaults.  If there are any `parent' configuration
  733.      * records, they'll get merged as part of a separate callback.
  734.      */
  735.     cfg->local = 0;
  736.     cfg->congenital = 0;
  737.     cfg->cmode = CONFIG_MODE_DIRECTORY;
  738.     /*
  739.      * Finally, add our trace to the callback list.
  740.      */
  741.     dname = (dname != NULL) ? dname : "";
  742.     cfg->loc = ap_pstrcat(p, "DIR(", dname, ")", NULL);
  743.     trace_add(NULL, NULL, cfg, "example_create_dir_config()");
  744.     return (void *) cfg;
  745. }
  746.  
  747. /*
  748.  * This function gets called to merge two per-directory configuration
  749.  * records.  This is typically done to cope with things like .htaccess files
  750.  * or <Location> directives for directories that are beneath one for which a
  751.  * configuration record was already created.  The routine has the
  752.  * responsibility of creating a new record and merging the contents of the
  753.  * other two into it appropriately.  If the module doesn't declare a merge
  754.  * routine, the record for the closest ancestor location (that has one) is
  755.  * used exclusively.
  756.  *
  757.  * The routine MUST NOT modify any of its arguments!
  758.  *
  759.  * The return value is a pointer to the created module-specific structure
  760.  * containing the merged values.
  761.  */
  762. static void *example_merge_dir_config(pool *p, void *parent_conf,
  763.                                       void *newloc_conf)
  764. {
  765.  
  766.     excfg *merged_config = (excfg *) ap_pcalloc(p, sizeof(excfg));
  767.     excfg *pconf = (excfg *) parent_conf;
  768.     excfg *nconf = (excfg *) newloc_conf;
  769.     char *note;
  770.  
  771.     /*
  772.      * Some things get copied directly from the more-specific record, rather
  773.      * than getting merged.
  774.      */
  775.     merged_config->local = nconf->local;
  776.     merged_config->loc = ap_pstrdup(p, nconf->loc);
  777.     /*
  778.      * Others, like the setting of the `congenital' flag, get ORed in.  The
  779.      * setting of that particular flag, for instance, is TRUE if it was ever
  780.      * true anywhere in the upstream configuration.
  781.      */
  782.     merged_config->congenital = (pconf->congenital | pconf->local);
  783.     /*
  784.      * If we're merging records for two different types of environment (server
  785.      * and directory), mark the new record appropriately.  Otherwise, inherit
  786.      * the current value.
  787.      */
  788.     merged_config->cmode =
  789.         (pconf->cmode == nconf->cmode) ? pconf->cmode : CONFIG_MODE_COMBO;
  790.     /*
  791.      * Now just record our being called in the trace list.  Include the
  792.      * locations we were asked to merge.
  793.      */
  794.     note = ap_pstrcat(p, "example_merge_dir_config(\"", pconf->loc, "\",\"",
  795.                    nconf->loc, "\")", NULL);
  796.     trace_add(NULL, NULL, merged_config, note);
  797.     return (void *) merged_config;
  798. }
  799.  
  800. /*
  801.  * This function gets called to create a per-server configuration
  802.  * record.  It will always be called for the "default" server.
  803.  *
  804.  * The return value is a pointer to the created module-specific
  805.  * structure.
  806.  */
  807. static void *example_create_server_config(pool *p, server_rec *s)
  808. {
  809.  
  810.     excfg *cfg;
  811.     char *sname = s->server_hostname;
  812.  
  813.     /*
  814.      * As with the example_create_dir_config() reoutine, we allocate and fill
  815.      * in an empty record.
  816.      */
  817.     cfg = (excfg *) ap_pcalloc(p, sizeof(excfg));
  818.     cfg->local = 0;
  819.     cfg->congenital = 0;
  820.     cfg->cmode = CONFIG_MODE_SERVER;
  821.     /*
  822.      * Note that we were called in the trace list.
  823.      */
  824.     sname = (sname != NULL) ? sname : "";
  825.     cfg->loc = ap_pstrcat(p, "SVR(", sname, ")", NULL);
  826.     trace_add(s, NULL, cfg, "example_create_server_config()");
  827.     return (void *) cfg;
  828. }
  829.  
  830. /*
  831.  * This function gets called to merge two per-server configuration
  832.  * records.  This is typically done to cope with things like virtual hosts and
  833.  * the default server configuration  The routine has the responsibility of
  834.  * creating a new record and merging the contents of the other two into it
  835.  * appropriately.  If the module doesn't declare a merge routine, the more
  836.  * specific existing record is used exclusively.
  837.  *
  838.  * The routine MUST NOT modify any of its arguments!
  839.  *
  840.  * The return value is a pointer to the created module-specific structure
  841.  * containing the merged values.
  842.  */
  843. static void *example_merge_server_config(pool *p, void *server1_conf,
  844.                                          void *server2_conf)
  845. {
  846.  
  847.     excfg *merged_config = (excfg *) ap_pcalloc(p, sizeof(excfg));
  848.     excfg *s1conf = (excfg *) server1_conf;
  849.     excfg *s2conf = (excfg *) server2_conf;
  850.     char *note;
  851.  
  852.     /*
  853.      * Our inheritance rules are our own, and part of our module's semantics.
  854.      * Basically, just note whence we came.
  855.      */
  856.     merged_config->cmode =
  857.         (s1conf->cmode == s2conf->cmode) ? s1conf->cmode : CONFIG_MODE_COMBO;
  858.     merged_config->local = s2conf->local;
  859.     merged_config->congenital = (s1conf->congenital | s1conf->local);
  860.     merged_config->loc = ap_pstrdup(p, s2conf->loc);
  861.     /*
  862.      * Trace our call, including what we were asked to merge.
  863.      */
  864.     note = ap_pstrcat(p, "example_merge_server_config(\"", s1conf->loc, "\",\"",
  865.                    s2conf->loc, "\")", NULL);
  866.     trace_add(NULL, NULL, merged_config, note);
  867.     return (void *) merged_config;
  868. }
  869.  
  870. /*
  871.  * This routine is called after the request has been read but before any other
  872.  * phases have been processed.  This allows us to make decisions based upon
  873.  * the input header fields.
  874.  *
  875.  * The return value is OK, DECLINED, or HTTP_mumble.  If we return OK, no
  876.  * further modules are called for this phase.
  877.  */
  878. static int example_post_read_request(request_rec *r)
  879. {
  880.  
  881.     excfg *cfg;
  882.  
  883.     cfg = our_dconfig(r);
  884.     /*
  885.      * We don't actually *do* anything here, except note the fact that we were
  886.      * called.
  887.      */
  888.     trace_add(r->server, r, cfg, "example_post_read_request()");
  889.     return DECLINED;
  890. }
  891.  
  892. /*
  893.  * This routine gives our module an opportunity to translate the URI into an
  894.  * actual filename.  If we don't do anything special, the server's default
  895.  * rules (Alias directives and the like) will continue to be followed.
  896.  *
  897.  * The return value is OK, DECLINED, or HTTP_mumble.  If we return OK, no
  898.  * further modules are called for this phase.
  899.  */
  900. static int example_translate_handler(request_rec *r)
  901. {
  902.  
  903.     excfg *cfg;
  904.  
  905.     cfg = our_dconfig(r);
  906.     /*
  907.      * We don't actually *do* anything here, except note the fact that we were
  908.      * called.
  909.      */
  910.     trace_add(r->server, r, cfg, "example_translate_handler()");
  911.     return DECLINED;
  912. }
  913.  
  914. /*
  915.  * This routine is called to check the authentication information sent with
  916.  * the request (such as looking up the user in a database and verifying that
  917.  * the [encrypted] password sent matches the one in the database).
  918.  *
  919.  * The return value is OK, DECLINED, or some HTTP_mumble error (typically
  920.  * HTTP_UNAUTHORIZED).  If we return OK, no other modules are given a chance
  921.  * at the request during this phase.
  922.  */
  923. static int example_check_user_id(request_rec *r)
  924. {
  925.  
  926.     excfg *cfg;
  927.  
  928.     cfg = our_dconfig(r);
  929.     /*
  930.      * Don't do anything except log the call.
  931.      */
  932.     trace_add(r->server, r, cfg, "example_check_user_id()");
  933.     return DECLINED;
  934. }
  935.  
  936. /*
  937.  * This routine is called to check to see if the resource being requested
  938.  * requires authorisation.
  939.  *
  940.  * The return value is OK, DECLINED, or HTTP_mumble.  If we return OK, no
  941.  * other modules are called during this phase.
  942.  *
  943.  * If *all* modules return DECLINED, the request is aborted with a server
  944.  * error.
  945.  */
  946. static int example_auth_checker(request_rec *r)
  947. {
  948.  
  949.     excfg *cfg;
  950.  
  951.     cfg = our_dconfig(r);
  952.     /*
  953.      * Log the call and return OK, or access will be denied (even though we
  954.      * didn't actually do anything).
  955.      */
  956.     trace_add(r->server, r, cfg, "example_auth_checker()");
  957.     return DECLINED;
  958. }
  959.  
  960. /*
  961.  * This routine is called to check for any module-specific restrictions placed
  962.  * upon the requested resource.  (See the mod_access module for an example.)
  963.  *
  964.  * The return value is OK, DECLINED, or HTTP_mumble.  All modules with an
  965.  * handler for this phase are called regardless of whether their predecessors
  966.  * return OK or DECLINED.  The first one to return any other status, however,
  967.  * will abort the sequence (and the request) as usual.
  968.  */
  969. static int example_access_checker(request_rec *r)
  970. {
  971.  
  972.     excfg *cfg;
  973.  
  974.     cfg = our_dconfig(r);
  975.     trace_add(r->server, r, cfg, "example_access_checker()");
  976.     return DECLINED;
  977. }
  978.  
  979. /*
  980.  * This routine is called to determine and/or set the various document type
  981.  * information bits, like Content-type (via r->content_type), language, et
  982.  * cetera.
  983.  *
  984.  * The return value is OK, DECLINED, or HTTP_mumble.  If we return OK, no
  985.  * further modules are given a chance at the request for this phase.
  986.  */
  987. static int example_type_checker(request_rec *r)
  988. {
  989.  
  990.     excfg *cfg;
  991.  
  992.     cfg = our_dconfig(r);
  993.     /*
  994.      * Log the call, but don't do anything else - and report truthfully that
  995.      * we didn't do anything.
  996.      */
  997.     trace_add(r->server, r, cfg, "example_type_checker()");
  998.     return DECLINED;
  999. }
  1000.  
  1001. /*
  1002.  * This routine is called to perform any module-specific fixing of header
  1003.  * fields, et cetera.  It is invoked just before any content-handler.
  1004.  *
  1005.  * The return value is OK, DECLINED, or HTTP_mumble.  If we return OK, the
  1006.  * server will still call any remaining modules with an handler for this
  1007.  * phase.
  1008.  */
  1009. static int example_fixer_upper(request_rec *r)
  1010. {
  1011.  
  1012.     excfg *cfg;
  1013.  
  1014.     cfg = our_dconfig(r);
  1015.     /*
  1016.      * Log the call and exit.
  1017.      */
  1018.     trace_add(r->server, r, cfg, "example_fixer_upper()");
  1019.     return OK;
  1020. }
  1021.  
  1022. /*
  1023.  * This routine is called to perform any module-specific logging activities
  1024.  * over and above the normal server things.
  1025.  *
  1026.  * The return value is OK, DECLINED, or HTTP_mumble.  If we return OK, any
  1027.  * remaining modules with an handler for this phase will still be called.
  1028.  */
  1029. static int example_logger(request_rec *r)
  1030. {
  1031.  
  1032.     excfg *cfg;
  1033.  
  1034.     cfg = our_dconfig(r);
  1035.     trace_add(r->server, r, cfg, "example_logger()");
  1036.     return DECLINED;
  1037. }
  1038.  
  1039. /*
  1040.  * This routine is called to give the module a chance to look at the request
  1041.  * headers and take any appropriate specific actions early in the processing
  1042.  * sequence.
  1043.  *
  1044.  * The return value is OK, DECLINED, or HTTP_mumble.  If we return OK, any
  1045.  * remaining modules with handlers for this phase will still be called.
  1046.  */
  1047. static int example_header_parser(request_rec *r)
  1048. {
  1049.  
  1050.     excfg *cfg;
  1051.  
  1052.     cfg = our_dconfig(r);
  1053.     trace_add(r->server, r, cfg, "example_header_parser()");
  1054.     return DECLINED;
  1055. }
  1056.  
  1057. /*--------------------------------------------------------------------------*/
  1058. /*                                                                          */
  1059. /* All of the routines have been declared now.  Here's the list of          */
  1060. /* directives specific to our module, and information about where they      */
  1061. /* may appear and how the command parser should pass them to us for         */
  1062. /* processing.  Note that care must be taken to ensure that there are NO    */
  1063. /* collisions of directive names between modules.                           */
  1064. /*                                                                          */
  1065. /*--------------------------------------------------------------------------*/
  1066. /* 
  1067.  * List of directives specific to our module.
  1068.  */
  1069. static const command_rec example_cmds[] =
  1070. {
  1071.     {
  1072.         "Example",              /* directive name */
  1073.         cmd_example,            /* config action routine */
  1074.         NULL,                   /* argument to include in call */
  1075.         OR_OPTIONS,             /* where available */
  1076.         NO_ARGS,                /* arguments */
  1077.         "Example directive - no arguments"
  1078.                                 /* directive description */
  1079.     },
  1080.     {NULL}
  1081. };
  1082.  
  1083. /*--------------------------------------------------------------------------*/
  1084. /*                                                                          */
  1085. /* Now the list of content handlers available from this module.             */
  1086. /*                                                                          */
  1087. /*--------------------------------------------------------------------------*/
  1088. /* 
  1089.  * List of content handlers our module supplies.  Each handler is defined by
  1090.  * two parts: a name by which it can be referenced (such as by
  1091.  * {Add,Set}Handler), and the actual routine name.  The list is terminated by
  1092.  * a NULL block, since it can be of variable length.
  1093.  *
  1094.  * Note that content-handlers are invoked on a most-specific to least-specific
  1095.  * basis; that is, a handler that is declared for "text/plain" will be
  1096.  * invoked before one that was declared for "text / *".  Note also that
  1097.  * if a content-handler returns anything except DECLINED, no other
  1098.  * content-handlers will be called.
  1099.  */
  1100. static const handler_rec example_handlers[] =
  1101. {
  1102.     {"example-handler", example_handler},
  1103.     {NULL}
  1104. };
  1105.  
  1106. /*--------------------------------------------------------------------------*/
  1107. /*                                                                          */
  1108. /* Finally, the list of callback routines and data structures that          */
  1109. /* provide the hooks into our module from the other parts of the server.    */
  1110. /*                                                                          */
  1111. /*--------------------------------------------------------------------------*/
  1112. /* 
  1113.  * Module definition for configuration.  If a particular callback is not
  1114.  * needed, replace its routine name below with the word NULL.
  1115.  *
  1116.  * The number in brackets indicates the order in which the routine is called
  1117.  * during request processing.  Note that not all routines are necessarily
  1118.  * called (such as if a resource doesn't have access restrictions).
  1119.  */
  1120. module example_module =
  1121. {
  1122.     STANDARD_MODULE_STUFF,
  1123.     example_init,               /* module initializer */
  1124.     example_create_dir_config,  /* per-directory config creator */
  1125.     example_merge_dir_config,   /* dir config merger */
  1126.     example_create_server_config,       /* server config creator */
  1127.     example_merge_server_config,        /* server config merger */
  1128.     example_cmds,               /* command table */
  1129.     example_handlers,           /* [7] list of handlers */
  1130.     example_translate_handler,  /* [2] filename-to-URI translation */
  1131.     example_check_user_id,      /* [5] check/validate user_id */
  1132.     example_auth_checker,       /* [6] check user_id is valid *here* */
  1133.     example_access_checker,     /* [4] check access by host address */
  1134.     example_type_checker,       /* [7] MIME type checker/setter */
  1135.     example_fixer_upper,        /* [8] fixups */
  1136.     example_logger,             /* [10] logger */
  1137. #if MODULE_MAGIC_NUMBER >= 19970103
  1138.     example_header_parser,      /* [3] header parser */
  1139. #endif
  1140. #if MODULE_MAGIC_NUMBER >= 19970719
  1141.     example_child_init,         /* process initializer */
  1142. #endif
  1143. #if MODULE_MAGIC_NUMBER >= 19970728
  1144.     example_child_exit,         /* process exit/cleanup */
  1145. #endif
  1146. #if MODULE_MAGIC_NUMBER >= 19970902
  1147.     example_post_read_request   /* [1] post read_request handling */
  1148. #endif
  1149. };
  1150.