msresponse_addproperty: add support for xmlNode property values and add check to make sure, properties are only added once webdav

Thu, 16 Jan 2020 22:28:22 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 16 Jan 2020 22:28:22 +0100
branch
webdav
changeset 226
49adcbd7d473
parent 225
e4f3e1433098
child 227
3c23855f7b46

msresponse_addproperty: add support for xmlNode property values and add check to make sure, properties are only added once

src/server/webdav/multistatus.c file | annotate | diff | comparison | revisions
src/server/webdav/multistatus.h file | annotate | diff | comparison | revisions
--- a/src/server/webdav/multistatus.c	Thu Jan 16 21:31:16 2020 +0100
+++ b/src/server/webdav/multistatus.c	Thu Jan 16 22:28:22 2020 +0100
@@ -78,11 +78,19 @@
     
     // set href
     res->resource.href = pool_strdup(ms->sn->pool, path);
+    if(!res->resource.href) {
+        return NULL;
+    }
     
     // add resource funcs
     res->resource.addproperty = msresponse_addproperty;
     res->resource.close = msresponse_close;
     
+    res->properties = ucx_map_new_a(session_get_allocator(ms->sn), 32);
+    if(!res->properties) {
+        return NULL;
+    }
+    
     res->multistatus = ms;
     res->errors = NULL;
     res->resource.isclosed = 0;
@@ -137,6 +145,23 @@
         return 1;
     }
     
+    // check if the property was already added to the resource
+    UcxAllocator *a = session_get_allocator(response->multistatus->sn);
+    sstr_t key = sstrcat_a(
+            a,
+            3,
+            sstr((char*)property->namespace->href),
+            S("\0"),
+            sstr((char*)property->name));
+    if(ucx_map_sstr_get(response->properties, key)) {
+        a->free(a->pool, key.ptr);
+        return 0;
+    }
+    if(ucx_map_sstr_put(response->properties, key, property)) {
+        return 1; // OOM
+    }
+    a->free(a->pool, key.ptr);
+    
     // add namespace of this property to the namespace map
     // the namespace map will be used for global namespace definitions
     if(property->namespace->prefix) {
@@ -173,34 +198,43 @@
     }
     
     // add all namespaces used by this property to the nsdef list
+    WebdavNSList *nslist = NULL;
     if(property->vtype == WS_VALUE_XML_NODE) {
         // iterate over xml tree and collect all namespaces
-        
-        // TODO: implement
+        int err = 0;
+        WebdavNSList *nsdef = wsxml_get_required_namespaces(
+                response->multistatus->sn->pool,
+                property->value.node,
+                &err);
+        if(err) {
+            return 1; // OOM
+        }
+        nslist = nsdef;
     } else if(property->vtype == WS_VALUE_XML_DATA) {
         // xml data contains a list of all used namespaces
-        WebdavNSList *nslist = property->value.data->namespaces;
-        while(nslist) {
-            // only add the namespace to the definitions list, if it isn't
-            // property namespace, because the prop ns is already added
-            // to the element's def list or global definitions list
-            if(strcmp(
+        nslist = property->value.data->namespaces;
+    } // other value types don't contain xml namespaces
+    
+    while(nslist) {
+        // only add the namespace to the definitions list, if it isn't a
+        // property namespace, because the prop ns is already added
+        // to the element's def list or global definitions list
+        if(strcmp(
+                (const char*)nslist->namespace->prefix,
+                (const char*)property->namespace->prefix))
+        {
+            // ns-prefix != property-prefix -> add ns to nsdef
+            if(webdav_property_add_nsdef(
+                    property,
+                    response->multistatus->sn->pool,
                     (const char*)nslist->namespace->prefix,
-                    (const char*)property->namespace->prefix))
+                    (const char*)nslist->namespace->href))
             {
-                // ns-prefix != property-prefix -> add ns to nsdef
-                if(webdav_property_add_nsdef(
-                        property,
-                        response->multistatus->sn->pool,
-                        (const char*)nslist->namespace->prefix,
-                        (const char*)nslist->namespace->href))
-                {
-                    return 1; // OOM
-                }    
-            }
-            nslist = nslist->next;
+                return 1; // OOM
+            }    
         }
-    } // other value types don't contain xml namespaces
+        nslist = nslist->next;
+    }
     
     // add property to the list
     WebdavPList *listelm = pool_malloc(
@@ -288,6 +322,9 @@
         ret = REQ_ABORTED;
     }
     
+    // we don't need the properties anymore
+    ucx_map_free(response->properties);
+    
     response->resource.isclosed = TRUE;
     response->closing = FALSE;
     return ret;
--- a/src/server/webdav/multistatus.h	Thu Jan 16 21:31:16 2020 +0100
+++ b/src/server/webdav/multistatus.h	Thu Jan 16 22:28:22 2020 +0100
@@ -70,6 +70,8 @@
     WebdavResource resource;
     Multistatus *multistatus;
     
+    UcxMap *properties;
+    
     PropertyErrorList *errors;
     
     WebdavPList *plist_begin;

mercurial