ASF Bugzilla – Attachment 20552 Details for
Bug 38034
PUT If-None-Match: "*" failures
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Fixes If-Match: * and If-None-Match: * bug for mod_dav
httpd-2.2.4-match-any.patch (text/plain), 6.29 KB, created by
Werner
on 2007-07-26 11:30:39 UTC
(
hide
)
Description:
Fixes If-Match: * and If-None-Match: * bug for mod_dav
Filename:
MIME Type:
Creator:
Werner
Created:
2007-07-26 11:30:39 UTC
Size:
6.29 KB
patch
obsolete
>--- httpd-2.2.4/modules/dav/main/util.c 2006-07-12 05:38:44.000000000 +0200 >+++ httpd-2.2.4-new/modules/dav/main/util.c 2007-07-26 18:30:01.000000000 +0200 >@@ -19,6 +19,7 @@ > ** - various utilities, repository-independent > */ > >+#include "apr_date.h" > #include "apr_strings.h" > #include "apr_lib.h" > >@@ -1404,6 +1405,141 @@ > return NULL; > } > >+/** This is a copy of ap_meets_conditions with this changes: >+ * - additional parameter resource >+ * - use (*resource->hooks->getetag)(resource) to get etag, as >+ * apr_table_get(r->headers_out, "ETag") does not work in this context. >+ * - "If-None-Match: *" evaluates to TRUE if the resource does not exist. >+ * - "If-Match: *" evaluates to TRUE if the resource exists. >+ */ >+static int dav_meets_conditions(request_rec *r, dav_resource *resource) >+{ >+ const char *etag; >+ const char *if_match, *if_modified_since, *if_unmodified, *if_nonematch; >+ apr_time_t tmp_time; >+ apr_int64_t mtime; >+ int not_modified = 0; >+ >+ /* Check for conditional requests --- note that we only want to do >+ * this if we are successful so far and we are not processing a >+ * subrequest or an ErrorDocument. >+ * >+ * The order of the checks is important, since ETag checks are supposed >+ * to be more accurate than checks relative to the modification time. >+ * However, not all documents are guaranteed to *have* ETags, and some >+ * might have Last-Modified values w/o ETags, so this gets a little >+ * complicated. >+ */ >+ >+ if (!ap_is_HTTP_SUCCESS(r->status) || r->no_local_copy) { >+ return OK; >+ } >+ >+ etag = (*resource->hooks->getetag)(resource); >+ >+ /* All of our comparisons must be in seconds, because that's the >+ * highest time resolution the HTTP specification allows. >+ */ >+ /* XXX: we should define a "time unset" constant */ >+ tmp_time = ((r->mtime != 0) ? r->mtime : apr_time_now()); >+ mtime = apr_time_sec(tmp_time); >+ >+ /* If an If-Match request-header field was given >+ * AND ( the field value is not "*" (meaning match anything) >+ * OR the resource does not exist ) >+ * 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 = apr_table_get(r->headers_in, "If-Match")) != NULL) { >+ if (!(if_match[0] == '*' && resource->exists) >+ && (etag == NULL || etag[0] == 'W' >+ || !ap_find_list_item(r->pool, if_match, etag))) { >+ return HTTP_PRECONDITION_FAILED; >+ } >+ } >+ else { >+ /* Else if a valid If-Unmodified-Since request-header field was given >+ * AND the requested resource has been modified since the time >+ * specified in this field, then the server MUST >+ * respond with a status of 412 (Precondition Failed). >+ */ >+ if_unmodified = apr_table_get(r->headers_in, "If-Unmodified-Since"); >+ if (if_unmodified != NULL) { >+ apr_time_t ius = apr_date_parse_http(if_unmodified); >+ >+ if ((ius != APR_DATE_BAD) && (mtime > apr_time_sec(ius))) { >+ return HTTP_PRECONDITION_FAILED; >+ } >+ } >+ } >+ >+ /* If an If-None-Match request-header field was given >+ * AND the field value is "*" (meaning match anything) >+ * AND the resource exists >+ * 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 = apr_table_get(r->headers_in, "If-None-Match"); >+ if (if_nonematch != NULL) { >+ if (r->method_number == M_GET) { >+ if (if_nonematch[0] == '*') { >+ not_modified = 1; >+ } >+ else if (etag != NULL) { >+ if (apr_table_get(r->headers_in, "Range")) { >+ not_modified = etag[0] != 'W' >+ && ap_find_list_item(r->pool, >+ if_nonematch, etag); >+ } >+ else { >+ not_modified = ap_find_list_item(r->pool, >+ if_nonematch, etag); >+ } >+ } >+ } >+ else if ((if_nonematch[0] == '*' && resource->exists) >+ || (etag != NULL >+ && ap_find_list_item(r->pool, if_nonematch, etag))) { >+ return HTTP_PRECONDITION_FAILED; >+ } >+ } >+ >+ /* If a valid If-Modified-Since request-header field was given >+ * AND it is a GET or HEAD request >+ * AND the requested resource has not been modified since the time >+ * specified in this field, then the server MUST >+ * respond with a status of 304 (Not Modified). >+ * A date later than the server's current request time is invalid. >+ */ >+ if (r->method_number == M_GET >+ && (not_modified || !if_nonematch) >+ && (if_modified_since = >+ apr_table_get(r->headers_in, >+ "If-Modified-Since")) != NULL) { >+ apr_time_t ims_time; >+ apr_int64_t ims, reqtime; >+ >+ ims_time = apr_date_parse_http(if_modified_since); >+ ims = apr_time_sec(ims_time); >+ reqtime = apr_time_sec(r->request_time); >+ >+ not_modified = ims >= mtime && ims <= reqtime; >+ } >+ >+ if (not_modified) { >+ return HTTP_NOT_MODIFIED; >+ } >+ >+ return OK; >+} >+ > /* > ** dav_validate_request: Validate if-headers (and check for locks) on: > ** (1) r->filename @ depth; >@@ -1450,9 +1586,9 @@ > *response = NULL; > > /* Do the standard checks for conditional requests using >- * If-..-Since, If-Match etc */ >- if ((result = ap_meets_conditions(r)) != OK) { >- /* ### fix this up... how? */ >+ * If-..-Since, If-Match etc >+ * use dav_meets_conditions instead of ap_meets_conditions. */ >+ if ((result = dav_meets_conditions(r, resource)) != OK) { > return dav_new_error(r->pool, result, 0, NULL); > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 38034
:
19658
| 20552 |
20553
|
21295
|
21343