diff options
Diffstat (limited to 'modules/dav')
-rw-r--r-- | modules/dav/fs/lock.c | 9 | ||||
-rw-r--r-- | modules/dav/fs/repos.c | 12 | ||||
-rw-r--r-- | modules/dav/lock/locks.c | 9 | ||||
-rw-r--r-- | modules/dav/main/mod_dav.c | 2 | ||||
-rw-r--r-- | modules/dav/main/util.c | 59 |
5 files changed, 71 insertions, 20 deletions
diff --git a/modules/dav/fs/lock.c b/modules/dav/fs/lock.c index 61dd8553..32220a79 100644 --- a/modules/dav/fs/lock.c +++ b/modules/dav/fs/lock.c @@ -600,8 +600,7 @@ static dav_error * dav_fs_load_lock_record(dav_lockdb *lockdb, apr_datum_t key, dp = apr_pcalloc(p, sizeof(*dp)); memcpy(dp, val.dptr + offset, sizeof(dp->f)); offset += sizeof(dp->f); - dp->locktoken = apr_palloc(p, sizeof(*dp->locktoken)); - memcpy(dp->locktoken, val.dptr + offset, sizeof(*dp->locktoken)); + dp->locktoken = apr_pmemdup(p, val.dptr + offset, sizeof(*dp->locktoken)); offset += sizeof(*dp->locktoken); if (*(val.dptr + offset) == '\0') { ++offset; @@ -648,15 +647,13 @@ static dav_error * dav_fs_load_lock_record(dav_lockdb *lockdb, apr_datum_t key, /* Create and fill a dav_lock_indirect structure */ ip = apr_pcalloc(p, sizeof(*ip)); - ip->locktoken = apr_palloc(p, sizeof(*ip->locktoken)); - memcpy(ip->locktoken, val.dptr + offset, sizeof(*ip->locktoken)); + ip->locktoken = apr_pmemdup(p, val.dptr + offset, sizeof(*ip->locktoken)); offset += sizeof(*ip->locktoken); memcpy(&ip->timeout, val.dptr + offset, sizeof(ip->timeout)); offset += sizeof(ip->timeout); memcpy(&ip->key.dsize, val.dptr + offset, sizeof(ip->key.dsize)); /* length of datum */ offset += sizeof(ip->key.dsize); - ip->key.dptr = apr_palloc(p, ip->key.dsize); - memcpy(ip->key.dptr, val.dptr + offset, ip->key.dsize); + ip->key.dptr = apr_pmemdup(p, val.dptr + offset, ip->key.dsize); offset += ip->key.dsize; if (!dav_fs_lock_expired(ip->timeout)) { diff --git a/modules/dav/fs/repos.c b/modules/dav/fs/repos.c index 8c28c076..a532e6e9 100644 --- a/modules/dav/fs/repos.c +++ b/modules/dav/fs/repos.c @@ -1777,13 +1777,15 @@ static const char *dav_fs_getetag(const dav_resource *resource) return apr_pstrdup(ctx->pool, ""); if (ctx->finfo.filetype != 0) { - return apr_psprintf(ctx->pool, "\"%lx-%lx-%lx\"", - (unsigned long) ctx->finfo.inode, - (unsigned long) ctx->finfo.size, - (unsigned long) ctx->finfo.mtime); + return apr_psprintf(ctx->pool, "\"%" APR_UINT64_T_HEX_FMT "-%" + APR_UINT64_T_HEX_FMT "-%" APR_UINT64_T_HEX_FMT "\"", + (apr_uint64_t) ctx->finfo.inode, + (apr_uint64_t) ctx->finfo.size, + (apr_uint64_t) ctx->finfo.mtime); } - return apr_psprintf(ctx->pool, "\"%lx\"", (unsigned long) ctx->finfo.mtime); + return apr_psprintf(ctx->pool, "\"%" APR_UINT64_T_HEX_FMT "\"", + (apr_uint64_t) ctx->finfo.mtime); } static const dav_hooks_repository dav_hooks_repository_fs = diff --git a/modules/dav/lock/locks.c b/modules/dav/lock/locks.c index 2b297a8c..a4e0e214 100644 --- a/modules/dav/lock/locks.c +++ b/modules/dav/lock/locks.c @@ -603,8 +603,7 @@ static dav_error * dav_generic_load_lock_record(dav_lockdb *lockdb, offset += sizeof(dp->f); /* Copy the lock token. */ - dp->locktoken = apr_palloc(p, sizeof(*dp->locktoken)); - memcpy(dp->locktoken, val.dptr + offset, sizeof(*dp->locktoken)); + dp->locktoken = apr_pmemdup(p, val.dptr + offset, sizeof(*dp->locktoken)); offset += sizeof(*dp->locktoken); /* Do we have an owner field? */ @@ -639,16 +638,14 @@ static dav_error * dav_generic_load_lock_record(dav_lockdb *lockdb, /* Create and fill a dav_lock_indirect structure */ ip = apr_pcalloc(p, sizeof(*ip)); - ip->locktoken = apr_palloc(p, sizeof(*ip->locktoken)); - memcpy(ip->locktoken, val.dptr + offset, sizeof(*ip->locktoken)); + ip->locktoken = apr_pmemdup(p, val.dptr + offset, sizeof(*ip->locktoken)); offset += sizeof(*ip->locktoken); memcpy(&ip->timeout, val.dptr + offset, sizeof(ip->timeout)); offset += sizeof(ip->timeout); /* length of datum */ ip->key.dsize = *((int *) (val.dptr + offset)); offset += sizeof(ip->key.dsize); - ip->key.dptr = apr_palloc(p, ip->key.dsize); - memcpy(ip->key.dptr, val.dptr + offset, ip->key.dsize); + ip->key.dptr = apr_pmemdup(p, val.dptr + offset, ip->key.dsize); offset += ip->key.dsize; if (!dav_generic_lock_expired(ip->timeout)) { diff --git a/modules/dav/main/mod_dav.c b/modules/dav/main/mod_dav.c index 9033cad9..24699bc0 100644 --- a/modules/dav/main/mod_dav.c +++ b/modules/dav/main/mod_dav.c @@ -317,7 +317,7 @@ static int dav_error_response(request_rec *r, int status, const char *body) /* ### I really don't think this is needed; gotta test */ r->status_line = ap_get_status_line(status); - ap_set_content_type(r, "text/html"); + ap_set_content_type(r, "text/html; charset=ISO-8859-1"); /* begin the response now... */ ap_rvputs(r, diff --git a/modules/dav/main/util.c b/modules/dav/main/util.c index 153f25d4..5297b908 100644 --- a/modules/dav/main/util.c +++ b/modules/dav/main/util.c @@ -1404,6 +1404,39 @@ 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 +1466,9 @@ 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; + const char *etag; + int set_etag = 0; #if DAV_DEBUG if (depth && response == NULL) { @@ -1449,10 +1485,29 @@ DAV_DECLARE(dav_error *) dav_validate_request(request_rec *r, if (response != NULL) *response = NULL; + /* Set the ETag header required by dav_meets_conditions() */ + etag = apr_table_get(r->headers_out, "ETag"); + if (!etag) { + etag = (*resource->hooks->getetag)(resource); + if (etag && *etag) { + apr_table_set(r->headers_out, "ETag", etag); + set_etag = 1; + } + } /* Do the standard checks for conditional requests using * If-..-Since, If-Match etc */ - if ((result = ap_meets_conditions(r)) != OK) { - /* ### fix this up... how? */ + resource_state = dav_get_resource_state(r, resource); + result = dav_meets_conditions(r, resource_state); + if (set_etag) { + /* + * If we have set an ETag to headers out above for + * dav_meets_conditions() revert this here as we do not want to set + * the ETag in responses to requests with methods where this might not + * be desired. + */ + apr_table_unset(r->headers_out, "ETag"); + } + if (result != OK) { return dav_new_error(r->pool, result, 0, NULL); } |