diff -r 527d0fde484e -r de23f8881e9f libidav/methods.c --- a/libidav/methods.c Sun Mar 06 15:19:50 2016 +0100 +++ b/libidav/methods.c Mon Mar 14 11:54:55 2016 +0100 @@ -962,10 +962,13 @@ CURLcode do_head_request(CURL *handle) { curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, "HEAD"); - curl_easy_setopt(handle, CURLOPT_PUT, 0L); curl_easy_setopt(handle, CURLOPT_UPLOAD, 0L); curl_easy_setopt(handle, CURLOPT_NOBODY, 1L); + // clear headers + struct curl_slist *headers = NULL; + curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, dummy_write); curl_easy_setopt(handle, CURLOPT_WRITEDATA, NULL); @@ -1006,3 +1009,115 @@ return ret; } + +UcxBuffer* create_lock_request() { + UcxBuffer *buf = ucx_buffer_new(NULL, 512, UCX_BUFFER_AUTOEXTEND); + sstr_t s; + + s = S("\n"); + ucx_buffer_write(s.ptr, 1, s.length, buf); + + s = S("\n" + "\n" + "\n" + "http://davutils.org/libidav/\n"); + ucx_buffer_write(s.ptr, 1, s.length, buf); + + s = S("\n"); + ucx_buffer_write(s.ptr, 1, s.length, buf); + + return buf; +} + +int parse_lock_response(DavSession *sn, UcxBuffer *response, LockDiscovery *lock) { + lock->locktoken = NULL; + lock->timeout = NULL; + + xmlDoc *doc = xmlReadMemory(response->space, response->size, NULL, NULL, 0); + if(!doc) { + sn->error = DAV_ERROR; + return -1; + } + + char *timeout = NULL; + char *locktoken = NULL; + + int ret = -1; + xmlNode *xml_root = xmlDocGetRootElement(doc); + DavBool lockdiscovery = 0; + if(xml_root) { + xmlNode *node = xml_root->children; + while(node) { + if(node->type == XML_ELEMENT_NODE) { + if(xstreq(node->name, "lockdiscovery")) { + node = node->children; + lockdiscovery = 1; + continue; + } + + if(lockdiscovery) { + if(xstreq(node->name, "timeout")) { + timeout = util_xml_get_text(node); + } else if(xstreq(node->name, "locktoken")) { + xmlNode *n = node->children; + while(n) { + if(xstreq(n->name, "href")) { + locktoken = util_xml_get_text(n); + break; + } + n = n->next; + } + } + } + } + node = node->next; + } + } + + if(timeout && locktoken) { + lock->timeout = strdup(timeout); + lock->locktoken = strdup(locktoken); + ret = 0; + } + + xmlFreeDoc(doc); + return ret; +} + +CURLcode do_lock_request(CURL *handle, UcxBuffer *request, UcxBuffer *response) { + curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, "LOCK"); + curl_easy_setopt(handle, CURLOPT_UPLOAD, 1L); + request->pos = 0; + + // clear headers + struct curl_slist *headers = NULL; + curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers); + + curl_easy_setopt(handle, CURLOPT_UPLOAD, 1); + curl_easy_setopt(handle, CURLOPT_READFUNCTION, ucx_buffer_read); + curl_easy_setopt(handle, CURLOPT_READDATA, request); + curl_easy_setopt(handle, CURLOPT_INFILESIZE, request->size); + + curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, ucx_buffer_write); + curl_easy_setopt(handle, CURLOPT_WRITEDATA, response); + + CURLcode ret = curl_easy_perform(handle); + + return ret; +} + +CURLcode do_unlock_request(CURL *handle, char *locktoken) { + curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, "UNLOCK"); + curl_easy_setopt(handle, CURLOPT_UPLOAD, 0L); + + // set lock-token header + sstr_t ltheader = ucx_sprintf("Lock-Token: <%s>", locktoken); + struct curl_slist *headers = curl_slist_append(NULL, ltheader.ptr); + curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers); + + CURLcode ret = curl_easy_perform(handle); + curl_slist_free_all(headers); + free(ltheader.ptr); + + return ret; +}