httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From field...@hyperreal.org
Subject cvs commit: apache-1.3/src/support httpd.exp
Date Tue, 09 Feb 1999 16:57:27 GMT
fielding    99/02/09 08:57:26

  Modified:    src      ApacheCore.def CHANGES
               src/include ap_mmn.h httpd.h
               src/main http_protocol.c util.c
               src/support httpd.exp
  Log:
  Refix the entity tag comparisons for If-Range, If-Match and If-None-Match.
  Comparisons need to be case sensitive and in all but one case (cache update)
  need to be strong comparisons, taking into account the possibility that
  any of the current Etag or the one(s) received from the client may be weak.
  
  Changed name of ap_find_list_item() to ap_size_list_item() to be consistent
  with other find routines and added new (simple) ap_find_list_item(), whose
  implementation will eventually be replaced with something more efficient.
  
  PR: 2065, 3657
  Submitted by:	Roy Fielding, Ken Coar, Dean Gaudet
  
  Revision  Changes    Path
  1.11      +2 -2      apache-1.3/src/ApacheCore.def
  
  Index: ApacheCore.def
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/ApacheCore.def,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- ApacheCore.def	1999/02/08 15:12:15	1.10
  +++ ApacheCore.def	1999/02/09 16:57:19	1.11
  @@ -324,9 +324,9 @@
   	ap_make_etag   @317
   	ap_array_pstrcat   @318
   	ap_os_is_filename_valid   @319
  -	ap_find_opaque_token   @320
  +	ap_find_list_item   @320
   	ap_MD5Encode   @321
   	ap_validate_password   @322
  -	ap_find_list_item   @323
  +	ap_size_list_item   @323
   	ap_get_list_item   @324
   
  
  
  
  1.1242    +11 -5     apache-1.3/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/CHANGES,v
  retrieving revision 1.1241
  retrieving revision 1.1242
  diff -u -r1.1241 -r1.1242
  --- CHANGES	1999/02/09 16:38:07	1.1241
  +++ CHANGES	1999/02/09 16:57:20	1.1242
  @@ -1,16 +1,22 @@
   Changes with Apache 1.3.5
   
  +  *) Entity tag comparisons for If-Match and If-None-Match were not being
  +     performed correctly -- weak tags might cause false positives.  Also,
  +     strong comparison wasn't properly enforced in all cases.
  +     [Roy Fielding, Ken Coar, Dean Gaudet] PR#2065, 3657
  +
     *) OS/2: Supply OS/2 error code instead of errno on semaphore errors.
        [Brian Havard]
   
     *) Work around a bug in Lynx regarding its sending "Negotiate: trans"
        even though it doesn't understand TCN.  [Koen Holtman, Roy Fielding]
   
  -  *) Added ap_find_list_item() and ap_get_list_item() to util.c for parsing
  -     an HTTP header field value to extract the next list item, taking into
  -     account the possible presence of nested comments, quoted-pairs,
  -     and quoted-strings. ap_get_list_item() also removes insignificant
  -     whitespace and lowercases non-quoted tokens. [Roy Fielding] PR#2065
  +  *) Added ap_size_list_item(), ap_get_list_item(), and ap_find_list_item()
  +     to util.c for parsing an HTTP header field value to extract the next
  +     list item, taking into account the possible presence of nested comments,
  +     quoted-pairs, and quoted-strings. ap_get_list_item() also removes
  +     insignificant whitespace and lowercases non-quoted tokens.
  +     [Roy Fielding] PR#2065
   
     *) proxy: The various calls to ap_proxyerror() can return HTTP/1.1 status
        code different from 500. This allows the proxy to, e.g., return
  
  
  
  1.28      +3 -2      apache-1.3/src/include/ap_mmn.h
  
  Index: ap_mmn.h
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/include/ap_mmn.h,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- ap_mmn.h	1999/02/09 12:29:52	1.27
  +++ ap_mmn.h	1999/02/09 16:57:22	1.28
  @@ -207,7 +207,8 @@
    * 19990108.1           - add ap_MD5Encode() for MD5 password handling.
    * 19990108.2           - add ap_validate_password() and change ap_MD5Encode()
    *                        to use a stronger algorithm.
  - * 19990108.3           - add ap_find_list_item() and ap_get_list_item()
  + * 19990108.4           - add ap_size_list_item(), ap_get_list_item(), and
  + *                        ap_find_list_item()
    */
   
   #define MODULE_MAGIC_COOKIE 0x41503133UL /* "AP13" */
  @@ -215,7 +216,7 @@
   #ifndef MODULE_MAGIC_NUMBER_MAJOR
   #define MODULE_MAGIC_NUMBER_MAJOR 19990108
   #endif
  -#define MODULE_MAGIC_NUMBER_MINOR 3                     /* 0...n */
  +#define MODULE_MAGIC_NUMBER_MINOR 4                     /* 0...n */
   #define MODULE_MAGIC_NUMBER MODULE_MAGIC_NUMBER_MAJOR	/* backward compat */
   
   /* Useful for testing for features. */
  
  
  
  1.269     +3 -1      apache-1.3/src/include/httpd.h
  
  Index: httpd.h
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/include/httpd.h,v
  retrieving revision 1.268
  retrieving revision 1.269
  diff -u -r1.268 -r1.269
  --- httpd.h	1999/02/09 12:29:53	1.268
  +++ httpd.h	1999/02/09 16:57:22	1.269
  @@ -932,8 +932,10 @@
   API_EXPORT(char *) ap_getword_conf(pool *p, const char **line);
   API_EXPORT(char *) ap_getword_conf_nc(pool *p, char **line);
   
  -API_EXPORT(const char *) ap_find_list_item(const char **field, int *len);
  +API_EXPORT(const char *) ap_size_list_item(const char **field, int *len);
   API_EXPORT(char *) ap_get_list_item(pool *p, const char **field);
  +API_EXPORT(int) ap_find_list_item(pool *p, const char *line, const char *tok);
  +
   API_EXPORT(char *) ap_get_token(pool *p, const char **accept_line, int accept_white);
   API_EXPORT(int) ap_find_token(pool *p, const char *line, const char *tok);
   API_EXPORT(int) ap_find_last_token(pool *p, const char *line, const char *tok);
  
  
  
  1.257     +40 -21    apache-1.3/src/main/http_protocol.c
  
  Index: http_protocol.c
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/main/http_protocol.c,v
  retrieving revision 1.256
  retrieving revision 1.257
  diff -u -r1.256 -r1.257
  --- http_protocol.c	1999/02/09 12:29:57	1.256
  +++ http_protocol.c	1999/02/09 16:57:24	1.257
  @@ -144,16 +144,18 @@
           return 0;
       }
   
  -    /* Check the If-Range header for Etag or Date */
  -
  +    /* Check the If-Range header for Etag or Date.
  +     * Note that this check will return false (as required) if either
  +     * of the two etags are weak.
  +     */
       if ((if_range = ap_table_get(r->headers_in, "If-Range"))) {
           if (if_range[0] == '"') {
               if (!(match = ap_table_get(r->headers_out, "Etag")) ||
  -                (strcasecmp(if_range, match) != 0))
  +                (strcmp(if_range, match) != 0))
                   return 0;
           }
           else if (!(match = ap_table_get(r->headers_out, "Last-Modified")) ||
  -                 (strcasecmp(if_range, match) != 0))
  +                 (strcmp(if_range, match) != 0))
               return 0;
       }
   
  @@ -398,13 +400,14 @@
       mtime = (r->mtime != 0) ? r->mtime : time(NULL);
   
       /* If an If-Match request-header field was given
  -     * AND if our ETag does not match any of the entity tags in that field
  -     * AND the field value is not "*" (meaning match anything), then
  +     * AND the field value is not "*" (meaning match anything)
  +     * AND if our strong ETag does not match any entity tag in that field,
        *     respond with a status of 412 (Precondition Failed).
        */
       if ((if_match = ap_table_get(r->headers_in, "If-Match")) != NULL) {
  -        if ((etag == NULL) ||
  -            ((if_match[0] != '*') && !ap_find_token(r->pool, if_match, etag)))
{
  +        if (if_match[0] != '*' &&
  +            (etag == NULL || etag[0] == 'W' ||
  +             !ap_find_list_item(r->pool, if_match, etag))) {
               return HTTP_PRECONDITION_FAILED;
           }
       }
  @@ -425,22 +428,38 @@
       }
   
       /* If an If-None-Match request-header field was given
  -     * AND if our ETag matches any of the entity tags in that field
  -     * OR if the field value is "*" (meaning match anything), then
  -     *    if the request method was GET or HEAD, the server SHOULD
  -     *       respond with a 304 (Not Modified) response.
  -     *    For all other request methods, the server MUST
  -     *       respond with a status of 412 (Precondition Failed).
  +     * AND the field value is "*" (meaning match anything)
  +     *     OR our ETag matches any of the entity tags in that field, fail.
  +     *
  +     * If the request method was GET or HEAD, failure means the server
  +     *    SHOULD respond with a 304 (Not Modified) response.
  +     * For all other request methods, failure means the server MUST
  +     *    respond with a status of 412 (Precondition Failed).
  +     *
  +     * GET or HEAD allow weak etag comparison, all other methods require
  +     * strong comparison.  We can only use weak if it's not a range request.
        */
       if_nonematch = ap_table_get(r->headers_in, "If-None-Match");
       if (if_nonematch != NULL) {
  -        int rstatus;
  -
  -        if ((if_nonematch[0] == '*')
  -            || ((etag != NULL) && ap_find_token(r->pool, if_nonematch, etag)))
{
  -            rstatus = (r->method_number == M_GET) ? HTTP_NOT_MODIFIED
  -                                                  : HTTP_PRECONDITION_FAILED;
  -            return rstatus;
  +        if (r->method_number == M_GET) {
  +            if (if_nonematch[0] == '*')
  +                return HTTP_NOT_MODIFIED;
  +            if (etag != NULL) {
  +                if (ap_table_get(r->headers_in, "Range")) {
  +                    if (etag[0] != 'W' &&
  +                        ap_find_list_item(r->pool, if_nonematch, etag)) {
  +                        return HTTP_NOT_MODIFIED;
  +                    }
  +                }
  +                else if (strstr(if_nonematch, etag)) {
  +                    return HTTP_NOT_MODIFIED;
  +                }
  +            }
  +        }
  +        else if (if_nonematch[0] == '*' ||
  +                 (etag != NULL &&
  +                  ap_find_list_item(r->pool, if_nonematch, etag))) {
  +            return HTTP_PRECONDITION_FAILED;
           }
       }
       /* Else if a valid If-Modified-Since request-header field was given
  
  
  
  1.150     +36 -9     apache-1.3/src/main/util.c
  
  Index: util.c
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/main/util.c,v
  retrieving revision 1.149
  retrieving revision 1.150
  diff -u -r1.149 -r1.150
  --- util.c	1999/02/09 12:29:58	1.149
  +++ util.c	1999/02/09 16:57:24	1.150
  @@ -978,16 +978,16 @@
       }
   }
   
  -/* Find an HTTP header field list item, as separated by a comma.
  +/* Size an HTTP header field list item, as separated by a comma.
    * The return value is a pointer to the beginning of the non-empty list item
    * within the original string (or NULL if there is none) and the address
    * of field is shifted to the next non-comma, non-whitespace character.
    * len is the length of the item excluding any beginning whitespace.
    */
  -API_EXPORT(const char *) ap_find_list_item(const char **field, int *len)
  +API_EXPORT(const char *) ap_size_list_item(const char **field, int *len)
   {
  -    const char *ptr = *field;
  -    const char *token;
  +    const unsigned char *ptr = (const unsigned char *)*field;
  +    const unsigned char *token;
       int in_qpair, in_qstr, in_com;
   
       /* Find first non-comma, non-whitespace byte */
  @@ -1035,7 +1035,7 @@
   	++ptr;
   
       *field = ptr;
  -    return token;
  +    return (const char *)token;
   }
   
   /* Retrieve an HTTP header field list item, as separated by a comma,
  @@ -1046,14 +1046,16 @@
    */
   API_EXPORT(char *) ap_get_list_item(pool *p, const char **field)
   {
  -    const char *tok_start, *ptr;
  -    char *token, *pos;
  +    const char *tok_start;
  +    const unsigned char *ptr;
  +    unsigned char *pos;
  +    char *token;
       int addspace = 0, in_qpair = 0, in_qstr = 0, in_com = 0, tok_len = 0;
   
       /* Find the beginning and maximum length of the list item so that
        * we can allocate a buffer for the new string and reset the field.
        */
  -    if ((tok_start = ap_find_list_item(field, &tok_len)) == NULL) {
  +    if ((tok_start = ap_size_list_item(field, &tok_len)) == NULL) {
           return NULL;
       }
       token = ap_palloc(p, tok_len + 1);
  @@ -1063,7 +1065,7 @@
        * strip comments, and lowercase normal characters not within a
        * quoted-string or quoted-pair.  The result may be an empty string.
        */
  -    for (ptr = tok_start, pos = token;
  +    for (ptr = (const unsigned char *)tok_start, pos = (unsigned char *)token;
            *ptr && (in_qpair || in_qstr || in_com || *ptr != ',');
            ++ptr) {
   
  @@ -1129,6 +1131,31 @@
   
       return token;
   }
  +
  +/* Find an item in canonical form (lowercase, no extra spaces) within
  + * an HTTP field value list.  Returns 1 if found, 0 if not found.
  + * This would be much more efficient if we stored header fields as
  + * an array of list items as they are received instead of a plain string.
  + * We could make it more efficient by duplicating the loop/switch above
  + * within this function, replacing the assignments with compares.
  + */
  +API_EXPORT(int) ap_find_list_item(pool *p, const char *line, const char *tok)
  +{
  +    const char *nxt;
  +    char *item;
  +
  +    if (!line || !tok)
  +        return 0;
  +
  +    nxt = line;
  +
  +    while ((item = ap_get_list_item(p, &nxt)) != NULL) {
  +        if (strcmp(item, tok) == 0)
  +            return 1;
  +    }
  +    return 0;
  +}
  +
   
   /* Retrieve a token, spacing over it and returning a pointer to
    * the first non-white byte afterwards.  Note that these tokens
  
  
  
  1.15      +1 -0      apache-1.3/src/support/httpd.exp
  
  Index: httpd.exp
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/support/httpd.exp,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- httpd.exp	1999/02/08 15:12:21	1.14
  +++ httpd.exp	1999/02/09 16:57:26	1.15
  @@ -312,6 +312,7 @@
   ap_signal
   ap_single_module_configure
   ap_single_module_init
  +ap_size_list_item
   ap_slack
   ap_snprintf
   ap_soft_timeout
  
  
  

Mime
View raw message