httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From c...@apache.org
Subject cvs commit: httpd-2.0/server core.c
Date Fri, 11 Jan 2002 18:55:28 GMT
coar        02/01/11 10:55:28

  Modified:    .        CHANGES
               include  ap_mmn.h http_core.h
               modules/http http_protocol.c
               server   core.c
  Log:
  	Bring forward the FileETag directive enhancement from 1.3.23-dev.
  	(Passes all 61 of the apache/etags.t test.)  Bump MMN due to
  	change to core_dir_config structure (new fields at end).
  
  Revision  Changes    Path
  1.517     +5 -0      httpd-2.0/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/CHANGES,v
  retrieving revision 1.516
  retrieving revision 1.517
  diff -u -u -r1.516 -r1.517
  --- CHANGES	11 Jan 2002 13:38:28 -0000	1.516
  +++ CHANGES	11 Jan 2002 18:55:27 -0000	1.517
  @@ -1,5 +1,10 @@
   Changes with Apache 2.0.31-dev
   
  +  *) Add FileETag directive to allow configurable control of what
  +     data are used to form ETag values for file-based URIs.  MMN
  +     bumped to 20020111 because of fields added to the end of
  +     the core_dir_config structure.  [Ken Coar]
  +
     *) Fix a segfault in mod_rewrite's logging code caused by passing the
        wrong config to ap_get_remote_host().  [Jeff Trawick]
   
  
  
  
  1.27      +2 -1      httpd-2.0/include/ap_mmn.h
  
  Index: ap_mmn.h
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/include/ap_mmn.h,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -u -r1.26 -r1.27
  --- ap_mmn.h	10 Jan 2002 05:16:19 -0000	1.26
  +++ ap_mmn.h	11 Jan 2002 18:55:27 -0000	1.27
  @@ -89,12 +89,13 @@
    * 20020102 (2.0.30-dev) bump for changed type of limit_req_body in 
    *                       core_dir_config
    * 20020109 (2.0.31-dev) bump for changed shm and scoreboard declarations
  + * 20020111 (2.0.31-dev) bump for ETag fields added at end of cor_dir_config
    */
   
   #define MODULE_MAGIC_COOKIE 0x41503230UL /* "AP20" */
   
   #ifndef MODULE_MAGIC_NUMBER_MAJOR
  -#define MODULE_MAGIC_NUMBER_MAJOR 20020109
  +#define MODULE_MAGIC_NUMBER_MAJOR 20020111
   #endif
   #define MODULE_MAGIC_NUMBER_MINOR 0                     /* 0...n */
   #define MODULE_MAGIC_NUMBER MODULE_MAGIC_NUMBER_MAJOR	/* backward compat */
  
  
  
  1.59      +23 -0     httpd-2.0/include/http_core.h
  
  Index: http_core.h
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/include/http_core.h,v
  retrieving revision 1.58
  retrieving revision 1.59
  diff -u -u -r1.58 -r1.59
  --- http_core.h	2 Jan 2002 07:56:24 -0000	1.58
  +++ http_core.h	11 Jan 2002 18:55:27 -0000	1.59
  @@ -382,6 +382,22 @@
   typedef unsigned char allow_options_t;
   typedef unsigned char overrides_t;
   
  +/*
  + * Bits of info that go into making an ETag for a file
  + * document.  Why a long?  Because char historically
  + * proved too short for Options, and int can be different
  + * sizes on different platforms.
  + */
  +typedef unsigned long etag_components_t;
  +
  +#define ETAG_UNSET 0
  +#define ETAG_NONE  (1 << 0)
  +#define ETAG_MTIME (1 << 1)
  +#define ETAG_INODE (1 << 2)
  +#define ETAG_SIZE  (1 << 3)
  +#define ETAG_BACKWARD (ETAG_MTIME | ETAG_INODE | ETAG_SIZE)
  +#define ETAG_ALL   (ETAG_MTIME | ETAG_INODE | ETAG_SIZE)
  +
   typedef enum {
       srv_sig_unset,
       srv_sig_off,
  @@ -489,6 +505,13 @@
       const char *output_filters;  /* forced with SetOutputFilters */
       const char *input_filters;   /* forced with SetInputFilters */
       int accept_path_info;        /* forced with AcceptPathInfo */
  +
  +    /*
  +     * What attributes/data should be included in ETag generation?
  +     */
  +    etag_components_t etag_bits;
  +    etag_components_t etag_add;
  +    etag_components_t etag_remove;
   } core_dir_config;
   
   /* Per-server core configuration */
  
  
  
  1.386     +55 -9     httpd-2.0/modules/http/http_protocol.c
  
  Index: http_protocol.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/http/http_protocol.c,v
  retrieving revision 1.385
  retrieving revision 1.386
  diff -u -u -r1.385 -r1.386
  --- http_protocol.c	7 Jan 2002 22:36:15 -0000	1.385
  +++ http_protocol.c	11 Jan 2002 18:55:27 -0000	1.386
  @@ -1189,6 +1189,14 @@
           fixup_vary(r);
       }
   
  +    /*
  +     * Now remove any ETag response header field if earlier processing
  +     * says so (such as a 'FileETag None' directive).
  +     */
  +    if (apr_table_get(r->notes, "no-etag") != NULL) {
  +        apr_table_unset(r->headers_out, "ETag");
  +    }
  +
       /* determine the protocol and whether we should use keepalives. */
       basic_http_header_check(r, &protocol);
       ap_set_keepalive(r);
  @@ -2205,7 +2213,27 @@
       apr_size_t weak_len;
       char *etag;
       char *next;
  +    core_dir_config *cfg;
  +    etag_components_t etag_bits;
  +    etag_components_t bits_added;
  +
  +    cfg = (core_dir_config *)ap_get_module_config(r->per_dir_config,
  +                                                  &core_module);
  +    etag_bits = (cfg->etag_bits & (~ cfg->etag_remove)) | cfg->etag_add;
  +    
  +    /*
  +     * If it's a file (or we wouldn't be here) and no ETags
  +     * should be set for files, return an empty string and
  +     * note it for the header-sender to ignore.
  +     */
  +    if (etag_bits & ETAG_NONE) {
  +        apr_table_setn(r->notes, "no-etag", "omit");
  +        return "";
  +    }
   
  +    if (etag_bits == ETAG_UNSET) {
  +        etag_bits = ETAG_BACKWARD;
  +    }
       /*
        * Make an ETag header out of various pieces of information. We use
        * the last-modified date and, if we have a real file, the
  @@ -2228,7 +2256,10 @@
       }
   
       if (r->finfo.filetype != 0) {
  -        /* [W/]"inode-size-mtime" */
  +        /*
  +         * ETag gets set to [W/]"inode-size-mtime", modulo any
  +         * FileETag keywords.
  +         */
           etag = apr_palloc(r->pool, weak_len + sizeof("\"--\"") +
                             3 * CHARS_PER_UNSIGNED_LONG + 1);
           next = etag;
  @@ -2238,16 +2269,31 @@
               }
           }
           *next++ = '"';
  -        next = etag_ulong_to_hex(next, (unsigned long)r->finfo.inode);
  -        *next++ = '-';
  -        next = etag_ulong_to_hex(next, (unsigned long)r->finfo.size);
  -        *next++ = '-';
  -        next = etag_ulong_to_hex(next, (unsigned long)r->mtime);
  +        bits_added = 0;
  +        if (etag_bits & ETAG_INODE) {
  +            next = etag_ulong_to_hex(next, (unsigned long)r->finfo.inode);
  +            bits_added |= ETAG_INODE;
  +        }
  +        if (etag_bits & ETAG_SIZE) {
  +            if (bits_added != 0) {
  +                *next++ = '-';
  +            }
  +            next = etag_ulong_to_hex(next, (unsigned long)r->finfo.size);
  +            bits_added |= ETAG_SIZE;
  +        }
  +        if (etag_bits & ETAG_MTIME) {
  +            if (bits_added != 0) {
  +                *next++ = '-';
  +            }
  +            next = etag_ulong_to_hex(next, (unsigned long)r->mtime);
  +        }
           *next++ = '"';
  -        *next = 0;
  +        *next = '\0';
       }
       else {
  -        /* [W/]"mtime" */
  +        /*
  +         * Not a file document, so just use the mtime: [W/]"mtime"
  +         */
           etag = apr_palloc(r->pool, weak_len + sizeof("\"\"") +
                             CHARS_PER_UNSIGNED_LONG + 1);
           next = etag;
  @@ -2259,7 +2305,7 @@
           *next++ = '"';
           next = etag_ulong_to_hex(next, (unsigned long)r->mtime);
           *next++ = '"';
  -        *next = 0;
  +        *next = '\0';
       }
   
       return etag;
  
  
  
  1.129     +158 -0    httpd-2.0/server/core.c
  
  Index: core.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/server/core.c,v
  retrieving revision 1.128
  retrieving revision 1.129
  diff -u -u -r1.128 -r1.129
  --- core.c	8 Jan 2002 17:07:19 -0000	1.128
  +++ core.c	11 Jan 2002 18:55:27 -0000	1.129
  @@ -166,6 +166,13 @@
       conf->output_filters = NULL;
       conf->input_filters = NULL;
   
  +    /*
  +     * Flag for use of inodes in ETags.
  +     */
  +    conf->etag_bits = ETAG_UNSET;
  +    conf->etag_add = ETAG_UNSET;
  +    conf->etag_remove = ETAG_UNSET;
  +
       return (void *)conf;
   }
   
  @@ -330,6 +337,26 @@
           conf->input_filters = new->input_filters;
       }
   
  +    /*
  +     * Now merge the setting of the FileETag directive.
  +     */
  +    if (new->etag_bits == ETAG_UNSET) {
  +        conf->etag_add =
  +            (conf->etag_add & (~ new->etag_remove)) | new->etag_add;
  +        conf->etag_remove =
  +            (conf->opts_remove & (~ new->etag_add)) | new->etag_remove;
  +        conf->etag_bits =
  +            (conf->etag_bits & (~ conf->etag_remove)) | conf->etag_add;
  +    }
  +    else {
  +        conf->etag_bits = new->etag_bits;
  +        conf->etag_add = new->etag_add;
  +        conf->etag_remove = new->etag_remove;
  +    }
  +    if (conf->etag_bits != ETAG_NONE) {
  +        conf->etag_bits &= (~ ETAG_NONE);
  +    }
  +
       return (void*)conf;
   }
   
  @@ -1131,6 +1158,135 @@
       return NULL;
   }
   
  +/*
  + * Note what data should be used when forming file ETag values.
  + * It would be nicer to do this as an ITERATE, but then we couldn't
  + * remember the +/- state properly.
  + */
  +static const char *set_etag_bits(cmd_parms *cmd, void *mconfig,
  +                                 const char *args_p)
  +{
  +    core_dir_config *cfg;
  +    etag_components_t bit;
  +    char action;
  +    char *token;
  +    const char *args;
  +    int valid;
  +    int first;
  +    int explicit;
  +
  +    cfg = (core_dir_config *) mconfig;
  +
  +    args = args_p;
  +    first = 1;
  +    explicit = 0;
  +    while (args[0] != '\0') {
  +        action = '*';
  +        bit = ETAG_UNSET;
  +        valid = 1;
  +        token = ap_getword_conf(cmd->pool, &args);
  +        if ((*token == '+') || (*token == '-')) {
  +            action = *token;
  +            token++;
  +        }
  +        else {
  +            /*
  +             * The occurrence of an absolute setting wipes
  +             * out any previous relative ones.  The first such
  +             * occurrence forgets any inherited ones, too.
  +             */
  +            if (first) {
  +                cfg->etag_bits = ETAG_UNSET;
  +                cfg->etag_add = ETAG_UNSET;
  +                cfg->etag_remove = ETAG_UNSET;
  +                first = 0;
  +            }
  +        }
  +
  +        if (strcasecmp(token, "None") == 0) {
  +            if (action != '*') {
  +                valid = 0;
  +            }
  +            else {
  +                cfg->etag_bits = bit = ETAG_NONE;
  +                explicit = 1;
  +            }
  +        }
  +        else if (strcasecmp(token, "All") == 0) {
  +            if (action != '*') {
  +                valid = 0;
  +            }
  +            else {
  +                explicit = 1;
  +                cfg->etag_bits = bit = ETAG_ALL;
  +            }
  +        }
  +        else if (strcasecmp(token, "Size") == 0) {
  +            bit = ETAG_SIZE;
  +        }
  +        else if ((strcasecmp(token, "LMTime") == 0)
  +                 || (strcasecmp(token, "MTime") == 0)
  +                 || (strcasecmp(token, "LastModified") == 0)) {
  +            bit = ETAG_MTIME;
  +        }
  +        else if (strcasecmp(token, "INode") == 0) {
  +            bit = ETAG_INODE;
  +        }
  +        else {
  +            return ap_pstrcat(cmd->pool, "Unknown keyword '",
  +                              token, "' for ", cmd->cmd->name,
  +                              " directive", NULL);
  +        }
  +
  +        if (! valid) {
  +            return ap_pstrcat(cmd->pool, cmd->cmd->name, " keyword '",
  +                              token, "' cannot be used with '+' or '-'",
  +                              NULL);
  +        }
  +
  +        if (action == '+') {
  +            /*
  +             * Make sure it's in the 'add' list and absent from the
  +             * 'subtract' list.
  +             */
  +            cfg->etag_add |= bit;
  +            cfg->etag_remove &= (~ bit);
  +        }
  +        else if (action == '-') {
  +            cfg->etag_remove |= bit;
  +            cfg->etag_add &= (~ bit);
  +        }
  +        else {
  +            /*
  +             * Non-relative values wipe out any + or - values
  +             * accumulated so far.
  +             */
  +            cfg->etag_bits |= bit;
  +            cfg->etag_add = ETAG_UNSET;
  +            cfg->etag_remove = ETAG_UNSET;
  +            explicit = 1;
  +        }
  +    }
  +
  +    /*
  +     * Any setting at all will clear the 'None' and 'Unset' bits.
  +     */
  +
  +    if (cfg->etag_add != ETAG_UNSET) {
  +        cfg->etag_add &= (~ ETAG_UNSET);
  +    }
  +    if (cfg->etag_remove != ETAG_UNSET) {
  +        cfg->etag_remove &= (~ ETAG_UNSET);
  +    }
  +    if (explicit) {
  +        cfg->etag_bits &= (~ ETAG_UNSET);
  +        if ((cfg->etag_bits & ETAG_NONE) != ETAG_NONE) {
  +            cfg->etag_bits &= (~ ETAG_NONE);
  +        }
  +    }
  +    return NULL;
  +}
  +
   static const char *satisfy(cmd_parms *cmd, void *c_, const char *arg)
   {
       core_dir_config *c=c_;
  @@ -2459,6 +2615,8 @@
   AP_INIT_TAKE1("DefaultType", ap_set_string_slot,
     (void*)APR_XtOffsetOf (core_dir_config, ap_default_type),
     OR_FILEINFO, "the default MIME type for untypable files"),
  +AP_INIT_RAW_ARGS("FileETag", set_etag_bits, NULL, OR_FILEINFO,
  +  "Specify components used to construct a file's ETag"),
   
   /* Old server config file commands */
   
  
  
  

Mime
View raw message