libidav/methods.c

changeset 128
649eb328674a
parent 104
6fb4d24d9df9
child 135
664aeaec8d25
equal deleted inserted replaced
127:7072a2b4ae35 128:649eb328674a
223 ucx_buffer_write(s.ptr, 1, s.length, buf); 223 ucx_buffer_write(s.ptr, 1, s.length, buf);
224 224
225 return buf; 225 return buf;
226 } 226 }
227 227
228 PropfindParser* create_propfind_parser(UcxBuffer *response, char *url) {
229 PropfindParser *parser = malloc(sizeof(PropfindParser));
230 if(!parser) {
231 return NULL;
232 }
233 parser->document = xmlReadMemory(response->space, response->size, url, NULL, 0);
234 parser->current = NULL;
235 if(parser->document) {
236 xmlNode *xml_root = xmlDocGetRootElement(parser->document);
237 if(xml_root) {
238 xmlNode *node = xml_root->children;
239 while(node) {
240 // find first response tag
241 if(node->type == XML_ELEMENT_NODE) {
242 if(xstreq(node->name, "response")) {
243 parser->current = node;
244 break;
245 }
246 }
247 node = node->next;
248 }
249 return parser;
250 } else {
251 xmlFreeDoc(parser->document);
252 }
253 }
254 free(parser);
255 return NULL;
256 }
257
258 int get_propfind_response(PropfindParser *parser, ResponseTag *result) {
259 if(parser->current == NULL) {
260 return 0;
261 }
262
263 char *href = NULL;
264 int iscollection = 0;
265 UcxList *properties = NULL; // xmlNode list
266 char *crypto_name = NULL; // name set by crypto-name property
267 char *crypto_key = NULL;
268
269 xmlNode *node = parser->current->children;
270 while(node) {
271 if(node->type == XML_ELEMENT_NODE) {
272 if(xstreq(node->name, "href")) {
273 xmlNode *href_node = node->children;
274 if(href_node->type != XML_TEXT_NODE) {
275 // error
276 return -1;
277 }
278 href = (char*)href_node->content;
279 } else if(xstreq(node->name, "propstat")) {
280 xmlNode *n = node->children;
281 xmlNode *prop_node = NULL;
282 int ok = 0;
283 // get the status code
284 while(n) {
285 if(n->type == XML_ELEMENT_NODE) {
286 if(xstreq(n->name, "prop")) {
287 prop_node = n;
288 } else if(xstreq(n->name, "status")) {
289 xmlNode *status_node = n->children;
290 if(status_node->type != XML_TEXT_NODE) {
291 // error
292 return -1;
293 }
294 sstr_t status_str = sstr((char*)status_node->content);
295 if(status_str.length < 13) {
296 // error
297 return -1;
298 }
299 status_str = sstrsubsl(status_str, 9, 3);
300 if(!sstrcmp(status_str, S("200"))) {
301 ok = 1;
302 }
303 }
304 }
305 n = n->next;
306 }
307 // if status is ok, get all properties
308 if(ok) {
309 n = prop_node->children;
310 while(n) {
311 if(n->type == XML_ELEMENT_NODE) {
312 properties = ucx_list_append(properties, n);
313 if(xstreq(n->name, "resourcetype")) {
314 xmlNode *rsnode = n->children;
315 if(rsnode && rsnode->type == XML_ELEMENT_NODE) {
316 // TODO: check content
317 iscollection = 1;
318 }
319 } else if(xstreq(n->ns->href, DAV_NS)) {
320 if(xstreq(n->name, "crypto-name")) {
321 crypto_name = util_xml_get_text(n);
322 } else if(xstreq(n->name, "crypto-key")) {
323 crypto_key = util_xml_get_text(n);
324 }
325 }
326 }
327 n = n->next;
328 }
329 }
330 }
331 }
332 node = node->next;
333 }
334
335 result->href = href;
336 result->iscollection = iscollection;
337 result->properties = properties;
338 result->crypto_name = crypto_name;
339 result->crypto_key = crypto_key;
340
341 // find next response tag
342 xmlNode *next = parser->current->next;
343 while(next) {
344 if(next->type == XML_ELEMENT_NODE) {
345 if(xstreq(next->name, "response")) {
346 break;
347 }
348 }
349 next = next->next;
350 }
351 parser->current = next;
352
353 return 1;
354 }
355
356 int hrefeq(DavSession *sn, char *href1, char *href2) {
357 sstr_t href_s = sstr(util_url_decode(sn, href1));
358 sstr_t href_r = sstr(util_url_decode(sn, href2));
359 int ret = 0;
360 if(!sstrcmp(href_s, href_r)) {
361 ret = 1;
362 } else if(href_s.length == href_r.length + 1) {
363 if(href_s.ptr[href_s.length-1] == '/') {
364 href_s.length--;
365 if(!sstrcmp(href_s, href_r)) {
366 ret = 1;
367 }
368 }
369 }
370
371 free(href_s.ptr);
372 free(href_r.ptr);
373
374 return ret;
375 }
376
377
228 DavResource* parse_propfind_response(DavSession *sn, DavResource *root, UcxBuffer *response, DavQOp *cond, size_t len) { 378 DavResource* parse_propfind_response(DavSession *sn, DavResource *root, UcxBuffer *response, DavQOp *cond, size_t len) {
229 char *url = NULL; 379 char *url = NULL;
230 curl_easy_getinfo(sn->handle, CURLINFO_EFFECTIVE_URL, &url); 380 curl_easy_getinfo(sn->handle, CURLINFO_EFFECTIVE_URL, &url);
231 if(!root) { 381 if(!root) {
232 printf("method.c: TODO: remove\n"); 382 printf("method.c: TODO: remove\n");
252 node = node->next; 402 node = node->next;
253 } 403 }
254 xmlFreeDoc(doc); 404 xmlFreeDoc(doc);
255 405
256 return root; 406 return root;
407 }
408
409 DavResource* response2resource(DavSession *sn, ResponseTag *response, char *parent_path) {
410 // create resource
411 char *name = NULL;
412 if(DAV_DECRYPT_NAME(sn) && response->crypto_name) {
413 if(!response->crypto_key) {
414 // TODO: error
415 fprintf(stderr, "encrypted resource without key\n");
416 return NULL;
417 }
418 name = util_decrypt_str(sn, response->crypto_name, response->crypto_key);
419 if(!name) {
420 // TODO: error
421 fprintf(stderr, "decrypted name is null\n");
422 return NULL;
423 }
424 } else {
425 sstr_t resname = sstr(util_resource_name(response->href));
426 int nlen = 0;
427 char *uname = curl_easy_unescape(
428 sn->handle,
429 resname.ptr,
430 resname.length,
431 &nlen);
432 name = dav_session_strdup(sn, uname);
433 curl_free(uname);
434 }
435
436 char *href = dav_session_strdup(sn, href);
437 DavResource *res = NULL;
438 if(parent_path) {
439 res = dav_resource_new_full(sn, parent_path, name, href);
440 } else {
441 res = dav_resource_new_href(sn, href);
442 }
443 dav_session_free(sn, name);
444
445 add_properties(res, response);
446 return res;
447 }
448
449 void add_properties(DavResource *res, ResponseTag *response) {
450 res->iscollection = response->iscollection;
451
452 // add properties
453 UCX_FOREACH(elm, response->properties) {
454 xmlNode *prop = elm->data;
455
456 // TODO: add xml data instead of a string
457 char *text = util_xml_get_text(prop);
458 if(text) {
459 resource_add_property(res, (char*)prop->ns->href, (char*)prop->name, text);
460 }
461 }
462
463 set_davprops(res);
257 } 464 }
258 465
259 int parse_response_tag(DavResource *resource, xmlNode *node, DavQOp *cond, size_t clen) { 466 int parse_response_tag(DavResource *resource, xmlNode *node, DavQOp *cond, size_t clen) {
260 DavSession *sn = resource->session; 467 DavSession *sn = resource->session;
261 468

mercurial