src/server/webdav/multistatus.c

branch
webdav
changeset 239
d5031c30022c
parent 238
e820d433f405
child 241
4adad7faf452
--- 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);
     

mercurial