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

  1. /* ====================================================================
  2.  * Copyright (c) 1996-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.  * mod_headers.c: Add/append/remove HTTP response headers
  60.  *     Written by Paul Sutton, paul@ukweb.com, 1 Oct 1996
  61.  *
  62.  * New directive, Header, can be used to add/replace/remove HTTP headers.
  63.  * Valid in both per-server and per-dir configurations.
  64.  *
  65.  * Syntax is:
  66.  *
  67.  *   Header action header value
  68.  *
  69.  * Where action is one of:
  70.  *     set    - set this header, replacing any old value
  71.  *     add    - add this header, possible resulting in two or more
  72.  *              headers with the same name
  73.  *     append - append this text onto any existing header of this same
  74.  *     unset  - remove this header
  75.  *
  76.  * Where action is unset, the third argument (value) should not be given.
  77.  * The header name can include the colon, or not.
  78.  *
  79.  * The Header directive can only be used where allowed by the FileInfo 
  80.  * override.
  81.  *
  82.  * When the request is processed, the header directives are processed in
  83.  * this order: firstly, the main server, then the virtual server handling
  84.  * this request (if any), then any <Directory> sections (working downwards 
  85.  * from the root dir), then an <Location> sections (working down from 
  86.  * shortest URL component), the any <File> sections. This order is
  87.  * important if any 'set' or 'unset' actions are used. For example,
  88.  * the following two directives have different effect if applied in
  89.  * the reverse order:
  90.  *
  91.  *   Header append Author "John P. Doe"
  92.  *   Header unset Author
  93.  *
  94.  * Examples:
  95.  *
  96.  *  To set the "Author" header, use
  97.  *     Header add Author "John P. Doe"
  98.  *
  99.  *  To remove a header:
  100.  *     Header unset Author
  101.  *
  102.  */
  103.  
  104. #include "httpd.h"
  105. #include "http_config.h"
  106.  
  107. typedef enum {
  108.     hdr_add = 'a',              /* add header (could mean multiple hdrs) */
  109.     hdr_set = 's',              /* set (replace old value) */
  110.     hdr_append = 'm',           /* append (merge into any old value) */
  111.     hdr_unset = 'u'             /* unset header */
  112. } hdr_actions;
  113.  
  114. typedef struct {
  115.     hdr_actions action;
  116.     char *header;
  117.     char *value;
  118. } header_entry;
  119.  
  120. /*
  121.  * headers_conf is our per-module configuration. This is used as both
  122.  * a per-dir and per-server config
  123.  */
  124. typedef struct {
  125.     array_header *headers;
  126. } headers_conf;
  127.  
  128. module MODULE_VAR_EXPORT headers_module;
  129.  
  130. static void *create_headers_config(pool *p, server_rec *s)
  131. {
  132.     headers_conf *a =
  133.     (headers_conf *) ap_pcalloc(p, sizeof(headers_conf));
  134.  
  135.     a->headers = ap_make_array(p, 2, sizeof(header_entry));
  136.     return a;
  137. }
  138.  
  139. static void *create_headers_dir_config(pool *p, char *d)
  140. {
  141.     return (headers_conf *) create_headers_config(p, NULL);
  142. }
  143.  
  144. static void *merge_headers_config(pool *p, void *basev, void *overridesv)
  145. {
  146.     headers_conf *a =
  147.     (headers_conf *) ap_pcalloc(p, sizeof(headers_conf));
  148.     headers_conf *base = (headers_conf *) basev, *overrides = (headers_conf *) overridesv;
  149.  
  150.     a->headers = ap_append_arrays(p, base->headers, overrides->headers);
  151.  
  152.     return a;
  153. }
  154.  
  155.  
  156. static const char *header_cmd(cmd_parms *cmd, headers_conf * dirconf, char *action, char *hdr, char *value)
  157. {
  158.     header_entry *new;
  159.     server_rec *s = cmd->server;
  160.     headers_conf *serverconf =
  161.     (headers_conf *) ap_get_module_config(s->module_config, &headers_module);
  162.     char *colon;
  163.  
  164.     if (cmd->path) {
  165.         new = (header_entry *) ap_push_array(dirconf->headers);
  166.     }
  167.     else {
  168.         new = (header_entry *) ap_push_array(serverconf->headers);
  169.     }
  170.  
  171.     if (!strcasecmp(action, "set"))
  172.         new->action = hdr_set;
  173.     else if (!strcasecmp(action, "add"))
  174.         new->action = hdr_add;
  175.     else if (!strcasecmp(action, "append"))
  176.         new->action = hdr_append;
  177.     else if (!strcasecmp(action, "unset"))
  178.         new->action = hdr_unset;
  179.     else
  180.         return "first argument must be add, set, append or unset.";
  181.  
  182.     if (new->action == hdr_unset) {
  183.         if (value)
  184.             return "Header unset takes two arguments";
  185.     }
  186.     else if (!value)
  187.         return "Header requires three arguments";
  188.  
  189.     if ((colon = strchr(hdr, ':')))
  190.         *colon = '\0';
  191.  
  192.     new->header = hdr;
  193.     new->value = value;
  194.  
  195.     return NULL;
  196. }
  197.  
  198. static const command_rec headers_cmds[] =
  199. {
  200.     {"Header", header_cmd, NULL, OR_FILEINFO, TAKE23,
  201.      "an action, header and value"},
  202.     {NULL}
  203. };
  204.  
  205. static void do_headers_fixup(request_rec *r, array_header *headers)
  206. {
  207.     int i;
  208.  
  209.     for (i = 0; i < headers->nelts; ++i) {
  210.         header_entry *hdr = &((header_entry *) (headers->elts))[i];
  211.         switch (hdr->action) {
  212.         case hdr_add:
  213.             ap_table_addn(r->headers_out, hdr->header, hdr->value);
  214.             break;
  215.         case hdr_append:
  216.             ap_table_mergen(r->headers_out, hdr->header, hdr->value);
  217.             break;
  218.         case hdr_set:
  219.             ap_table_setn(r->headers_out, hdr->header, hdr->value);
  220.             break;
  221.         case hdr_unset:
  222.             ap_table_unset(r->headers_out, hdr->header);
  223.             break;
  224.         }
  225.     }
  226.  
  227. }
  228.  
  229. static int fixup_headers(request_rec *r)
  230. {
  231.     void *sconf = r->server->module_config;
  232.     headers_conf *serverconf =
  233.     (headers_conf *) ap_get_module_config(sconf, &headers_module);
  234.     void *dconf = r->per_dir_config;
  235.     headers_conf *dirconf =
  236.     (headers_conf *) ap_get_module_config(dconf, &headers_module);
  237.  
  238.     do_headers_fixup(r, serverconf->headers);
  239.     do_headers_fixup(r, dirconf->headers);
  240.  
  241.     return DECLINED;
  242. }
  243.  
  244. module MODULE_VAR_EXPORT headers_module =
  245. {
  246.     STANDARD_MODULE_STUFF,
  247.     NULL,                       /* initializer */
  248.     create_headers_dir_config,  /* dir config creater */
  249.     merge_headers_config,       /* dir merger --- default is to override */
  250.     create_headers_config,      /* server config */
  251.     merge_headers_config,       /* merge server configs */
  252.     headers_cmds,               /* command table */
  253.     NULL,                       /* handlers */
  254.     NULL,                       /* filename translation */
  255.     NULL,                       /* check_user_id */
  256.     NULL,                       /* check auth */
  257.     NULL,                       /* check access */
  258.     NULL,                       /* type_checker */
  259.     fixup_headers,              /* fixups */
  260.     NULL,                       /* logger */
  261.     NULL,                       /* header parser */
  262.     NULL,                       /* child_init */
  263.     NULL,                       /* child_exit */
  264.     NULL                        /* post read-request */
  265. };
  266.