diff -r e820d433f405 -r d5031c30022c src/server/webdav/multistatus.c --- a/src/server/webdav/multistatus.c Sat Jan 25 09:00:27 2020 +0100 +++ b/src/server/webdav/multistatus.c Sat Jan 25 11:16:55 2020 +0100 @@ -52,6 +52,7 @@ ms->sn = sn; ms->rq = rq; ms->namespaces = ucx_map_new_a(session_get_allocator(ms->sn), 8); + ms->proppatch = FALSE; if(!ms->namespaces) { return NULL; } @@ -435,6 +436,13 @@ } } + if(response->multistatus->proppatch && response->errors) { + // in a proppatch request all operations must succeed + // if we have an error, the property update status code must be + // 424 Failed Dependency + status = 424; + } + // error properties will be added to a separate list if(status != 200) { return msresponse_addproperror(response, property, status); @@ -545,16 +553,17 @@ if(response->closing) { return 0; // close already in progress } + Multistatus *ms = response->multistatus; int ret = REQ_PROCEED; - WebdavOperation *op = response->multistatus->response.op; - if(webdav_op_propfiond_close_resource(op, res)) { + WebdavOperation *op = ms->response.op; + if(op->response_close(op, res)) { 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; + UcxAllocator *a = session_get_allocator(ms->sn); + WebdavPList *pl = ms->response.op->reqprops; while(pl) { sstr_t key = sstrcat_a( a, @@ -564,15 +573,40 @@ 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; + if(ms->proppatch) { + if(msresponse_addproperror(response, pl->property, 424)) { + ret = REQ_ABORTED; + break; + } + } else { + if(msresponse_addproperror(response, pl->property, 404)) { + ret = REQ_ABORTED; + break; + } } } pl = pl->next; } + if(ms->proppatch && response->errors) { + // a proppatch response must succeed entirely + // if we have a single error prop, move all props with status 200 + // to the error list + PropertyOkList *elm = response->plist_begin; + PropertyOkList *nextelm; + while(elm) { + if(msresponse_addproperror(response, elm->property, 424)) { + return 1; + } + nextelm = elm->next; + pool_free(response->multistatus->sn->pool, elm); + elm = nextelm; + } + response->plist_begin = NULL; + response->plist_end = NULL; + } + // we don't need the properties anymore ucx_map_free(response->properties);