diff -r 99a34860c105 -r d938228c382e src/server/webdav/multistatus.c --- a/src/server/webdav/multistatus.c Wed Nov 02 19:19:01 2022 +0100 +++ b/src/server/webdav/multistatus.c Sun Nov 06 15:53:32 2022 +0100 @@ -33,7 +33,8 @@ #include "../daemon/protocol.h" #include "../util/platform.h" -#include +#include +#include #include "multistatus.h" @@ -51,48 +52,48 @@ ms->response.addresource = multistatus_addresource; ms->sn = sn; ms->rq = rq; - ms->namespaces = ucx_map_new_a(session_get_allocator(ms->sn), 8); + ms->namespaces = cxHashMapCreate(pool_allocator(sn->pool), 8); ms->proppatch = FALSE; if(!ms->namespaces) { return NULL; } - if(ucx_map_cstr_put(ms->namespaces, "D", webdav_dav_namespace())) { + if(cxMapPut(ms->namespaces, cx_hash_key_str("D"), webdav_dav_namespace())) { return NULL; } return ms; } static int send_xml_root(Multistatus *ms, Writer *out) { - writer_puts(out, S("\n" - "\n" + "namespaces); - WSNamespace *ns; - UCX_MAP_FOREACH(key, ns, i) { - writer_puts(out, S(" xmlns:")); - writer_put(out, key.data, key.len); - writer_puts(out, S("=\"")); - writer_puts(out, sstr((char*)ns->href)); - writer_puts(out, S("\"")); + CxIterator i = cxMapIterator(ms->namespaces); + cx_foreach(CxMapEntry*, entry, i) { + WSNamespace *ns = entry->value; + writer_put_lit(out, " xmlns:"); + writer_put (out, entry->key->data.str, entry->key->len); + writer_put_lit(out, "=\""); + writer_put_str(out, (char*)ns->href); + writer_put_lit(out, "\""); } - writer_puts(out, S(">\n")); + writer_put_lit(out, ">\n"); return out->error; } static void send_nsdef(WSNamespace *ns, Writer *out) { - writer_puts(out, S(" xmlns:")); - writer_puts(out, sstr((char*)ns->prefix)); - writer_puts(out, S("=\"")); - writer_puts(out, sstr((char*)ns->href)); - writer_putc(out, '\"'); + writer_put_lit(out, " xmlns:"); + writer_put_str(out, (char*)ns->prefix); + writer_put_lit(out, "=\""); + writer_put_str(out, (char*)ns->href); + writer_putc (out, '\"'); } -static void send_string_escaped(Writer *out, sstr_t str) { +static void send_string_escaped(Writer *out, cxmutstr str) { char *begin = str.ptr; char *end = begin; char *escape = NULL; @@ -150,10 +151,10 @@ Writer *out) { // write: "namespace->prefix)); - writer_putc(out, ':'); - writer_puts(out, sstr((char*)property->name)); + writer_putc (out, '<'); + writer_put_str(out, (char*)property->namespace->prefix); + writer_putc (out, ':'); + writer_put_str(out, (char*)property->name); // send additional namespace definitions required for the value WebdavNSList *def = nsdef; @@ -164,9 +165,9 @@ // send xml lang attribute if(property->lang) { - writer_puts(out, S(" xml:lang=\"")); - writer_puts(out, sstr((char*)property->lang)); - writer_putc(out, '\"'); + writer_put_lit(out, " xml:lang=\""); + writer_put_str(out, (char*)property->lang); + writer_putc (out, '\"'); } // end property tag and write content @@ -202,55 +203,54 @@ } // end tag - writer_puts(out, S("namespace->prefix)); - writer_putc(out, ':'); - writer_puts(out, sstr((char*)property->name)); - writer_putc(out, '>'); + writer_put_lit(out, "namespace->prefix); + writer_putc (out, ':'); + writer_put_str(out, (char*)property->name); + writer_putc (out, '>'); } else { - writer_puts(out, S("/>")); + writer_put_lit(out, "/>"); } return out->error; } static int send_response_tag(Multistatus *ms, MSResponse *rp, Writer *out) { - writer_puts(out, S(" \n" - " ")); - //writer_puts(out, sstr(rp->resource.href)); - send_string_escaped(out, sstr(rp->resource.href)); - writer_puts(out, S("\n")); + writer_put_lit(out, " \n" + " "); + send_string_escaped(out, cx_mutstr(rp->resource.href)); + writer_put_lit(out, "\n"); WSBool writeContent = ms->proppatch ? FALSE : TRUE; if(rp->plist_begin) { - writer_puts(out, S(" \n" - " \n")); + writer_put_lit(out, " \n" + " \n"); // send properties PropertyOkList *p = rp->plist_begin; while(p) { - writer_puts(out, S(" ")); + writer_put_lit(out, " "); if(send_property(ms, p->property, p->nsdef, writeContent, out)) { return out->error; } - writer_puts(out, S("\n")); + writer_put_lit(out, "\n"); p = p->next; } - writer_puts(out, S(" \n" - " HTTP/1.1 200 OK\n" - " \n")); + writer_put_lit(out, " \n" + " HTTP/1.1 200 OK\n" + " \n"); } // send error properties PropertyErrorList *error = rp->errors; while(error) { - writer_puts(out, S(" \n" - " \n")); + writer_put_lit(out, " \n" + " \n"); WebdavPList *errprop = error->begin; while(errprop) { - writer_puts(out, S(" ")); + writer_put_lit(out, " "); if(send_property(ms, errprop->property, NULL, FALSE, out)) { return out->error; } @@ -267,24 +267,24 @@ statuscode[3] = ' '; sclen = 4; } - writer_puts(out, S(" \n" - " HTTP/1.1 ")); + writer_put_lit(out, " \n" + " HTTP/1.1 "); writer_put(out, statuscode, sclen); const char *status_msg = protocol_status_message(error->status); if(status_msg) { writer_put(out, status_msg, strlen(status_msg)); } else { - writer_puts(out, S("Server Error")); + writer_put_lit(out, "Server Error"); } - writer_puts(out, S("\n" - " \n")); + writer_put_lit(out, "\n" + " \n"); error = error->next; } // end response tag - writer_puts(out, S(" \n")); + writer_put_lit(out, " \n"); return out->error; } @@ -322,7 +322,7 @@ } // end multistatus - writer_puts(out, S("\n")); + writer_put_lit(out, "\n"); //printf("\n\n"); //fflush(stdout); @@ -355,7 +355,7 @@ res->resource.addproperty = msresponse_addproperty; res->resource.close = msresponse_close; - res->properties = ucx_map_new_a(session_get_allocator(ms->sn), 32); + res->properties = cxHashMapCreate(pool_allocator(ms->sn->pool), 32); if(!res->properties) { return NULL; } @@ -414,7 +414,6 @@ int statuscode) { pool_handle_t *pool = response->multistatus->sn->pool; - UcxAllocator *a = session_get_allocator(response->multistatus->sn); response->resource.err++; @@ -459,6 +458,15 @@ return 0; } +static CxHashKey ms_property_key( + CxAllocator *a, + const xmlChar *href, + const char *property_name) +{ + cxmutstr key_data = cx_strcat_a(a, 3, cx_str((const char*)href), (cxstring){ "\0", 1 }, cx_str(property_name)); + return cx_hash_key_bytes((unsigned char*)key_data.ptr, key_data.length); +} + int msresponse_addproperty( WebdavResource *res, WebdavProperty *property, @@ -486,21 +494,16 @@ } // check if the property was already added to the resource - UcxAllocator *a = session_get_allocator(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); + CxAllocator *a = pool_allocator(sn->pool); + CxHashKey key = ms_property_key(a, property->namespace->href, property->name); + if(cxMapGet(response->properties, key)) { + cxFree(a, key.data.bytes); return 0; } - if(ucx_map_sstr_put(response->properties, key, property)) { + if(cxMapPut(response->properties, key, property)) { return 1; // OOM } - a->free(a->pool, key.ptr); + cxFree(a, key.data.bytes); // list of namespace definitions for this property WebdavNSList *nsdef_begin = NULL; @@ -509,14 +512,14 @@ // add namespace of this property to the namespace map // the namespace map will be used for global namespace definitions if(property->namespace->prefix) { - WSNamespace *ns = ucx_map_cstr_get( + WSNamespace *ns = cxMapGet( response->multistatus->namespaces, - (const char*)property->namespace->prefix); + cx_hash_key_str((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( + int err = cxMapPut( response->multistatus->namespaces, - (const char*)property->namespace->prefix, + cx_hash_key_str((const char*)property->namespace->prefix), property->namespace); if(err) { return 1; // OOM @@ -622,16 +625,11 @@ } // add missing properties with status code 404 - UcxAllocator *a = session_get_allocator(ms->sn); + CxAllocator *a = pool_allocator(ms->sn->pool); WebdavPList *pl = ms->response.op->reqprops; while(pl) { - sstr_t key = sstrcat_a( - a, - 3, - sstr((char*)pl->property->namespace->href), - S("\0"), - sstr((char*)pl->property->name)); - if(!ucx_map_sstr_get(response->properties, key)) { + CxHashKey key = ms_property_key(a, pl->property->namespace->href, pl->property->name); + if(!cxMapGet(response->properties, key)) { // property was not added to this response if(ms->proppatch) { if(msresponse_addproperty(res, pl->property, 424)) { @@ -668,7 +666,7 @@ } // we don't need the properties anymore - ucx_map_free(response->properties); + cxMapDestroy(response->properties); response->resource.isclosed = TRUE; return ret;