libidav/resource.c

changeset 40
a95ee94b9204
parent 33
0bbbb0341606
child 41
1c598ee0d3d9
equal deleted inserted replaced
39:3e55bed345f9 40:a95ee94b9204
32 #include <libxml/tree.h> 32 #include <libxml/tree.h>
33 33
34 #include "utils.h" 34 #include "utils.h"
35 #include "methods.h" 35 #include "methods.h"
36 #include "davql.h" 36 #include "davql.h"
37 #include "crypto.h"
37 #include "ucx/buffer.h" 38 #include "ucx/buffer.h"
38 #include "ucx/utils.h" 39 #include "ucx/utils.h"
39 40
40 #include "resource.h" 41 #include "resource.h"
41 42
42 #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b) 43 #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b)
43 44
44 DavResource* dav_resource_new(DavSession *sn, char *path) { 45 DavResource* dav_resource_new(DavSession *sn, char *path) {
45 char *url = util_concat_path(sn->base_url, path); 46 int plen = 0;
47 char *url = util_path_to_url(sn, path);
46 char *href = util_url_path(url); 48 char *href = util_url_path(url);
47 DavResource *res = dav_resource_new_href(sn, href); 49 DavResource *res = dav_resource_new_href(sn, href);
48 free(url); 50 free(url);
49 return res; 51 return res;
50 } 52 }
51 53
52 54
53 DavResource* dav_resource_new_href(DavSession *sn, char *href) { 55 DavResource* dav_resource_new_href(DavSession *sn, char *href) {
54 UcxMempool *mp = sn->mp; 56 DavResource *res = ucx_mempool_calloc(sn->mp, 1, sizeof(DavResource));
55 UcxAllocator *a = sn->allocator;
56
57 DavResource *res = ucx_mempool_calloc(mp, 1, sizeof(DavResource));
58 res->session = sn; 57 res->session = sn;
59 58
60 // set name, path and href 59 // set name, path and href
61 resource_set_info(res, href); 60 resource_set_info(res, href);
62 61
73 sstr_t href = sstr(href_str); 72 sstr_t href = sstr(href_str);
74 73
75 sstr_t base_href = sstr(util_url_path(res->session->base_url)); 74 sstr_t base_href = sstr(util_url_path(res->session->base_url));
76 sstr_t path = sstrsubs(href, base_href.length - 1); 75 sstr_t path = sstrsubs(href, base_href.length - 1);
77 76
78 UcxAllocator *a = res->session->allocator; 77 UcxAllocator *a = res->session->mp->allocator;
79 res->name = sstrdup_a(a, name).ptr; 78 CURL *handle = res->session->handle;
79
80 int nlen = 0;
81 char *uname = curl_easy_unescape(handle, name.ptr, name.length , &nlen);
82 int plen = 0;
83 char *upath = curl_easy_unescape(handle, path.ptr, path.length, &plen);
84
85 res->name = sstrdup_a(a, sstrn(uname, nlen)).ptr;
80 res->href = sstrdup_a(a, href).ptr; 86 res->href = sstrdup_a(a, href).ptr;
81 res->path = sstrdup_a(a, path).ptr; 87 res->path = sstrdup_a(a, sstrn(upath, plen)).ptr;
88
89 curl_free(uname);
90 curl_free(upath);
82 } 91 }
83 92
84 DavResourceData* resource_data_new(DavSession *sn) { 93 DavResourceData* resource_data_new(DavSession *sn) {
85 DavResourceData *data = ucx_mempool_malloc( 94 DavResourceData *data = ucx_mempool_malloc(
86 sn->mp, 95 sn->mp,
87 sizeof(DavResourceData)); 96 sizeof(DavResourceData));
88 if(!data) { 97 if(!data) {
89 return NULL; 98 return NULL;
90 } 99 }
91 data->properties = ucx_map_new_a(sn->allocator, 32); 100 data->properties = ucx_map_new_a(sn->mp->allocator, 32);
92 data->set = NULL; 101 data->set = NULL;
93 data->remove = NULL; 102 data->remove = NULL;
94 data->content = NULL; 103 data->content = NULL;
95 data->read = NULL; 104 data->read = NULL;
96 data->length = 0; 105 data->length = 0;
99 108
100 void resource_add_property(DavResource *res, char *ns, char *name, char *val) { 109 void resource_add_property(DavResource *res, char *ns, char *name, char *val) {
101 if(!val) { 110 if(!val) {
102 return; 111 return;
103 } 112 }
104 UcxAllocator *a = res->session->allocator;
105 113
106 UcxKey key = dav_property_key(ns, name); 114 UcxKey key = dav_property_key(ns, name);
107 sstr_t v = sstrdup_a(a, sstr(val)); 115 sstr_t v = sstrdup_a(res->session->mp->allocator, sstr(val));
108 ucx_map_put(((DavResourceData*)res->data)->properties, key, v.ptr); 116 ucx_map_put(((DavResourceData*)res->data)->properties, key, v.ptr);
109 free(key.data); 117 free(key.data);
110 } 118 }
111 119
112 char* resource_get_property(DavResource *res, char *ns, char *name) { 120 char* resource_get_property(DavResource *res, char *ns, char *name) {
187 dav_get_property_namespace(res->session->context, name, &pns, &pname); 195 dav_get_property_namespace(res->session->context, name, &pns, &pname);
188 dav_set_property_ns(res, pns, pname, value); 196 dav_set_property_ns(res, pns, pname, value);
189 } 197 }
190 198
191 void dav_set_property_ns(DavResource *res, char *ns, char *name, char *value) { 199 void dav_set_property_ns(DavResource *res, char *ns, char *name, char *value) {
192 UcxAllocator *a = res->session->allocator; 200 UcxAllocator *a = res->session->mp->allocator;
193 DavResourceData *data = res->data; 201 DavResourceData *data = res->data;
194 202
195 DavProperty *property = a->malloc(a->pool, sizeof(DavProperty)); 203 DavProperty *property = dav_session_malloc(
204 res->session,
205 sizeof(DavProperty));
196 property->name = sstrdup_a(a, sstr(name)).ptr; 206 property->name = sstrdup_a(a, sstr(name)).ptr;
197 property->value = sstrdup_a(a, sstr(value)).ptr; 207 property->value = sstrdup_a(a, sstr(value)).ptr;
198 DavNamespace *namespace = a->malloc(a->pool, sizeof(DavNamespace)); 208
209 DavNamespace *namespace = dav_session_malloc(
210 res->session,
211 sizeof(DavNamespace));
199 namespace->prefix = NULL; 212 namespace->prefix = NULL;
200 namespace->name = sstrdup_a(a, sstr(ns)).ptr; 213 namespace->name = sstrdup_a(a, sstr(ns)).ptr;
201 property->ns = namespace; 214 property->ns = namespace;
202 215
203 data->set = ucx_list_append_a(a, data->set, property); 216 data->set = ucx_list_append_a(a, data->set, property);
209 dav_get_property_namespace(res->session->context, name, &pns, &pname); 222 dav_get_property_namespace(res->session->context, name, &pns, &pname);
210 dav_remove_property_ns(res, pns, pname); 223 dav_remove_property_ns(res, pns, pname);
211 } 224 }
212 225
213 void dav_remove_property_ns(DavResource *res, char *ns, char *name) { 226 void dav_remove_property_ns(DavResource *res, char *ns, char *name) {
214 UcxAllocator *a = res->session->allocator;
215 DavResourceData *data = res->data; 227 DavResourceData *data = res->data;
216 228 UcxAllocator *a = res->session->mp->allocator;
217 DavProperty *property = a->malloc(a->pool, sizeof(DavProperty)); 229
230 DavProperty *property = dav_session_malloc(
231 res->session,
232 sizeof(DavProperty));
218 property->name = sstrdup_a(a, sstr(name)).ptr; 233 property->name = sstrdup_a(a, sstr(name)).ptr;
219 property->value = NULL; 234 property->value = NULL;
220 DavNamespace *namespace = a->malloc(a->pool, sizeof(DavNamespace)); 235
236 DavNamespace *namespace = dav_session_malloc(
237 res->session,
238 sizeof(DavNamespace));
221 namespace->prefix = NULL; 239 namespace->prefix = NULL;
222 namespace->name = sstrdup_a(a, sstr(ns)).ptr; 240 namespace->name = sstrdup_a(a, sstr(ns)).ptr;
223 property->ns = namespace; 241 property->ns = namespace;
224 242
225 data->remove = ucx_list_append_a(a, data->remove, property); 243 data->remove = ucx_list_append_a(a, data->remove, property);
226 } 244 }
227 245
228 246
229 void dav_set_content(DavResource *res, void *stream, dav_read_func read_func) { 247 void dav_set_content(DavResource *res, void *stream, dav_read_func read_func) {
230 DavResourceData *data = res->data; 248 DavSession *sn = res->session;
231 data->content = stream; 249 if((sn->flags & DAV_SESSION_ENCRYPT_FILE) == DAV_SESSION_ENCRYPT_FILE) {
232 data->read = read_func; 250 AESEncrypter *enc = aes_encrypter_new(sn->key, stream, read_func);
233 data->length = 0; 251 DavResourceData *data = res->data;
252 data->content = enc;
253 data->read = (dav_read_func)aes_read;
254 data->length = 0;
255 dav_set_property_ns(
256 res,
257 "http://www.uap-core.de/",
258 "crypto-key",
259 sn->key->name);
260 } else {
261 DavResourceData *data = res->data;
262 data->content = stream;
263 data->read = read_func;
264 data->length = 0;
265 }
234 } 266 }
235 267
236 void dav_set_content_data(DavResource *res, char *content, size_t length) { 268 void dav_set_content_data(DavResource *res, char *content, size_t length) {
237 DavSession *sn = res->session; 269 DavSession *sn = res->session;
238 DavResourceData *data = res->data; 270 DavResourceData *data = res->data;
251 UcxMapIterator i = ucx_map_iterator(data->properties); 283 UcxMapIterator i = ucx_map_iterator(data->properties);
252 UCX_MAP_FOREACH(key, value, i) { 284 UCX_MAP_FOREACH(key, value, i) {
253 ucx_map_remove(data->properties, key); 285 ucx_map_remove(data->properties, key);
254 } 286 }
255 287
256 char *url = util_concat_path(sn->base_url, res->path); 288 util_set_url(sn, res->path);
257
258 CURL *handle = sn->handle;
259 curl_easy_setopt(handle, CURLOPT_URL, url);
260 free(url);
261 289
262 UcxBuffer *rqbuf = create_allprop_propfind_request(); 290 UcxBuffer *rqbuf = create_allprop_propfind_request();
263 UcxBuffer *rpbuf = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND); 291 UcxBuffer *rpbuf = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND);
264 292
265 //fwrite(rpbuf->space, 1, rpbuf->size, stdout); 293 //fwrite(rpbuf->space, 1, rpbuf->size, stdout);
266 //printf("\n"); 294 //printf("\n");
267 295
268 CURLcode ret = do_propfind_request(handle, rqbuf, rpbuf); 296 CURLcode ret = do_propfind_request(sn->handle, rqbuf, rpbuf);
269 int status = 0; 297 int status = 0;
270 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); 298 curl_easy_getinfo (sn->handle, CURLINFO_RESPONSE_CODE, &status);
271 if(ret == CURLE_OK) { 299 if(ret == CURLE_OK) {
272 //printf("response\n%s\n", rpbuf->space); 300 //printf("response\n%s\n", rpbuf->space);
273 // TODO: use parse_propfind_response() 301 // TODO: use parse_propfind_response()
274 xmlDoc *doc = xmlReadMemory(rpbuf->space, rpbuf->size, url, NULL, 0); 302 xmlDoc *doc = xmlReadMemory(rpbuf->space, rpbuf->size, NULL, NULL, 0);
275 if(!doc) { 303 if(!doc) {
276 return 1; 304 return 1;
277 } 305 }
278 306
279 xmlNode *xml_root = xmlDocGetRootElement(doc); 307 xmlNode *xml_root = xmlDocGetRootElement(doc);
296 324
297 int dav_store(DavResource *res) { 325 int dav_store(DavResource *res) {
298 DavSession *sn = res->session; 326 DavSession *sn = res->session;
299 DavResourceData *data = res->data; 327 DavResourceData *data = res->data;
300 328
301 char *url = util_concat_path(sn->base_url, res->path); 329 util_set_url(sn, res->path);;
302 CURL *handle = res->session->handle;
303 curl_easy_setopt(handle, CURLOPT_URL, url);
304 free(url);
305 330
306 // store content 331 // store content
307 if(data->content) { 332 if(data->content) {
308 CURLcode ret = do_put_request(handle, data->content, data->read, data->length); 333 CURLcode ret = do_put_request(sn->handle, data->content, data->read, data->length);
309 int status = 0; 334 int status = 0;
310 curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &status); 335 curl_easy_getinfo(sn->handle, CURLINFO_RESPONSE_CODE, &status);
311 if(ret == CURLE_OK && (status >= 200 && status < 300)) { 336 if(ret == CURLE_OK && (status >= 200 && status < 300)) {
312 res->session->error = 0; 337 res->session->error = 0;
313 // cleanup node data 338 // cleanup node data
314 if(!data->read) { 339 if(!data->read) {
315 ucx_mempool_free(sn->mp, data->content); 340 ucx_mempool_free(sn->mp, data->content);
326 // store properties 351 // store properties
327 if(data->set || data->remove) { 352 if(data->set || data->remove) {
328 UcxBuffer *request = create_proppatch_request(data); 353 UcxBuffer *request = create_proppatch_request(data);
329 UcxBuffer *response = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND); 354 UcxBuffer *response = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND);
330 355
331 CURLcode ret = do_proppatch_request(handle, request, response); 356 CURLcode ret = do_proppatch_request(sn->handle, request, response);
332 int status = 0; 357 int status = 0;
333 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); 358 curl_easy_getinfo (sn->handle, CURLINFO_RESPONSE_CODE, &status);
334 if(ret == CURLE_OK && status == 207) { 359 if(ret == CURLE_OK && status == 207) {
335 //printf("%s\n", response->space); 360 //printf("%s\n", response->space);
336 // TODO: parse response 361 // TODO: parse response
337 // TODO: cleanup node data correctly 362 // TODO: cleanup node data correctly
338 data->set = NULL; 363 data->set = NULL;
345 sn->error = DAV_OK; 370 sn->error = DAV_OK;
346 return 0; 371 return 0;
347 } 372 }
348 373
349 int dav_get_content(DavResource *res, void *stream, dav_write_func write_fnc) { 374 int dav_get_content(DavResource *res, void *stream, dav_write_func write_fnc) {
350 char *url = util_concat_path(res->session->base_url, res->path);
351 CURL *handle = res->session->handle; 375 CURL *handle = res->session->handle;
352 curl_easy_setopt(handle, CURLOPT_URL, url); 376 util_set_url(res->session, res->path);
353 free(url);
354 377
355 curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0); 378 curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0);
356 curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, NULL); 379 curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, NULL);
357 curl_easy_setopt(handle, CURLOPT_PUT, 0L); 380 curl_easy_setopt(handle, CURLOPT_PUT, 0L);
358 curl_easy_setopt(handle, CURLOPT_UPLOAD, 0L); 381 curl_easy_setopt(handle, CURLOPT_UPLOAD, 0L);
376 // TODO 399 // TODO
377 return NULL; 400 return NULL;
378 } 401 }
379 402
380 int dav_delete(DavResource *res) { 403 int dav_delete(DavResource *res) {
381 char *url = util_concat_path(res->session->base_url, res->path);
382 CURL *handle = res->session->handle; 404 CURL *handle = res->session->handle;
383 curl_easy_setopt(handle, CURLOPT_URL, url); 405 util_set_url(res->session, res->path);
384 free(url);
385 406
386 UcxBuffer *response = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND); 407 UcxBuffer *response = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND);
387 CURLcode ret = do_delete_request(handle, response); 408 CURLcode ret = do_delete_request(handle, response);
388 int status = 0; 409 int status = 0;
389 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); 410 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
399 return 1; 420 return 1;
400 } 421 }
401 } 422 }
402 423
403 int dav_create(DavResource *res) { 424 int dav_create(DavResource *res) {
404 char *url = util_concat_path(res->session->base_url, res->path); 425 //char *url = util_concat_path(res->session->base_url, res->path);
405 char *parent = util_parent_path(res->path); 426 char *parent = util_parent_path(res->path);
406 427
407 DavSession *sn = res->session; 428 DavSession *sn = res->session;
408 DavResource *parent_res = dav_get(sn, parent, NULL); 429 DavResource *parent_res = dav_get(sn, parent, NULL);
409 if(!parent_res && sn->error == DAV_NOT_FOUND) { 430 if(!parent_res && sn->error == DAV_NOT_FOUND) {
420 } else if(sn->error != DAV_OK) { 441 } else if(sn->error != DAV_OK) {
421 return 1; 442 return 1;
422 } 443 }
423 444
424 CURL *handle = res->session->handle; 445 CURL *handle = res->session->handle;
425 curl_easy_setopt(handle, CURLOPT_URL, url); 446 util_set_url(res->session, res->path);
426 free(url);
427 free(parent); 447 free(parent);
428 448
429 // create new collection or do an empty put request 449 // create new collection or do an empty put request
430 CURLcode ret; 450 CURLcode ret;
431 if(res->iscollection) { 451 if(res->iscollection) {
453 status = 0; 473 status = 0;
454 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); 474 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
455 if(ret == CURLE_OK && (status >= 200 && status < 300)) { 475 if(ret == CURLE_OK && (status >= 200 && status < 300)) {
456 //printf("response\n%s\n", rpbuf->space); 476 //printf("response\n%s\n", rpbuf->space);
457 // TODO: use parse_propfind_response() 477 // TODO: use parse_propfind_response()
458 xmlDoc *doc = xmlReadMemory(rpbuf->space, rpbuf->size, url, NULL, 0); 478 xmlDoc *doc = xmlReadMemory(rpbuf->space, rpbuf->size, NULL, NULL, 0);
459 if(!doc) { 479 if(!doc) {
460 return 1; 480 return 1;
461 } 481 }
462 482
463 xmlNode *xml_root = xmlDocGetRootElement(doc); 483 xmlNode *xml_root = xmlDocGetRootElement(doc);
479 } 499 }
480 } 500 }
481 501
482 int dav_exists(DavResource *res) { 502 int dav_exists(DavResource *res) {
483 DavSession *sn = res->session; 503 DavSession *sn = res->session;
484 char *url = util_concat_path(sn->base_url, res->path);
485 CURL *handle = sn->handle; 504 CURL *handle = sn->handle;
486 curl_easy_setopt(handle, CURLOPT_URL, url); 505 util_set_url(sn, res->path);
487 free(url);
488 506
489 CURLcode ret = do_head_request(handle); 507 CURLcode ret = do_head_request(handle);
490 int status = 0; 508 int status = 0;
491 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); 509 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
492 if(ret == CURLE_OK && (status >= 200 && status < 300)) { 510 if(ret == CURLE_OK && (status >= 200 && status < 300)) {

mercurial