httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dean Gaudet <dgau...@arctic.org>
Subject [PATCH] etag continued
Date Thu, 28 Jan 1999 09:29:42 GMT
On 27 Jan 1999 coar@hyperreal.org wrote:

>   +  *) Fix checking of ETags and other opaque 'tokens' by adding
>   +     ap_find_opaque_token().  PR#2065, 3657 [Ken Coar]
>   +
...
>   --- http_protocol.c	1999/01/08 17:54:41	1.253
>   +++ http_protocol.c	1999/01/27 12:16:01	1.254
>   @@ -404,7 +404,8 @@
>         */
>        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_match[0] != '*')
>   +	     && !ap_find_opaque_token(r->pool, if_match, etag))) {
>                return HTTP_PRECONDITION_FAILED;
>            }
>        }
>   @@ -437,7 +438,8 @@
>            int rstatus;
>    
>            if ((if_nonematch[0] == '*')
>   -            || ((etag != NULL) && ap_find_token(r->pool, if_nonematch,
etag))) {
>   +            || ((etag != NULL)
>   +		&& ap_find_opaque_token(r->pool, if_nonematch, etag))) {
>                rstatus = (r->method_number == M_GET) ? HTTP_NOT_MODIFIED
>                                                      : HTTP_PRECONDITION_FAILED;
>                return rstatus;

Unforunately, this is not quite everything. 

In the if-match case, a strong etag comparison has to be performed. 
That's pretty easy to handle -- just make sure etag[0] != 'W' && etag[1]
!= '/'. 

In the if-none-match case, a strong etag comparison has to be performed
unless the method is GET or HEAD.  In that case a weak comparison can be
used...

I think this patch finishes it.  But I haven't tested it at all.  Protocol
cops should check this.

Dean

Index: main/http_protocol.c
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/main/http_protocol.c,v
retrieving revision 1.254
diff -u -r1.254 http_protocol.c
--- http_protocol.c	1999/01/27 12:16:01	1.254
+++ http_protocol.c	1999/01/28 09:27:50
@@ -401,10 +401,12 @@
      * 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
      *     respond with a status of 412 (Precondition Failed).
+     * must use strong comparison
      */
     if ((if_match = ap_table_get(r->headers_in, "If-Match")) != NULL) {
-        if ((etag == NULL) ||
-            ((if_match[0] != '*')
+        if ((etag == NULL)
+	    || (etag[0] == 'W' && etag[1] == '/')
+            || ((if_match[0] != '*')
 	     && !ap_find_opaque_token(r->pool, if_match, etag))) {
             return HTTP_PRECONDITION_FAILED;
         }
@@ -432,17 +434,25 @@
      *       respond with a 304 (Not Modified) response.
      *    For all other request methods, the server MUST
      *       respond with a status of 412 (Precondition Failed).
+     * GET or HEAD allow weak comparison, all other methods require
+     * strong comparison
      */
     if_nonematch = ap_table_get(r->headers_in, "If-None-Match");
     if (if_nonematch != NULL) {
-        int rstatus;
-
-        if ((if_nonematch[0] == '*')
+	if (r->method_number == M_GET) {
+	    if ((if_nonematch[0] == '*')
+		|| ((etag != NULL)
+		    && ((etag[0] == 'W' && etag[1] == '/'
+			&& ap_find_opaque_token(r->pool, if_nonematch, etag + 2))
+			|| ap_find_opaque_token(r->pool, if_nonematch, etag)))) {
+		return HTTP_NOT_MODIFIED;
+	    }
+	}
+	else if ((if_nonematch[0] == '*')
             || ((etag != NULL)
+		&& (etag[0] != 'W' || etag[1] != '/')
 		&& ap_find_opaque_token(r->pool, if_nonematch, etag))) {
-            rstatus = (r->method_number == M_GET) ? HTTP_NOT_MODIFIED
-                                                  : HTTP_PRECONDITION_FAILED;
-            return rstatus;
+	    return HTTP_PRECONDITION_FAILED;
         }
     }
     /* Else if a valid If-Modified-Since request-header field was given





Mime
View raw message