# HG changeset patch # User Olaf Wintermann # Date 1579424611 -3600 # Node ID ee1680ef1ef2711a19e2d4289f5b1c235b5da871 # Parent e81d3e517b5772cbb74c9ac5c3abeea53d5653e6 handle missing properties in multistatus.c diff -r e81d3e517b57 -r ee1680ef1ef2 src/server/public/webdav.h --- a/src/server/public/webdav.h Sun Jan 19 09:31:45 2020 +0100 +++ b/src/server/public/webdav.h Sun Jan 19 10:03:31 2020 +0100 @@ -324,7 +324,7 @@ char *value); WebdavVFSProperties webdav_vfs_properties( - WebdavPropfindRequest *rq, + WebdavPList **plistInOut, WSBool removefromlist, uint32_t flags); diff -r e81d3e517b57 -r ee1680ef1ef2 src/server/test/webdav.c --- a/src/server/test/webdav.c Sun Jan 19 09:31:45 2020 +0100 +++ b/src/server/test/webdav.c Sun Jan 19 10:03:31 2020 +0100 @@ -212,6 +212,7 @@ (*out_sn), (*out_rq), &backend1, + propfind->properties, requests, response); } diff -r e81d3e517b57 -r ee1680ef1ef2 src/server/webdav/multistatus.c --- a/src/server/webdav/multistatus.c Sun Jan 19 09:31:45 2020 +0100 +++ b/src/server/webdav/multistatus.c Sun Jan 19 10:03:31 2020 +0100 @@ -552,6 +552,27 @@ ret = REQ_ABORTED; } + // add missing properties with status code 404 + UcxAllocator *a = session_get_allocator(response->multistatus->sn); + WebdavPList *pl = response->multistatus->response.op->reqprops; + while(pl) { + sstr_t key = sstrcat_a( + a, + 3, + sstr((char*)pl->property->namespace->href), + S("\0"), + sstr((char*)pl->property->name)); + if(!ucx_map_sstr_get(response->properties, key)) { + // property was not added to this response + if(msresponse_addproperror(response, pl->property, 404)) { + ret = REQ_ABORTED; + break; + } + } + + pl = pl->next; + } + // we don't need the properties anymore ucx_map_free(response->properties); diff -r e81d3e517b57 -r ee1680ef1ef2 src/server/webdav/multistatus.h --- a/src/server/webdav/multistatus.h Sun Jan 19 09:31:45 2020 +0100 +++ b/src/server/webdav/multistatus.h Sun Jan 19 10:03:31 2020 +0100 @@ -71,10 +71,21 @@ WebdavResource resource; Multistatus *multistatus; + /* + * Contains all properties that were added to the response + * key: null-byte + * value: WebdavProperty* + */ UcxMap *properties; + /* + * All properties with status != 200 + */ PropertyErrorList *errors; + /* + * All properties with status == 200 + */ PropertyOkList *plist_begin; PropertyOkList *plist_end; @@ -84,14 +95,29 @@ struct PropertyOkList { WebdavProperty *property; - WebdavNSList *nsdef; + WebdavNSList *nsdef; PropertyOkList *next; }; struct PropertyErrorList { + /* + * next list for different status code + */ PropertyErrorList *next; + + /* + * property list for all properties with this status code + */ WebdavPList *begin; + + /* + * tail of the property list + */ WebdavPList *end; + + /* + * property response status code + */ int status; }; diff -r e81d3e517b57 -r ee1680ef1ef2 src/server/webdav/operation.c --- a/src/server/webdav/operation.c Sun Jan 19 09:31:45 2020 +0100 +++ b/src/server/webdav/operation.c Sun Jan 19 10:03:31 2020 +0100 @@ -41,6 +41,7 @@ Session *sn, Request *rq, WebdavBackend *dav, + WebdavPList *reqprops, UcxList *requests, WebdavResponse *response) { @@ -49,6 +50,7 @@ op->dav = dav; op->sn = sn; op->rq = rq; + op->reqprops = reqprops; op->requests = requests; op->response = response; diff -r e81d3e517b57 -r ee1680ef1ef2 src/server/webdav/operation.h --- a/src/server/webdav/operation.h Sun Jan 19 09:31:45 2020 +0100 +++ b/src/server/webdav/operation.h Sun Jan 19 10:03:31 2020 +0100 @@ -39,18 +39,21 @@ WebdavBackend *dav; Request *rq; Session *sn; - UcxList *requests; /* backend specific request objects */ + + WebdavPList *reqprops; /* requested properties */ + UcxList *requests; /* backend specific request objects */ WebdavResponse *response; - VFS_DIR parent; /* current directory */ - struct stat *stat; /* current stat object */ + VFS_DIR parent; /* current directory */ + struct stat *stat; /* current stat object */ }; WebdavOperation* webdav_operation_create( Session *sn, Request *rq, WebdavBackend *dav, + WebdavPList *reqprops, UcxList *requests, WebdavResponse *response); diff -r e81d3e517b57 -r ee1680ef1ef2 src/server/webdav/webdav.c --- a/src/server/webdav/webdav.c Sun Jan 19 09:31:45 2020 +0100 +++ b/src/server/webdav/webdav.c Sun Jan 19 10:03:31 2020 +0100 @@ -228,6 +228,7 @@ sn, rq, dav, + propfind->properties, requestObjects, response); @@ -414,7 +415,7 @@ } rq->userdata = data; - data->vfsproperties = webdav_vfs_properties(rq, TRUE, 0); + data->vfsproperties = webdav_vfs_properties(outplist, TRUE, 0); return 0; } @@ -629,7 +630,7 @@ } WebdavVFSProperties webdav_vfs_properties( - WebdavPropfindRequest *rq, + WebdavPList **plistInOut, WSBool removefromlist, uint32_t flags) { @@ -639,14 +640,13 @@ WSBool etag = 1; WSBool creationdate = 1; - WebdavPList *property = rq->properties; - WebdavPList *prev = NULL; - while(property) { - WebdavPList *next = property->next; - WSNamespace *ns = property->property->namespace; - if(ns && !strcmp((char*)ns->href, "DAV:")) { - const char *name = property->property->name; - WebdavPList *removethis = property; + WebdavPListIterator i = webdav_plist_iterator(plistInOut); + WebdavPList *cur; + while(webdav_plist_iterator_next(&i, &cur)) { + WSNamespace *ns = cur->property->namespace; + if(ns && !strcmp((const char*)ns->href, "DAV:")) { + const char *name = cur->property->name; + WSBool remove_prop = TRUE; if(!strcmp(name, "getlastmodified")) { ret.getlastmodified = 1; } else if(!strcmp(name, "getcontentlength")) { @@ -658,20 +658,13 @@ } else if(creationdate && !strcmp(name, "creationdate")) { ret.creationdate = 1; } else { - removethis = NULL; + remove_prop = FALSE; } - if(removefromlist && removethis) { - - if(prev) { - prev->next = next; - } else { - rq->properties = next; - } + if(remove_prop) { + webdav_plist_iterator_remove_current(&i); } } - prev = property; - property = next; } return ret;