handle missing properties in multistatus.c webdav

Sun, 19 Jan 2020 10:03:31 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 19 Jan 2020 10:03:31 +0100
branch
webdav
changeset 237
ee1680ef1ef2
parent 236
e81d3e517b57
child 238
e820d433f405

handle missing properties in multistatus.c

src/server/public/webdav.h file | annotate | diff | comparison | revisions
src/server/test/webdav.c file | annotate | diff | comparison | revisions
src/server/webdav/multistatus.c file | annotate | diff | comparison | revisions
src/server/webdav/multistatus.h file | annotate | diff | comparison | revisions
src/server/webdav/operation.c file | annotate | diff | comparison | revisions
src/server/webdav/operation.h file | annotate | diff | comparison | revisions
src/server/webdav/webdav.c file | annotate | diff | comparison | revisions
--- 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);
 
--- 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);
 }
--- 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);
     
--- 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: <href> null-byte <name>
+     * 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;
 };
 
--- 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;
     
--- 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);
 
--- 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;

mercurial