httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stodd...@apache.org
Subject cvs commit: httpd-2.0/modules/metadata mod_headers.c
Date Sat, 19 May 2001 20:12:06 GMT
stoddard    01/05/19 13:12:06

  Modified:    .        CHANGES
               modules/metadata mod_headers.c
  Log:
  Reimplement mod_headers as an output filter. mod_headers can now
  add custom headers to inbound requests using the HeaderIn directive
  and to responses using the HeaderOut directive. The Header
  directive has been deprecated in favor of the HeaderOut directive.
  
  Submitted by: Graham Leggett
  Reviewed by: Bill Stoddard
  
  Revision  Changes    Path
  1.205     +5 -0      httpd-2.0/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/CHANGES,v
  retrieving revision 1.204
  retrieving revision 1.205
  diff -u -r1.204 -r1.205
  --- CHANGES	2001/05/18 11:42:06	1.204
  +++ CHANGES	2001/05/19 20:12:02	1.205
  @@ -1,4 +1,9 @@
   Changes with Apache 2.0.18-dev
  +  *) Reimplement mod_headers as an output filter. mod_headers can now
  +     add custom headers to inbound requests using the HeaderIn directive
  +     and to responses using the HeaderOut directive. The Header
  +     directive has been deprecated in favor of the HeaderOut directive.
  +     [Graham Leggett]
   
     *) Fix command-line processing so that if a bad argument is specified
        Apache will exit.  [Jeff Trawick]
  
  
  
  1.22      +114 -34   httpd-2.0/modules/metadata/mod_headers.c
  
  Index: mod_headers.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/metadata/mod_headers.c,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- mod_headers.c	2001/02/18 02:58:53	1.21
  +++ mod_headers.c	2001/05/19 20:12:05	1.22
  @@ -60,12 +60,13 @@
    * mod_headers.c: Add/append/remove HTTP response headers
    *     Written by Paul Sutton, paul@ukweb.com, 1 Oct 1996
    *
  - * New directive, Header, can be used to add/replace/remove HTTP headers.
  + * HeaderIn and HeaderOut can be used to add/replace/remove HTTP headers.
    * Valid in both per-server and per-dir configurations.
    *
    * Syntax is:
    *
  - *   Header action header value
  + *   HeaderIn action header value
  + *   HeaderOut action header value
    *
    * Where action is one of:
    *     set    - set this header, replacing any old value
  @@ -77,8 +78,8 @@
    * Where action is unset, the third argument (value) should not be given.
    * The header name can include the colon, or not.
    *
  - * The Header directive can only be used where allowed by the FileInfo 
  - * override.
  + * The Header(In|Out) directive can only be used where allowed by the
  + * FileInfo override.
    *
    * When the request is processed, the header directives are processed in
    * this order: firstly, the main server, then the virtual server handling
  @@ -89,21 +90,22 @@
    * the following two directives have different effect if applied in
    * the reverse order:
    *
  - *   Header append Author "John P. Doe"
  - *   Header unset Author
  + *   HeaderOut append Author "John P. Doe"
  + *   HeaderOut unset Author
    *
    * Examples:
    *
    *  To set the "Author" header, use
  - *     Header add Author "John P. Doe"
  + *     HeaderOut add Author "John P. Doe"
    *
    *  To remove a header:
  - *     Header unset Author
  + *     HeaderOut unset Author
    *
    */
   
   #include "apr.h"
   #include "apr_strings.h"
  +#include "apr_buckets.h"
   
   #define APR_WANT_STRFUNC
   #include "apr_want.h"
  @@ -111,8 +113,9 @@
   #include "httpd.h"
   #include "http_config.h"
   #include "http_request.h"
  +#include "http_log.h"
  +#include "util_filter.h"
   
  -
   typedef enum {
       hdr_add = 'a',              /* add header (could mean multiple hdrs) */
       hdr_set = 's',              /* set (replace old value) */
  @@ -120,6 +123,11 @@
       hdr_unset = 'u'             /* unset header */
   } hdr_actions;
   
  +typedef enum {
  +    hdr_in = 0,                 /* HeaderIn */
  +    hdr_out = 1,                /* HeaderOut */
  +} hdr_inout;
  +
   typedef struct {
       hdr_actions action;
       char *header;
  @@ -131,7 +139,8 @@
    * a per-dir and per-server config
    */
   typedef struct {
  -    apr_array_header_t *headers;
  +    apr_array_header_t *fixup_in;
  +    apr_array_header_t *fixup_out;
   } headers_conf;
   
   module AP_MODULE_DECLARE_DATA headers_module;
  @@ -140,7 +149,8 @@
   {
       headers_conf *conf = apr_pcalloc(p, sizeof(*conf));
   
  -    conf->headers = apr_array_make(p, 2, sizeof(header_entry));
  +    conf->fixup_in = apr_array_make(p, 2, sizeof(header_entry));
  +    conf->fixup_out = apr_array_make(p, 2, sizeof(header_entry));
   
       return conf;
   }
  @@ -156,13 +166,15 @@
       headers_conf *base = basev;
       headers_conf *overrides = overridesv;
   
  -    newconf->headers = apr_array_append(p, base->headers, overrides->headers);
  +    newconf->fixup_in = apr_array_append(p, base->fixup_in, overrides->fixup_in);
  +    newconf->fixup_out = apr_array_append(p, base->fixup_out, overrides->fixup_out);
   
       return newconf;
   }
   
   
  -static const char *header_cmd(cmd_parms *cmd, void *indirconf,
  +/* handle HeaderIn and HeaderOut directive */
  +static const char *header_inout_cmd(hdr_inout inout, cmd_parms *cmd, void *indirconf,
                                 const char *action, const char *inhdr,
                                 const char *value)
   {
  @@ -175,10 +187,10 @@
       char *colon;
   
       if (cmd->path) {
  -        new = (header_entry *) apr_array_push(dirconf->headers);
  +        new = (header_entry *) apr_array_push((hdr_in == inout) ? dirconf->fixup_in
: dirconf->fixup_out);
       }
       else {
  -        new = (header_entry *) apr_array_push(serverconf->headers);
  +        new = (header_entry *) apr_array_push((hdr_in == inout) ? serverconf->fixup_in
: serverconf->fixup_out);
       }
   
       if (!strcasecmp(action, "set"))
  @@ -194,10 +206,10 @@
   
       if (new->action == hdr_unset) {
           if (value)
  -            return "Header unset takes two arguments";
  +            return "Header(In|Out) unset takes two arguments";
       }
       else if (!value)
  -        return "Header requires three arguments";
  +        return "Header(In|Out) requires three arguments";
   
       if ((colon = strchr(hdr, ':')))
           *colon = '\0';
  @@ -208,54 +220,122 @@
       return NULL;
   }
   
  -static const command_rec headers_cmds[] =
  +/* handle deprecated Header directive */
  +static const char *header_cmd(cmd_parms *cmd, void *indirconf,
  +                              const char *action, const char *inhdr,
  +                              const char *value)
   {
  -    AP_INIT_TAKE23("Header", header_cmd, NULL, OR_FILEINFO,
  -                   "an action, header and value"),
  -    {NULL}
  -};
  +    return "The Header directive has been deprecated. Use HeaderOut instead.";
  +}
   
  -static void do_headers_fixup(request_rec *r, apr_array_header_t *headers)
  +/* handle HeaderOut directive */
  +static const char *header_out_cmd(cmd_parms *cmd, void *indirconf,
  +                              const char *action, const char *inhdr,
  +                              const char *value)
  +{
  +    return header_inout_cmd(hdr_out, cmd, indirconf, action, inhdr, value);
  +}
  +
  +/* handle HeaderIn directive */
  +static const char *header_in_cmd(cmd_parms *cmd, void *indirconf,
  +                              const char *action, const char *inhdr,
  +                              const char *value)
  +{
  +    return header_inout_cmd(hdr_in, cmd, indirconf, action, inhdr, value);
  +}
  +
  +
  +static void do_headers_fixup(apr_table_t *headers,
  +                             apr_array_header_t *fixup)
   {
       int i;
   
  -    for (i = 0; i < headers->nelts; ++i) {
  -        header_entry *hdr = &((header_entry *) (headers->elts))[i];
  +    for (i = 0; i < fixup->nelts; ++i) {
  +        header_entry *hdr = &((header_entry *) (fixup->elts))[i];
           switch (hdr->action) {
           case hdr_add:
  -            apr_table_addn(r->headers_out, hdr->header, hdr->value);
  +            apr_table_addn(headers, hdr->header, hdr->value);
               break;
           case hdr_append:
  -            apr_table_mergen(r->headers_out, hdr->header, hdr->value);
  +            apr_table_mergen(headers, hdr->header, hdr->value);
               break;
           case hdr_set:
  -            apr_table_setn(r->headers_out, hdr->header, hdr->value);
  +            apr_table_setn(headers, hdr->header, hdr->value);
               break;
           case hdr_unset:
  -            apr_table_unset(r->headers_out, hdr->header);
  +            apr_table_unset(headers, hdr->header);
               break;
           }
       }
  +}
  +
  +static void ap_headers_insert_output_filter(request_rec *r)
  +{
  +    headers_conf *serverconf = ap_get_module_config(r->server->module_config,
  +                                                    &headers_module);
  +    headers_conf *dirconf = ap_get_module_config(r->per_dir_config,
  +                                                 &headers_module);
  +
  +    if (serverconf->fixup_out->nelts || dirconf->fixup_out->nelts) {
  +	ap_add_output_filter("FIXUP_HEADERS_OUT", NULL, r, r->connection);
  +    }
  +}
  +
  +static apr_status_t ap_headers_output_filter(ap_filter_t *f,
  +                                             apr_bucket_brigade *in)
  +{
  +    headers_conf *serverconf = ap_get_module_config(f->r->server->module_config,
  +                                                    &headers_module);
  +    headers_conf *dirconf = ap_get_module_config(f->r->per_dir_config,
  +                                                 &headers_module);
   
  +    ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, f->r->server,
  +		 "headers: ap_headers_output_filter()");
  +
  +    /* do the fixup */
  +    do_headers_fixup(f->r->headers_out, serverconf->fixup_out);
  +    do_headers_fixup(f->r->headers_out, dirconf->fixup_out);
  +
  +    /* remove ourselves from the filter chain */
  +    ap_remove_output_filter(f);
  +
  +    /* send the data up the stack */
  +    return ap_pass_brigade(f->next,in);
   }
   
  -static int fixup_headers(request_rec *r)
  +static apr_status_t ap_headers_fixup(request_rec *r)
   {
       headers_conf *serverconf = ap_get_module_config(r->server->module_config,
                                                       &headers_module);
       headers_conf *dirconf = ap_get_module_config(r->per_dir_config,
                                                    &headers_module);
   
  -    do_headers_fixup(r, serverconf->headers);
  -    do_headers_fixup(r, dirconf->headers);
  +    /* do the fixup */
  +    if (serverconf->fixup_in->nelts || dirconf->fixup_in->nelts) {
  +        do_headers_fixup(r->headers_in, serverconf->fixup_in);
  +        do_headers_fixup(r->headers_in, dirconf->fixup_in);
  +    }
   
       return DECLINED;
   }
  +                                        
  +static const command_rec headers_cmds[] =
  +{
  +    AP_INIT_TAKE23("Header", header_cmd, NULL, OR_FILEINFO,
  +                   "deprecated, use HeaderOut instead"),
  +    AP_INIT_TAKE23("HeaderIn", header_in_cmd, NULL, OR_FILEINFO,
  +                   "an action, header and value"),
  +    AP_INIT_TAKE23("HeaderOut", header_out_cmd, NULL, OR_FILEINFO,
  +                   "an action, header and value"),
  +    {NULL}
  +};
   
   static void register_hooks(apr_pool_t *p)
   {
  -    ap_hook_fixups(fixup_headers, NULL, NULL, APR_HOOK_MIDDLE);
  -} 
  +    ap_hook_insert_filter(ap_headers_insert_output_filter, NULL, NULL, APR_HOOK_LAST);
  +    ap_hook_fixups(ap_headers_fixup, NULL, NULL, APR_HOOK_LAST);
  +    ap_register_output_filter("FIXUP_HEADERS_OUT", ap_headers_output_filter, AP_FTYPE_CONTENT);
  +}
   
   module AP_MODULE_DECLARE_DATA headers_module =
   {
  
  
  

Mime
View raw message