]> granicus.if.org Git - apache/commitdiff
mod_dav: Fix evaluation of If-Match * and If-None-Match * conditionals.
authorNick Kew <niq@apache.org>
Sat, 29 Dec 2007 19:38:51 +0000 (19:38 +0000)
committerNick Kew <niq@apache.org>
Sat, 29 Dec 2007 19:38:51 +0000 (19:38 +0000)
PR 38034
Patch by Paritosh Shah
Explanation by Werner Baumann

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@607466 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/dav/main/util.c

diff --git a/CHANGES b/CHANGES
index 5a595df6edeed12f3609d255bee327acb4de6ba0..e2ac4a79a4ce0c6abb7b339fda7b9d4702dc689b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -16,6 +16,9 @@ Changes with Apache 2.3.0
      Prevent crash in balancer manager if invalid balancer name is passed
      as parameter. Reported by SecurityReason. [Ruediger Pluem]
 
+  *) mod_dav: Fix evaluation of If-Match * and If-None-Match * conditionals.
+     PR 38034 [Paritosh Shah <shah.paritosh gmail.com>]
+
   *) mod_dav: Adjust etag generation to produce identical results on 32-bit
      and 64-bit platforms and avoid a regression with conditional PUT's on lock
      and etag. PR 44152.
index 153f25d45acb9534b6f7c1b3b1993cdf2190557b..b06f996b6c74bd22ad3c8ad3425ac80643fe471e 100644 (file)
@@ -1404,6 +1404,37 @@ static dav_error * dav_validate_walker(dav_walk_resource *wres, int calltype)
     return NULL;
 }
 
+/* If-* header checking */
+static int dav_meets_conditions(request_rec *r, int resource_state)
+{
+    const char *if_match, *if_none_match;
+    int retVal;
+
+    /* If-Match '*' fix. Resource existence not checked by ap_meets_conditions.
+     * If-Match '*' request should succeed only if the resource exists. */
+    if ((if_match = apr_table_get(r->headers_in, "If-Match")) != NULL) {
+        if(if_match[0] == '*' && resource_state != DAV_RESOURCE_EXISTS)
+            return HTTP_PRECONDITION_FAILED;
+    }
+
+    retVal = ap_meets_conditions(r);
+
+    /* If-None-Match '*' fix. If-None-Match '*' request should succeed 
+     * if the resource does not exist. */
+    if(retVal == HTTP_PRECONDITION_FAILED) {
+        /* Note. If if_none_match != NULL, if_none_match is the culprit.
+         * Since, in presence of If-None-Match, 
+         * other If-* headers are undefined. */
+        if((if_none_match = 
+                apr_table_get(r->headers_in, "If-None-Match")) != NULL) {
+            if(if_none_match[0] == '*' && resource_state != DAV_RESOURCE_EXISTS)
+                return OK;
+        }
+    }
+
+    return retVal;
+}
+
 /*
 ** dav_validate_request:  Validate if-headers (and check for locks) on:
 **    (1) r->filename @ depth;
@@ -1433,6 +1464,7 @@ DAV_DECLARE(dav_error *) dav_validate_request(request_rec *r,
     const dav_hooks_repository *repos_hooks = resource->hooks;
     dav_buffer work_buf = { 0 };
     dav_response *new_response;
+    int resource_state;
 
 #if DAV_DEBUG
     if (depth && response == NULL) {
@@ -1449,9 +1481,17 @@ DAV_DECLARE(dav_error *) dav_validate_request(request_rec *r,
     if (response != NULL)
         *response = NULL;
 
+    /* Set the ETag header required by dav_meets_conditions() */
+    if ((err = (*resource->hooks->set_headers)(r, resource)) != NULL) {
+        return dav_push_error(r->pool, err->status, 0,
+                             "Unable to set up HTTP headers.",
+                             err);
+    }
+
+    resource_state = dav_get_resource_state(r, resource);
     /* Do the standard checks for conditional requests using
      * If-..-Since, If-Match etc */
-    if ((result = ap_meets_conditions(r)) != OK) {
+    if ((result = dav_meets_conditions(r, resource_state)) != OK) {
         /* ### fix this up... how? */
         return dav_new_error(r->pool, result, 0, NULL);
     }