remove nsdef from WebdavProperty webdav

Fri, 17 Jan 2020 17:42:10 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 17 Jan 2020 17:42:10 +0100
branch
webdav
changeset 227
3c23855f7b46
parent 226
49adcbd7d473
child 228
c0afce708b1d

remove nsdef from WebdavProperty

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/requestparser.c file | annotate | diff | comparison | revisions
src/server/webdav/requestparser.h file | annotate | diff | comparison | revisions
src/server/webdav/webdav.c file | annotate | diff | comparison | revisions
--- a/src/server/public/webdav.h	Thu Jan 16 22:28:22 2020 +0100
+++ b/src/server/public/webdav.h	Fri Jan 17 17:42:10 2020 +0100
@@ -100,8 +100,6 @@
 struct WebdavProperty {
     WSNamespace *namespace;
     
-    WebdavNSList *nsdef;
-    
     const char *name;
     
     char *lang;
@@ -295,6 +293,12 @@
  */
 int webdav_getdepth(Request *rq);
 
+int webdav_plist_add(
+        pool_handle_t *pool,
+        WebdavPList **begin,
+        WebdavPList **end,
+        WebdavProperty *prop);
+
 WebdavPList* webdav_plist_clone(pool_handle_t *pool, WebdavPList *list);
 
 size_t webdav_plist_size(WebdavPList *list);
@@ -313,12 +317,6 @@
         pool_handle_t *pool,
         char *value);
 
-int webdav_property_add_nsdef(
-        WebdavProperty *p, 
-        pool_handle_t *pool,
-        const char *prefix,
-        const char *nsuri);
-
 WebdavVFSProperties webdav_vfs_properties(
         WebdavPropfindRequest *rq,
         WSBool removefromlist,
--- a/src/server/test/webdav.c	Thu Jan 16 22:28:22 2020 +0100
+++ b/src/server/test/webdav.c	Fri Jan 17 17:42:10 2020 +0100
@@ -709,9 +709,41 @@
     WebdavProperty p[16];
     const char *names[] = {"a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9"};
     
+    WSNamespace ns1;
+    ZERO(&ns1, sizeof(WSNamespace));
+    WSNamespace ns2;
+    ZERO(&ns2, sizeof(WSNamespace));
+    ns1.prefix = (xmlChar*)"x1";
+    ns1.href = (xmlChar*)"http://example.com/test/";
+    ns2.prefix = (xmlChar*)"x2";
+    ns2.href = (xmlChar*)"http://example.com/test/";
+    
+    WebdavProperty dp1;
+    ZERO(&dp1, sizeof(WebdavProperty));
+    dp1.name = "dup";
+    dp1.namespace = &ns1;
+    dp1.value.text.str = "Hello";
+    dp1.value.text.length = 5;
+    dp1.vtype = WS_VALUE_TEXT;
+    
+    WebdavProperty dp2;
+    ZERO(&dp2, sizeof(WebdavProperty));
+    dp2.name = "dup";
+    dp2.namespace = &ns1;
+    dp2.value.text.str = "Hello";
+    dp2.value.text.length = 5;
+    dp2.vtype = WS_VALUE_TEXT;
+    
+    WebdavProperty dp3;
+    ZERO(&dp3, sizeof(WebdavProperty));
+    dp3.name = "dup";
+    dp3.namespace = &ns2;
+    dp3.value.text.str = "Hello";
+    dp3.value.text.length = 5;
+    dp3.vtype = WS_VALUE_TEXT;
+    
     // init test data
     p1.namespace = webdav_dav_namespace();
-    p1.nsdef = NULL;
     p1.lang = NULL;
     p1.name = "test1";
     p1.value.data = NULL;
@@ -719,7 +751,6 @@
     
     for(int i=0;i<8;i++) {
         p[i].namespace = webdav_dav_namespace();
-        p[i].nsdef = NULL;
         p[i].name = names[i];
         p[i].lang = NULL;
         p[i].value.node = NULL;
@@ -751,6 +782,26 @@
     UCX_TEST_ASSERT(ucx_list_size(r->errors->next->begin) == 4, "403 list size != 4");
     UCX_TEST_ASSERT(ucx_list_size(r->errors->next->next->begin) == 1, "500 list size != 1");
     
+    // new resource for prop duplication tests
+    r = (MSResponse*)ms->response.addresource((WebdavResponse*)ms, "/test");
+    UCX_TEST_ASSERT(r, "cannot create second response");
+    
+    r->resource.addproperty((WebdavResource*)r, &dp1, 200);
+    UCX_TEST_ASSERT(r->plist_begin, "adding dp1 failed");
+    UCX_TEST_ASSERT(!r->plist_begin->next, "dp1: list size not 1");
+    
+    r->resource.addproperty((WebdavResource*)r, &dp2, 200);
+    UCX_TEST_ASSERT(!r->plist_begin->next, "dp1: adding dp2 should not work");
+    
+    r->resource.addproperty((WebdavResource*)r, &dp2, 404);
+    UCX_TEST_ASSERT(!r->plist_begin->next, "dp1: adding dp2 with different status should not work (1)");
+    if(r->errors) {
+        UCX_TEST_ASSERT(ucx_list_size(r->errors->begin) == 0, "dp1: error list not empty");
+    }
+    
+    r->resource.addproperty((WebdavResource*)r, &dp3, 200);
+    UCX_TEST_ASSERT(!r->plist_begin->next, "dp1: adding dp3 should not work");
+    
     UCX_TEST_END;
 }
 
--- a/src/server/webdav/multistatus.c	Thu Jan 16 22:28:22 2020 +0100
+++ b/src/server/webdav/multistatus.c	Fri Jan 17 17:42:10 2020 +0100
@@ -117,6 +117,7 @@
         int status)
 {
     MSResponse *response = (MSResponse*)res;
+    Session *sn = response->multistatus->sn;
     if(response->resource.isclosed) {
         log_ereport(
                 LOG_WARN,
@@ -135,18 +136,9 @@
                 property->name);
         return 1;
     }
-    if(property->nsdef) {
-        // error: nsdef MUST be NULL, only fill nsdef in this func
-        log_ereport(
-                LOG_FAILURE,
-                "%s",
-                "webdav: property '%s': nsdef must be null",
-                property->name);
-        return 1;
-    }
     
     // check if the property was already added to the resource
-    UcxAllocator *a = session_get_allocator(response->multistatus->sn);
+    UcxAllocator *a = session_get_allocator(sn);
     sstr_t key = sstrcat_a(
             a,
             3,
@@ -162,97 +154,20 @@
     }
     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) {
-        char *ns = ucx_map_cstr_get(
-                response->multistatus->namespaces,
-                (const char*)property->namespace->prefix);
-        if(!ns) {
-            // prefix is not in use -> we can add the namespace to the ns map
-            int err = ucx_map_cstr_put(
-                    response->multistatus->namespaces,
-                    (const char*)property->namespace->prefix,
-                    property->namespace->href);
-            if(err) {
-                return 1; // OOM
-            }
-        } else if(strcmp((char*)property->namespace->href, ns)) {
-            // global namespace != local namespace
-            // therefore we need a namespace definition in this element
-            
-            if(webdav_property_add_nsdef(
-                    property,
-                    response->multistatus->sn->pool,
-                    (const char*)property->namespace->prefix,
-                    (const char*)property->namespace->href))
-            {
-                return 1; // OOM
-            }          
-        }
-    }
-    
     // error properties will be added to a separate list
     if(status != 200) { 
         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;
-        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
-        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*)nslist->namespace->href))
-            {
-                return 1; // OOM
-            }    
-        }
-        nslist = nslist->next;
-    }
-    
     // add property to the list
-    WebdavPList *listelm = pool_malloc(
-            response->multistatus->sn->pool,
-            sizeof(WebdavPList));
-    if(!listelm) {
+    if(webdav_plist_add(
+            sn->pool,
+            &response->plist_begin,
+            &response->plist_end,
+            property))
+    {
         return 1;
     }
-    
-    listelm->property = property;
-    listelm->next = NULL;
-    
-    if(response->plist_end) {
-        response->plist_end->next = listelm;
-    } else {
-        response->plist_begin = listelm;
-    }
-    response->plist_end = listelm;
     return 0;
 }
 
--- a/src/server/webdav/multistatus.h	Thu Jan 16 22:28:22 2020 +0100
+++ b/src/server/webdav/multistatus.h	Fri Jan 17 17:42:10 2020 +0100
@@ -77,8 +77,6 @@
     WebdavPList *plist_begin;
     WebdavPList *plist_end;
     
-    UcxMap *nsdef;
-    
     MSResponse *next;
     WSBool closing;
 };
--- a/src/server/webdav/requestparser.c	Thu Jan 16 22:28:22 2020 +0100
+++ b/src/server/webdav/requestparser.c	Fri Jan 17 17:42:10 2020 +0100
@@ -38,33 +38,6 @@
 
 #define xstreq(a, b) !strcmp((const char*)a, (const char*)b)
 
-// TODO: make function public
-int proplist_add(
-        pool_handle_t *pool,
-        WebdavPList **begin,
-        WebdavPList **end,
-        WebdavProperty *prop)
-{
-    WebdavPList *elm = pool_malloc(pool, sizeof(WebdavPList));
-    if(!elm) {
-        return 1;
-    }
-    elm->prev = *end;
-    elm->next = NULL;
-    elm->property = prop;
-    
-    if(!*begin) {
-        *begin = elm;
-        *end = elm;
-        return 0;
-    }
-    
-    (*end)->next = elm;
-    *end = elm;
-    
-    return 0;
-}
-
 void proplist_free(pool_handle_t *pool, WebdavPList *list) {
     while(list) {
         WebdavPList *next = list->next;
@@ -134,7 +107,7 @@
                 prop->vtype = WS_VALUE_XML_NODE;
             }
             if(prop) {
-                if(proplist_add(sn->pool, plist_begin, plist_end, prop)) {
+                if(webdav_plist_add(sn->pool, plist_begin, plist_end, prop)) {
                     *error = proppatch ?
                         PROPPATCH_PARSER_OOM : PROPFIND_PARSER_OOM;
                 }
--- a/src/server/webdav/requestparser.h	Thu Jan 16 22:28:22 2020 +0100
+++ b/src/server/webdav/requestparser.h	Fri Jan 17 17:42:10 2020 +0100
@@ -59,12 +59,7 @@
 #define LOCK_PARSER_UNKNOWN_ELEMENT          3
 #define LOCK_PARSER_OOM                      4
 #define LOCK_PARSER_ERROR                    5
-    
-int proplist_add(
-        pool_handle_t *pool,
-        WebdavPList **begin,
-        WebdavPList **end,
-        WebdavProperty *prop);
+
 
 WebdavProperty* prop_create(
         pool_handle_t *pool,
--- a/src/server/webdav/webdav.c	Thu Jan 16 22:28:22 2020 +0100
+++ b/src/server/webdav/webdav.c	Fri Jan 17 17:42:10 2020 +0100
@@ -460,6 +460,32 @@
     return depth;
 }
 
+int webdav_plist_add(
+        pool_handle_t *pool,
+        WebdavPList **begin,
+        WebdavPList **end,
+        WebdavProperty *prop)
+{
+    WebdavPList *elm = pool_malloc(pool, sizeof(WebdavPList));
+    if(!elm) {
+        return 1;
+    }
+    elm->prev = *end;
+    elm->next = NULL;
+    elm->property = prop;
+    
+    if(!*begin) {
+        *begin = elm;
+        *end = elm;
+        return 0;
+    }
+    
+    (*end)->next = elm;
+    *end = elm;
+    
+    return 0;
+}
+
 WebdavPList* webdav_plist_clone(pool_handle_t *pool, WebdavPList *list) {
     WebdavPList *new_list = NULL;     // start of the new list
     WebdavPList *new_list_end = NULL; // end of the new list
@@ -573,44 +599,6 @@
     return 0;
 }
 
-int webdav_property_add_nsdef(
-        WebdavProperty *property, 
-        pool_handle_t *pool,
-        const char *prefix,
-        const char *nsuri)
-{
-    // because we're using a memory pool, we don't free in case stuff in
-    // case of an error (OOM) - stuff will be freed by destroyinig the pool
-    
-    WebdavNSList *new_def = pool_malloc(pool, sizeof(WebdavNSList));
-    if(!new_def) {
-        return 1;
-    }
-    WSNamespace *new_ns = pool_malloc(pool, sizeof(WSNamespace));
-    if(!new_ns) {
-        return 1;
-    }
-    ZERO(new_ns, sizeof(WSNamespace));
-    
-    new_ns->prefix = (xmlChar*)pool_strdup(pool, prefix);
-    new_ns->href = (xmlChar*)pool_strdup(pool, nsuri);
-    if(!new_ns->prefix || !new_ns->href) {
-        return 1;
-    }
-    
-    new_def->namespace = new_ns;
-    new_def->prev = NULL;
-    new_def->next = NULL;
-    
-    if(property->nsdef) {
-        property->nsdef->prev = new_def;
-        new_def->next = property->nsdef;
-    }
-    property->nsdef = new_def;
-    
-    return 0;
-}
-
 WebdavVFSProperties webdav_vfs_properties(
         WebdavPropfindRequest *rq,
         WSBool removefromlist,

mercurial