diff -r 4adad7faf452 -r c337a7ac82a8 src/server/webdav/webdav.c --- a/src/server/webdav/webdav.c Sat Jan 25 21:37:38 2020 +0100 +++ b/src/server/webdav/webdav.c Sun Jan 26 10:13:11 2020 +0100 @@ -297,6 +297,9 @@ ret = REQ_ABORTED; } + // cleanup + xmlFreeDoc(propfind->doc); + return ret; } @@ -363,7 +366,81 @@ int webdav_proppatch(pblock *pb, Session *sn, Request *rq) { - return REQ_ABORTED; + char *expect = pblock_findkeyval(pb_key_expect, rq->headers); + if(expect) { + if(!strcasecmp(expect, "100-continue")) { + if(http_send_continue(sn)) { + return REQ_ABORTED; + } + } + } + + UcxBuffer *reqbody = rqbody2buffer(sn, rq); + if(!reqbody) { + return REQ_ABORTED; + } + + int error = 0; + WebdavProppatchRequest *proppatch = proppatch_parse( + sn, + rq, + reqbody->space, + reqbody->size, + &error); + ucx_buffer_free(reqbody); + if(!proppatch) { + switch(error) { + // TODO: handle all errors + default: return REQ_ABORTED; + } + } + + WebdavBackend *dav = rq->davCollection ? + rq->davCollection : &default_backend; + + // requested uri and path + char *path = pblock_findkeyval(pb_key_path, rq->vars); + char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb); + + // The multistatus response object contains responses for all + // requested resources. At the end the Multistatus object will be + // serialized to xml + Multistatus *ms = multistatus_response(sn, rq); + if(!ms) { + return REQ_ABORTED; + } + ms->proppatch = TRUE; + + // WebdavResponse is the public interface used by Backends + // for adding resources to the response + WebdavResponse *response = (WebdavResponse*)ms; + + WebdavOperation *op = webdav_create_proppatch_operation( + sn, + rq, + dav, + proppatch, + response); + + int ret = REQ_PROCEED; + + // Execute proppatch + if(webdav_op_proppatch(op, uri, path)) { + ret = REQ_ABORTED; + } + + // send response + if(ret == REQ_PROCEED && multistatus_send(ms, sn->csd)) { + ret = REQ_ABORTED; + // TODO: log error + } else { + // TODO: error response + } + + // cleanup + xmlFreeDoc(proppatch->doc); + + return ret; } int webdav_mkcol(pblock *pb, Session *sn, Request *rq) {