libidav/resource.c

changeset 43
03076907b58a
parent 42
6518b035a9df
child 70
88092b88ec00
equal deleted inserted replaced
42:6518b035a9df 43:03076907b58a
30 #include <stdlib.h> 30 #include <stdlib.h>
31 #include <string.h> 31 #include <string.h>
32 #include <libxml/tree.h> 32 #include <libxml/tree.h>
33 33
34 #include "utils.h" 34 #include "utils.h"
35 #include "session.h"
35 #include "methods.h" 36 #include "methods.h"
36 #include "davql.h" 37 #include "davql.h"
37 #include "crypto.h" 38 #include "crypto.h"
38 #include "ucx/buffer.h" 39 #include "ucx/buffer.h"
39 #include "ucx/utils.h" 40 #include "ucx/utils.h"
41 #include "resource.h" 42 #include "resource.h"
42 43
43 #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b) 44 #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b)
44 45
45 DavResource* dav_resource_new(DavSession *sn, char *path) { 46 DavResource* dav_resource_new(DavSession *sn, char *path) {
46 char *url = util_path_to_url(sn, path); 47 //char *href = util_url_path(url);
47 char *href = util_url_path(url); 48 //DavResource *res = dav_resource_new_href(sn, href);
48 DavResource *res = dav_resource_new_href(sn, href); 49 char *parent = util_parent_path(path);
49 free(url); 50 char *name = util_resource_name(path);
51 char *href = dav_session_create_plain_href(sn, path);
52
53 DavResource *res = dav_resource_new_full(sn, parent, name, href);
54 free(parent);
50 return res; 55 return res;
51 } 56 }
52 57
53 DavResource* dav_resource_new_child(DavSession *sn, DavResource *parent, char *name) { 58 DavResource* dav_resource_new_child(DavSession *sn, DavResource *parent, char *name) {
54 char *path = util_concat_path(parent->path, name); 59 char *path = util_concat_path(parent->path, name);
55 DavResource *res = dav_resource_new(sn, path); 60 char *href = dav_session_create_plain_href(sn, path);
61 DavResource *res = dav_resource_new_full(sn, parent->path, name, href);
56 free(path); 62 free(path);
57 return res; 63 return res;
58 } 64 }
59 65
60 66
67 73
68 // initialize resource data 74 // initialize resource data
69 res->data = resource_data_new(sn); 75 res->data = resource_data_new(sn);
70 76
71 return res; 77 return res;
78 }
79
80 DavResource* dav_resource_new_full(DavSession *sn, char *parent_path, char *name, char *href) {
81 DavResource *res = ucx_mempool_calloc(sn->mp, 1, sizeof(DavResource));
82 res->session = sn;
83
84 // set name, path and href
85 sstr_t n = sstr(name);
86 res->name = sstrdup_a(sn->mp->allocator, n).ptr;
87 if(n.ptr[n.length-1] == '/') {
88 res->name[n.length-1] = '\0';
89 }
90
91 char *path = util_concat_path(parent_path, name);
92 res->path = dav_session_strdup(sn, path);
93 free(path);
94
95 res->href = href;
96
97 // initialize resource data
98 res->data = resource_data_new(sn);
99
100 // cache href/path
101 if(href) {
102 dav_session_cache_path(sn, sstr(path), sstr(href));
103 }
104
105 return res;
106 }
107
108 void dav_resource_free(DavResource *res) {
109 DavSession *sn = res->session;
110
111 dav_session_free(sn, res->name);
112 dav_session_free(sn, res->path);
113 if(res->href) {
114 dav_session_free(sn, res->href);
115 }
116
117 DavResourceData *data = res->data;
118 UcxMapIterator i = ucx_map_iterator(data->properties);
119 UcxKey key;
120 char *property;
121 UCX_MAP_FOREACH(key, property, i) {
122 dav_session_free(sn, property);
123 }
124 ucx_map_free(data->properties);
125
126 UCX_FOREACH(elm, data->set) {
127 DavProperty *p = elm->data;
128 dav_session_free(sn, p->ns->name);
129 if(p->ns->prefix) {
130 dav_session_free(sn, p->ns->prefix);
131 }
132 dav_session_free(sn, p->ns);
133
134 dav_session_free(sn, p->name);
135 dav_session_free(sn, p->value);
136 dav_session_free(sn, p);
137 }
138
139 UCX_FOREACH(elm, data->remove) {
140 DavProperty *p = elm->data;
141 dav_session_free(sn, p->ns->name);
142 if(p->ns->prefix) {
143 dav_session_free(sn, p->ns->prefix);
144 }
145 dav_session_free(sn, p->ns);
146
147 dav_session_free(sn, p->name);
148 dav_session_free(sn, p->value);
149 dav_session_free(sn, p);
150 }
151
152 if(!data->read && data->content) {
153 dav_session_free(sn, data->content);
154 }
155 dav_session_free(sn, data);
156
157 dav_session_free(sn, res);
158 }
159
160 void dav_resource_free_all(DavResource *res) {
161 DavResource *child = res->children;
162 dav_resource_free(res);
163 while(child) {
164 DavResource *next = child->next;
165 dav_resource_free_all(child);
166 child = next;
167 }
168 }
169
170 void resource_set_href(DavResource *res, sstr_t href) {
171 res->href = sstrdup_a(res->session->mp->allocator, href).ptr;
72 } 172 }
73 173
74 void resource_set_info(DavResource *res, char *href_str) { 174 void resource_set_info(DavResource *res, char *href_str) {
75 char *url_str = NULL; 175 char *url_str = NULL;
76 curl_easy_getinfo(res->session->handle, CURLINFO_EFFECTIVE_URL, &url_str); 176 curl_easy_getinfo(res->session->handle, CURLINFO_EFFECTIVE_URL, &url_str);
108 data->remove = NULL; 208 data->remove = NULL;
109 data->content = NULL; 209 data->content = NULL;
110 data->read = NULL; 210 data->read = NULL;
111 data->length = 0; 211 data->length = 0;
112 return data; 212 return data;
213 }
214
215 char* dav_resource_get_href(DavResource *resource) {
216 if(!resource->href) {
217 resource->href = dav_session_get_href(
218 resource->session,
219 resource->path);
220 }
221 return resource->href;
113 } 222 }
114 223
115 void resource_add_property(DavResource *res, char *ns, char *name, char *val) { 224 void resource_add_property(DavResource *res, char *ns, char *name, char *val) {
116 if(!val) { 225 if(!val) {
117 return; 226 return;
207 DavResourceData *data = res->data; 316 DavResourceData *data = res->data;
208 317
209 DavProperty *property = dav_session_malloc( 318 DavProperty *property = dav_session_malloc(
210 res->session, 319 res->session,
211 sizeof(DavProperty)); 320 sizeof(DavProperty));
321 property->name = dav_session_strdup(res->session, name);
322 property->value = dav_session_strdup(res->session, value);
323
324 DavNamespace *namespace = dav_session_malloc(
325 res->session,
326 sizeof(DavNamespace));
327 namespace->prefix = NULL;
328 namespace->name = dav_session_strdup(res->session, ns);
329 property->ns = namespace;
330
331 data->set = ucx_list_append_a(a, data->set, property);
332 }
333
334 void dav_remove_property(DavResource *res, char *name) {
335 char *pns;
336 char *pname;
337 dav_get_property_namespace(res->session->context, name, &pns, &pname);
338 dav_remove_property_ns(res, pns, pname);
339 }
340
341 void dav_remove_property_ns(DavResource *res, char *ns, char *name) {
342 DavResourceData *data = res->data;
343 UcxAllocator *a = res->session->mp->allocator;
344
345 DavProperty *property = dav_session_malloc(
346 res->session,
347 sizeof(DavProperty));
212 property->name = sstrdup_a(a, sstr(name)).ptr; 348 property->name = sstrdup_a(a, sstr(name)).ptr;
213 property->value = sstrdup_a(a, sstr(value)).ptr; 349 property->value = NULL;
214 350
215 DavNamespace *namespace = dav_session_malloc( 351 DavNamespace *namespace = dav_session_malloc(
216 res->session, 352 res->session,
217 sizeof(DavNamespace)); 353 sizeof(DavNamespace));
218 namespace->prefix = NULL; 354 namespace->prefix = NULL;
219 namespace->name = sstrdup_a(a, sstr(ns)).ptr; 355 namespace->name = sstrdup_a(a, sstr(ns)).ptr;
220 property->ns = namespace; 356 property->ns = namespace;
221 357
222 data->set = ucx_list_append_a(a, data->set, property); 358 data->remove = ucx_list_append_a(a, data->remove, property);
223 } 359 }
224 360
225 void dav_remove_property(DavResource *res, char *name) { 361
226 char *pns; 362 void dav_set_content(DavResource *res, void *stream, dav_read_func read_func) {
227 char *pname;
228 dav_get_property_namespace(res->session->context, name, &pns, &pname);
229 dav_remove_property_ns(res, pns, pname);
230 }
231
232 void dav_remove_property_ns(DavResource *res, char *ns, char *name) {
233 DavResourceData *data = res->data; 363 DavResourceData *data = res->data;
234 UcxAllocator *a = res->session->mp->allocator; 364 data->content = stream;
235 365 data->read = read_func;
236 DavProperty *property = dav_session_malloc( 366 data->length = 0;
237 res->session,
238 sizeof(DavProperty));
239 property->name = sstrdup_a(a, sstr(name)).ptr;
240 property->value = NULL;
241
242 DavNamespace *namespace = dav_session_malloc(
243 res->session,
244 sizeof(DavNamespace));
245 namespace->prefix = NULL;
246 namespace->name = sstrdup_a(a, sstr(ns)).ptr;
247 property->ns = namespace;
248
249 data->remove = ucx_list_append_a(a, data->remove, property);
250 }
251
252
253 void dav_set_content(DavResource *res, void *stream, dav_read_func read_func) {
254 DavSession *sn = res->session;
255 if((sn->flags & DAV_SESSION_ENCRYPT_FILE) == DAV_SESSION_ENCRYPT_FILE) {
256 AESEncrypter *enc = aes_encrypter_new(sn->key, stream, read_func);
257 DavResourceData *data = res->data;
258 data->content = enc;
259 data->read = (dav_read_func)aes_read;
260 data->length = 0;
261 dav_set_property_ns(
262 res,
263 "http://www.uap-core.de/",
264 "crypto-key",
265 sn->key->name);
266 } else {
267 DavResourceData *data = res->data;
268 data->content = stream;
269 data->read = read_func;
270 data->length = 0;
271 }
272 } 367 }
273 368
274 void dav_set_content_data(DavResource *res, char *content, size_t length) { 369 void dav_set_content_data(DavResource *res, char *content, size_t length) {
275 DavSession *sn = res->session; 370 DavSession *sn = res->session;
276 DavResourceData *data = res->data; 371 DavResourceData *data = res->data;
277 data->content = content; 372 data->content = dav_session_malloc(sn, length);
373 memcpy(data->content, content, length);
278 data->read = NULL; 374 data->read = NULL;
279 data->length = length; 375 data->length = length;
280 } 376 }
281 377
282 378
283 int dav_load(DavResource *res) { 379 int dav_load(DavResource *res) {
284 DavSession *sn = res->session;
285 DavResourceData *data = res->data;
286 // clean map
287 UcxKey key;
288 void *value;
289 UcxMapIterator i = ucx_map_iterator(data->properties);
290 UCX_MAP_FOREACH(key, value, i) {
291 ucx_map_remove(data->properties, key);
292 }
293
294 util_set_url(sn, res->path);
295
296 UcxBuffer *rqbuf = create_allprop_propfind_request(); 380 UcxBuffer *rqbuf = create_allprop_propfind_request();
297 UcxBuffer *rpbuf = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND); 381 int ret = dav_propfind(res->session, res, rqbuf, NULL, 0);
298 382 ucx_buffer_free(rqbuf);
299 //fwrite(rpbuf->space, 1, rpbuf->size, stdout); 383 return ret;
300 //printf("\n");
301
302 CURLcode ret = do_propfind_request(sn->handle, rqbuf, rpbuf);
303 int status = 0;
304 curl_easy_getinfo (sn->handle, CURLINFO_RESPONSE_CODE, &status);
305 if(ret == CURLE_OK) {
306 //printf("response\n%s\n", rpbuf->space);
307 // TODO: use parse_propfind_response()
308 xmlDoc *doc = xmlReadMemory(rpbuf->space, rpbuf->size, NULL, NULL, 0);
309 if(!doc) {
310 return 1;
311 }
312
313 xmlNode *xml_root = xmlDocGetRootElement(doc);
314 xmlNode *node = xml_root->children;
315 while(node) {
316 if(node->type == XML_ELEMENT_NODE) {
317 if(xstreq(node->name, "response")) {
318 parse_response_tag(res, node, NULL, 0);
319 }
320 }
321 node = node->next;
322 }
323
324 set_davprops(res);
325 } else {
326 session_set_error(sn, ret, status);
327 }
328 return 0;
329 } 384 }
330 385
331 int dav_store(DavResource *res) { 386 int dav_store(DavResource *res) {
332 DavSession *sn = res->session; 387 DavSession *sn = res->session;
333 DavResourceData *data = res->data; 388 DavResourceData *data = res->data;
334 389
335 util_set_url(sn, res->path);; 390 util_set_url(sn, dav_resource_get_href(res));
336 391
337 // store content 392 // store content
338 if(data->content) { 393 if(data->content) {
339 CURLcode ret = do_put_request(sn->handle, data->content, data->read, data->length); 394 int encryption = DAV_ENCRYPT_CONTENT(sn) && sn->key;
395 CURLcode ret;
396 if(encryption) {
397 AESEncrypter *enc = NULL;
398 UcxBuffer *buf = NULL;
399 if(data->read) {
400 enc = aes_encrypter_new(sn->key, data->content, data->read);
401 } else {
402 buf = ucx_buffer_new(data->content, data->length, 0);
403 buf->size = data->length;
404 enc = aes_encrypter_new(
405 sn->key,
406 buf,
407 (dav_read_func)ucx_buffer_read);
408 }
409
410 // create an empty resource
411 ret = do_put_request(
412 sn->handle,
413 enc,
414 (dav_read_func)aes_read,
415 0);
416 aes_encrypter_close(enc);
417 if(buf) {
418 ucx_buffer_free(buf);
419 }
420
421 // add crypto properties
422 // TODO: store the properties later
423 if(resource_add_crypto_info(sn, res->href, res->name)) {
424 return 1;
425 }
426 } else {
427 ret = do_put_request(
428 sn->handle,
429 data->content,
430 data->read,
431 data->length);
432 }
433
340 int status = 0; 434 int status = 0;
341 curl_easy_getinfo(sn->handle, CURLINFO_RESPONSE_CODE, &status); 435 curl_easy_getinfo(sn->handle, CURLINFO_RESPONSE_CODE, &status);
342 if(ret == CURLE_OK && (status >= 200 && status < 300)) { 436 if(ret == CURLE_OK && (status >= 200 && status < 300)) {
343 res->session->error = 0; 437 res->session->error = 0;
344 // cleanup node data 438 // cleanup node data
347 } 441 }
348 data->content = NULL; 442 data->content = NULL;
349 data->read = NULL; 443 data->read = NULL;
350 data->length = 0; 444 data->length = 0;
351 } else { 445 } else {
352 session_set_error(sn, ret, status); 446 dav_session_set_error(sn, ret, status);
353 return 1; 447 return 1;
354 } 448 }
355 } 449 }
356 450
357 // store properties 451 // store properties
367 // TODO: parse response 461 // TODO: parse response
368 // TODO: cleanup node data correctly 462 // TODO: cleanup node data correctly
369 data->set = NULL; 463 data->set = NULL;
370 data->remove = NULL; 464 data->remove = NULL;
371 } else { 465 } else {
372 session_set_error(sn, ret, status); 466 dav_session_set_error(sn, ret, status);
373 return 1; 467 return 1;
374 } 468 }
375 } 469 }
376 sn->error = DAV_OK; 470 sn->error = DAV_OK;
377 return 0; 471 return 0;
378 } 472 }
379 473
380 int dav_get_content(DavResource *res, void *stream, dav_write_func write_fnc) { 474 int dav_get_content(DavResource *res, void *stream, dav_write_func write_fnc) {
381 CURL *handle = res->session->handle; 475 DavSession *sn = res->session;
382 util_set_url(res->session, res->path); 476 CURL *handle = sn->handle;
477 util_set_url(res->session, dav_resource_get_href(res));
478
479 // check encryption
480 AESDecrypter *dec = NULL;
481 if(DAV_DECRYPT_CONTENT(sn)) {
482 char *keyname = dav_get_property_ns(res, DAV_NS, "crypto-key");
483 if(keyname) {
484 DavKey *key = dav_context_get_key(sn->context, keyname);
485 if(key) {
486 dec = aes_decrypter_new(key, stream, write_fnc);
487 stream = dec;
488 write_fnc = (dav_write_func)aes_write;
489 }
490 }
491 }
383 492
384 curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0); 493 curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0);
385 curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, NULL); 494 curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, NULL);
386 curl_easy_setopt(handle, CURLOPT_PUT, 0L); 495 curl_easy_setopt(handle, CURLOPT_PUT, 0L);
387 curl_easy_setopt(handle, CURLOPT_UPLOAD, 0L); 496 curl_easy_setopt(handle, CURLOPT_UPLOAD, 0L);
388 497
389 curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_fnc); 498 curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_fnc);
390 curl_easy_setopt(handle, CURLOPT_WRITEDATA, stream); 499 curl_easy_setopt(handle, CURLOPT_WRITEDATA, stream);
391 500
392 CURLcode ret = curl_easy_perform(handle); 501 CURLcode ret = curl_easy_perform(handle);
502
503 if(dec) {
504 aes_decrypter_close(dec);
505 }
506
393 int status = 0; 507 int status = 0;
394 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); 508 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
395 if(ret == CURLE_OK && (status >= 200 && status < 300)) { 509 if(ret == CURLE_OK && (status >= 200 && status < 300)) {
396 res->session->error = DAV_OK; 510 res->session->error = DAV_OK;
397 return 0; 511 return 0;
398 } else { 512 } else {
399 session_set_error(res->session, ret, status); 513 dav_session_set_error(res->session, ret, status);
400 return 1; 514 return 1;
401 } 515 }
402 } 516 }
403 517
404 DavResource* dav_create_child(DavResource *parent, char *name) { 518 DavResource* dav_create_child(DavResource *parent, char *name) {
411 } 525 }
412 } 526 }
413 527
414 int dav_delete(DavResource *res) { 528 int dav_delete(DavResource *res) {
415 CURL *handle = res->session->handle; 529 CURL *handle = res->session->handle;
416 util_set_url(res->session, res->path); 530 util_set_url(res->session, dav_resource_get_href(res));
417 531
418 UcxBuffer *response = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND); 532 UcxBuffer *response = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND);
419 CURLcode ret = do_delete_request(handle, response); 533 CURLcode ret = do_delete_request(handle, response);
420 int status = 0; 534 int status = 0;
421 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); 535 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
425 // TODO: parse response 539 // TODO: parse response
426 // TODO: free res 540 // TODO: free res
427 541
428 return 0; 542 return 0;
429 } else { 543 } else {
430 session_set_error(res->session, ret, status); 544 dav_session_set_error(res->session, ret, status);
431 return 1; 545 return 1;
432 } 546 }
433 } 547 }
434 548
549 static int create_ancestors(DavSession *sn, char *href, char *path) {
550 CURL *handle = sn->handle;
551 CURLcode code;
552 int status = 0;
553 int ret = 0;
554
555 if(strlen(path) <= 1) {
556 return 0;
557 }
558
559 char *p = util_parent_path(path);
560 char *h = util_parent_path(href);
561
562 for(int i=0;i<2;i++) {
563 util_set_url(sn, h);
564 code = do_mkcol_request(handle);
565 curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &status);
566 if(status == 201) {
567 // resource successfully created
568 char *name = util_resource_name(p);
569 int len = strlen(name);
570 if(name[len - 1] == '/') {
571 name[len - 1] = '\0';
572 }
573 if(resource_add_crypto_info(sn, h, name)) {
574 // TODO: error
575 }
576 break;
577 } else if(status == 405) {
578 // parent already exists
579 break;
580 } else if(status == 409) {
581 // parent doesn't exist
582 if(create_ancestors(sn, h, p)) {
583 ret = 1;
584 break;
585 }
586 } else {
587 dav_session_set_error(sn, code, status);
588 ret = 1;
589 break;
590 }
591 }
592
593 free(p);
594 free(h);
595 return ret;
596 }
597
598 static int create_resource(DavResource *res, int *status) {
599 DavSession *sn = res->session;
600 CURL *handle = sn->handle;
601 util_set_url(sn, dav_resource_get_href(res));
602
603 CURLcode code;
604 if(res->iscollection) {
605 code = do_mkcol_request(handle);
606 } else {
607 code = do_put_request(handle, "", NULL, 0);
608 }
609 int s = 0;
610 curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &s);
611 *status = s;
612 if(code == CURLE_OK && (s >= 200 && s < 300)) {
613 sn->error = DAV_OK;
614 // if the session has encrypted file names, add crypto infos
615 resource_add_crypto_info(sn, res->href, res->name); // TODO: check return type
616
617 // do a minimal propfind request
618 UcxBuffer *rqbuf = create_propfind_request(sn, NULL);
619 int ret = dav_propfind(sn, res, rqbuf, NULL, 0);
620 ucx_buffer_free(rqbuf);
621 return ret;
622 } else {
623 dav_session_set_error(sn, code, s);
624 return 1;
625 }
626 }
627
435 int dav_create(DavResource *res) { 628 int dav_create(DavResource *res) {
436 //char *url = util_concat_path(res->session->base_url, res->path); 629 int status;
437 char *parent = util_parent_path(res->path); 630 if(!create_resource(res, &status)) {
438 631 // resource successfully created
439 DavSession *sn = res->session; 632 return 0;
440 DavResource *parent_res = dav_get(sn, parent, NULL); 633 }
441 if(!parent_res && sn->error == DAV_NOT_FOUND) { 634
442 parent_res = dav_resource_new(sn, parent); 635 if(status == 403 || status == 409) {
443 parent_res->iscollection = 1; 636 // create intermediate collections
444 int r = dav_create(parent_res); 637 if(create_ancestors(res->session, res->href, res->path)) {
445 if(r) {
446 free(parent);
447 return r;
448 }
449 } else if(parent_res && !parent_res->iscollection) {
450 sn->error = DAV_FORBIDDEN;
451 return 1;
452 } else if(sn->error != DAV_OK) {
453 return 1;
454 }
455
456 CURL *handle = res->session->handle;
457 util_set_url(res->session, res->path);
458 free(parent);
459
460 // create new collection or do an empty put request
461 CURLcode ret;
462 if(res->iscollection) {
463 ret = do_mkcol_request(handle);
464 } else {
465 ret = do_put_request(handle, "", NULL, 0);
466 }
467 int status = 0;
468 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
469 if(ret == CURLE_OK && (status >= 200 && status < 300)) {
470 res->session->error = DAV_OK;
471 } else {
472 session_set_error(res->session, ret, status);
473 return 1;
474 }
475
476 // do an minimal propfind request
477 UcxBuffer *rqbuf = create_propfind_request(NULL);
478 UcxBuffer *rpbuf = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND);
479
480 //fwrite(rpbuf->space, 1, rpbuf->size, stdout);
481 //printf("\n");
482
483 ret = do_propfind_request(handle, rqbuf, rpbuf);
484 status = 0;
485 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
486 if(ret == CURLE_OK && (status >= 200 && status < 300)) {
487 //printf("response\n%s\n", rpbuf->space);
488 // TODO: use parse_propfind_response()
489 xmlDoc *doc = xmlReadMemory(rpbuf->space, rpbuf->size, NULL, NULL, 0);
490 if(!doc) {
491 return 1; 638 return 1;
492 } 639 }
493 640 }
494 xmlNode *xml_root = xmlDocGetRootElement(doc); 641
495 xmlNode *node = xml_root->children; 642 return create_resource(res, &status);
496 while(node) {
497 if(node->type == XML_ELEMENT_NODE) {
498 if(xstreq(node->name, "response")) {
499 parse_response_tag(res, node, NULL, 0);
500 }
501 }
502 node = node->next;
503 }
504
505 set_davprops(res);
506 return 0;
507 } else {
508 session_set_error(sn, ret, status);
509 return 1;
510 }
511 } 643 }
512 644
513 int dav_exists(DavResource *res) { 645 int dav_exists(DavResource *res) {
514 DavSession *sn = res->session; 646 DavSession *sn = res->session;
515 CURL *handle = sn->handle; 647 CURL *handle = sn->handle;
516 util_set_url(sn, res->path); 648 util_set_url(sn, dav_resource_get_href(res));
517 649
518 CURLcode ret = do_head_request(handle); 650 CURLcode ret = do_head_request(handle);
519 int status = 0; 651 int status = 0;
520 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); 652 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
521 if(ret == CURLE_OK && (status >= 200 && status < 300)) { 653 if(ret == CURLE_OK && (status >= 200 && status < 300)) {
522 return 1; 654 return 1;
523 } else { 655 } else {
524 session_set_error(sn, ret, status); 656 dav_session_set_error(sn, ret, status);
525 return 0; 657 return 0;
526 } 658 }
527 } 659 }
660
661
662 int resource_add_crypto_info(DavSession *sn, char *href, char *name) {
663 if(!DAV_IS_ENCRYPTED(sn)) {
664 return 0;
665 }
666
667 UcxBuffer *request = create_crypto_proppatch_request(sn, sn->key, name);
668 UcxBuffer *response = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND);
669
670 util_set_url(sn, href);
671 CURLcode ret = do_proppatch_request(sn->handle, request, response);
672 int status = 0;
673 curl_easy_getinfo (sn->handle, CURLINFO_RESPONSE_CODE, &status);
674 if(ret == CURLE_OK && status == 207) {
675 // TODO: parse response
676 sn->error = DAV_OK;
677 return 0;
678 } else {
679 dav_session_set_error(sn, ret, status);
680 return 1;
681 }
682 }

mercurial