Thu, 16 Jan 2020 22:28:22 +0100
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;