readd namespace handling to msresponse_addproperty webdav

Fri, 17 Jan 2020 19:37:24 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 17 Jan 2020 19:37:24 +0100
branch
webdav
changeset 230
ca50e1ebdc4d
parent 229
73cb1c98ef7d
child 231
4714468b9b7e

readd namespace handling to msresponse_addproperty

src/server/public/webdav.h 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/webdav.c file | annotate | diff | comparison | revisions
--- a/src/server/public/webdav.h	Fri Jan 17 19:12:05 2020 +0100
+++ b/src/server/public/webdav.h	Fri Jan 17 19:37:24 2020 +0100
@@ -303,6 +303,12 @@
 
 size_t webdav_plist_size(WebdavPList *list);
 
+int webdav_nslist_add(
+        pool_handle_t *pool,
+        WebdavNSList **begin,
+        WebdavNSList **end,
+        WSNamespace *ns);
+
 WebdavPListIterator webdav_plist_iterator(WebdavPList **list);
 int webdav_plist_iterator_next(WebdavPListIterator *i, WebdavPList **cur);
 void webdav_plist_iterator_remove_current(WebdavPListIterator *i);
--- a/src/server/webdav/multistatus.c	Fri Jan 17 19:12:05 2020 +0100
+++ b/src/server/webdav/multistatus.c	Fri Jan 17 19:37:24 2020 +0100
@@ -58,11 +58,14 @@
 
 int multistatus_send(Multistatus *ms, SYS_NETFD net) {
     char buffer[MULTISTATUS_BUFFER_LENGTH];
+    // create a writer, that flushes the buffer when it is filled
     Writer writer;
     Writer *out = &writer;
     writer_init(out, net, buffer, MULTISTATUS_BUFFER_LENGTH);
     
     
+    
+    return 0;
 }
 
 WebdavResource * multistatus_addresource(
@@ -111,6 +114,29 @@
     return (WebdavResource*)res;
 }
 
+static int oklist_add(
+        pool_handle_t *pool,
+        PropertyOkList **begin,
+        PropertyOkList **end,
+        WebdavProperty *property,
+        WebdavNSList *nsdef)
+{
+    PropertyOkList *newelm = pool_malloc(pool, sizeof(PropertyOkList));
+    if(!newelm) {
+        return 1;
+    }
+    newelm->property = property;
+    newelm->nsdef = nsdef;
+    newelm->next = NULL;
+    if(*end) {
+        (*end)->next = newelm;
+    } else {
+        *begin = newelm;
+    }
+    *end = newelm;
+    return 0;
+}
+
 int msresponse_addproperty(
         WebdavResource *res,
         WebdavProperty *property,
@@ -159,12 +185,53 @@
         return msresponse_addproperror(response, property, status);
     }
     
+    // 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
+        int err = 0;
+        nslist = wsxml_get_required_namespaces(
+                response->multistatus->sn->pool,
+                property->value.node,
+                &err);
+        if(err) {
+            return 1; // OOM
+        }
+    } else if(property->vtype == WS_VALUE_XML_DATA) {
+        // xml data contains a list of all used namespaces
+        nslist = property->value.data->namespaces;
+    } // other value types don't contain xml namespaces
+    
+    WebdavNSList *nsdef_begin = NULL;
+    WebdavNSList *nsdef_end = NULL;
+    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_nslist_add(
+                    sn->pool,
+                    &nsdef_begin,
+                    &nsdef_end,
+                    nslist->namespace))
+            {
+                return 1; // OOM
+            }    
+        }
+        nslist = nslist->next;
+    }
+    
     // add property to the list
-    if(webdav_plist_add(
+    if(oklist_add(
             sn->pool,
             &response->plist_begin,
             &response->plist_end,
-            property))
+            property,
+            nsdef_begin))
     {
         return 1;
     }
--- a/src/server/webdav/multistatus.h	Fri Jan 17 19:12:05 2020 +0100
+++ b/src/server/webdav/multistatus.h	Fri Jan 17 19:37:24 2020 +0100
@@ -42,6 +42,7 @@
 typedef struct Multistatus Multistatus;
 typedef struct MSResponse MSResponse;
 
+typedef struct PropertyOkList PropertyOkList;
 typedef struct PropertyErrorList PropertyErrorList;
 
 /*
@@ -74,13 +75,19 @@
     
     PropertyErrorList *errors;
     
-    WebdavPList *plist_begin;
-    WebdavPList *plist_end;
+    PropertyOkList *plist_begin;
+    PropertyOkList *plist_end;
     
     MSResponse *next;
     WSBool closing;
 };
 
+struct PropertyOkList {
+    WebdavProperty *property;
+    WebdavNSList *nsdef;
+    PropertyOkList *next;
+};
+
 struct PropertyErrorList {
     PropertyErrorList *next;
     WebdavPList *begin;
--- a/src/server/webdav/webdav.c	Fri Jan 17 19:12:05 2020 +0100
+++ b/src/server/webdav/webdav.c	Fri Jan 17 19:37:24 2020 +0100
@@ -560,6 +560,33 @@
     }
 }
 
+int webdav_nslist_add(
+        pool_handle_t *pool,
+        WebdavNSList **begin,
+        WebdavNSList **end,
+        WSNamespace *ns)
+{
+    // same as webdav_plist_add but with different type
+    WebdavNSList *elm = pool_malloc(pool, sizeof(WebdavNSList));
+    if(!elm) {
+        return 1;
+    }
+    elm->prev = *end;
+    elm->next = NULL;
+    elm->namespace = ns;
+    
+    if(!*begin) {
+        *begin = elm;
+        *end = elm;
+        return 0;
+    }
+    
+    (*end)->next = elm;
+    *end = elm;
+    
+    return 0;
+}
+
 
 WSNamespace* webdav_dav_namespace(void) {
     return &dav_namespace;

mercurial