From 0abfd39b25433598464c83b07f53e768771b8154 Mon Sep 17 00:00:00 2001 From: Nick Kew Date: Sat, 29 Dec 2007 19:38:51 +0000 Subject: [PATCH] mod_dav: Fix evaluation of If-Match * and If-None-Match * conditionals. 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 | 3 +++ modules/dav/main/util.c | 42 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 5a595df6ed..e2ac4a79a4 100644 --- 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 ] + *) 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. diff --git a/modules/dav/main/util.c b/modules/dav/main/util.c index 153f25d45a..b06f996b6c 100644 --- a/modules/dav/main/util.c +++ b/modules/dav/main/util.c @@ -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); } -- 2.50.1