Fri, 17 Jan 2020 19:37:24 +0100
readd namespace handling to msresponse_addproperty
--- 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;