From 5ac92dca08359f1991042ac624ec2d1056b9ff40 Mon Sep 17 00:00:00 2001 From: Glenn Strauss Date: Mon, 22 Apr 2019 22:11:48 -0400 Subject: [PATCH] [mod_webdav] check If-None-Match (#1818) x-ref: "add RFC-compliant LOCK support to mod_webdav" https://redmine.lighttpd.net/issues/1818 --- src/mod_webdav.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/mod_webdav.c b/src/mod_webdav.c index 423ec10f..9a89f5ef 100644 --- a/src/mod_webdav.c +++ b/src/mod_webdav.c @@ -2099,28 +2099,43 @@ webdav_if_match_or_unmodified_since (connection * const con, struct stat *st) CONST_STR_LEN("If-Match")) : NULL; + buffer *inm = (0 != con->etag_flags) + ? http_header_request_get(con, HTTP_HEADER_IF_NONE_MATCH, + CONST_STR_LEN("If-None-Match")) + : NULL; + buffer *ius = http_header_request_get(con, HTTP_HEADER_OTHER, CONST_STR_LEN("If-Unmodified-Since")); - if (NULL == im && NULL == ius) return 0; + if (NULL == im && NULL == inm && NULL == ius) return 0; struct stat stp; - if (NULL == st) { - st = &stp; - if (0 != lstat(con->physical.path->ptr, st)) - return 412; /* Precondition Failed */ - } + if (NULL == st) + st = (0 == lstat(con->physical.path->ptr, &stp)) ? &stp : NULL; - if (NULL != im) { - buffer *etagb = con->physical.etag; + buffer *etagb = con->physical.etag; + if (NULL != st && (NULL != im || NULL != inm)) { etag_create(etagb, st, con->etag_flags); etag_mutate(etagb, etagb); - if (!etag_is_equal(etagb, im->ptr, 0)) + } + + if (NULL != im) { + if (NULL == st || !etag_is_equal(etagb, im->ptr, 0)) + return 412; /* Precondition Failed */ + } + + if (NULL != inm) { + if (NULL == st + ? !buffer_is_equal_string(inm,CONST_STR_LEN("*")) + || (errno != ENOENT && errno != ENOTDIR) + : etag_is_equal(etagb, inm->ptr, 0)) return 412; /* Precondition Failed */ } if (NULL != ius) { + if (NULL == st) + return 412; /* Precondition Failed */ struct tm itm, *ftm = gmtime(&st->st_mtime); if (NULL == strptime(ius->ptr, "%a, %d %b %Y %H:%M:%S GMT", &itm) || mktime(ftm) > mktime(&itm)) { /* timegm() not standard */