libidav/webdav.c

changeset 135
664aeaec8d25
parent 134
4bccc18820e8
child 147
458a8dc68048
equal deleted inserted replaced
134:4bccc18820e8 135:664aeaec8d25
33 33
34 #include "utils.h" 34 #include "utils.h"
35 #include "webdav.h" 35 #include "webdav.h"
36 #include "session.h" 36 #include "session.h"
37 #include "methods.h" 37 #include "methods.h"
38 #include "davql.h"
39 #include "ucx/buffer.h" 38 #include "ucx/buffer.h"
40 #include "ucx/utils.h" 39 #include "ucx/utils.h"
40 #include "davqlparser.h"
41 #include "davqlexec.h"
41 42
42 43
43 DavContext* dav_context_new() { 44 DavContext* dav_context_new() {
44 // initialize 45 // initialize
45 DavContext *context = calloc(1, sizeof(DavContext)); 46 DavContext *context = calloc(1, sizeof(DavContext));
280 CURLcode ret = do_propfind_request(handle, rqbuf, rpbuf); 281 CURLcode ret = do_propfind_request(handle, rqbuf, rpbuf);
281 int status = 0; 282 int status = 0;
282 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); 283 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
283 if(ret == CURLE_OK && status == 207) { 284 if(ret == CURLE_OK && status == 207) {
284 //printf("response\n%s\n", rpbuf->space); 285 //printf("response\n%s\n", rpbuf->space);
285 resource = parse_propfind_response(sn, resource, rpbuf, NULL, 0); 286 // TODO: use PropfindParser
287 resource = parse_propfind_response(sn, resource, rpbuf);
286 sn->error = DAV_OK; 288 sn->error = DAV_OK;
287 } else { 289 } else {
288 dav_session_set_error(sn, ret, status); 290 dav_session_set_error(sn, ret, status);
289 dav_resource_free(resource); 291 dav_resource_free(resource);
290 resource = NULL; 292 resource = NULL;
294 ucx_buffer_free(rpbuf); 296 ucx_buffer_free(rpbuf);
295 297
296 return resource; 298 return resource;
297 } 299 }
298 300
299 int dav_propfind(DavSession *sn, DavResource *root, UcxBuffer *rqbuf, DavQOp *cond, size_t len) { 301
302 int dav_propfind(DavSession *sn, DavResource *root, UcxBuffer *rqbuf) {
300 // clean resource properties 303 // clean resource properties
301 DavResourceData *data = root->data; 304 DavResourceData *data = root->data;
302 size_t pcount = data->properties->count; 305 size_t pcount = data->properties->count;
303 if(pcount > 0) { 306 if(pcount > 0) {
304 UcxKey key; 307 UcxKey key;
324 int status = 0; 327 int status = 0;
325 int error = 0; 328 int error = 0;
326 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); 329 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
327 if(ret == CURLE_OK && status == 207) { 330 if(ret == CURLE_OK && status == 207) {
328 //printf("response\n%s\n", rpbuf->space); 331 //printf("response\n%s\n", rpbuf->space);
329 resource = parse_propfind_response(sn, resource, rpbuf, cond, len); 332 resource = parse_propfind_response(sn, resource, rpbuf);
330 sn->error = DAV_OK; 333 sn->error = DAV_OK;
331 } else { 334 } else {
332 dav_session_set_error(sn, ret, status); 335 dav_session_set_error(sn, ret, status);
333 error = 1; 336 error = 1;
334 } 337 }
335 ucx_buffer_free(rpbuf); 338 ucx_buffer_free(rpbuf);
336 return error; 339 return error;
337 }
338
339 static UcxList* propfind_stack_push(UcxList *stack, DavResource *children) {
340 while(children) {
341 if(children->iscollection) {
342 stack = ucx_list_prepend(stack, children);
343 }
344 children = children->next;
345 }
346 return stack;
347 }
348
349 DavResource* dav_query_get(DavSession *sn, DavGetQuery *query) {
350 char *path;
351 int depth = query->depth;
352 /*
353 if(parse_path_query(query->from, &path, &depth)) {
354 sn->error = DAV_ERROR;
355 return NULL;
356 }
357 */
358 path = sstrdup(query->from).ptr;
359
360 sstr_t ps = query->properties;
361 UcxBuffer *rqbuf;
362 if(!sstrcmp(ps, S("*"))) {
363 rqbuf = create_allprop_propfind_request();
364 } else if(!sstrcmp(ps, S("-"))) {
365 rqbuf = create_propfind_request(sn, NULL);
366 } else {
367 UcxList *proplist = parse_properties_string(sn->context, ps);
368 rqbuf = create_propfind_request(sn, proplist);
369 UCX_FOREACH(elm, proplist) {
370 DavProperty *prop = elm->data;
371 free(prop->name);
372 free(prop);
373 }
374 ucx_list_free(proplist);
375 }
376
377 //fwrite(rqbuf->space, 1, rqbuf->size, stdout);
378 //printf("\n");
379
380 DavResource *resource = dav_resource_new(sn, path);
381 free(path);
382 if(dav_propfind(sn, resource, rqbuf, query->condition, query->condlen)) {
383 dav_resource_free(resource);
384 resource = NULL;
385 }
386
387 int error = 0;
388 if(resource && depth == -1) {
389 UcxList *stack = NULL; // stack with DavResource* elements
390 stack = propfind_stack_push(stack, resource->children);
391 while(stack) {
392 DavResource *sr = stack->data; // get first element from the stack
393 stack = ucx_list_remove(stack, stack); // remove first element
394 // do propfind request for sr
395 if(dav_propfind(sn, sr, rqbuf, query->condition, query->condlen)) {
396 error = 1;
397 printf("subrequest failed\n");
398 break;
399 }
400 stack = propfind_stack_push(stack, sr->children); // add children
401 }
402 }
403
404 ucx_buffer_free(rqbuf);
405 return resource;
406 } 340 }
407 341
408 UcxList* parse_properties_string(DavContext *context, sstr_t str) { 342 UcxList* parse_properties_string(DavContext *context, sstr_t str) {
409 UcxList *proplist = NULL; 343 UcxList *proplist = NULL;
410 ssize_t nprops = 0; 344 ssize_t nprops = 0;
433 free(props); 367 free(props);
434 return proplist; 368 return proplist;
435 } 369 }
436 370
437 DavResource* dav_query(DavSession *sn, char *query, ...) { 371 DavResource* dav_query(DavSession *sn, char *query, ...) {
372 DavQLStatement *stmt = dav_parse_statement(sstr(query));
373 if(!stmt) {
374 sn->error = DAV_ERROR;
375 return NULL;
376 }
377 if(stmt->errorcode != 0) {
378 sn->error = DAV_QL_ERROR;
379 dav_free_statement(stmt);
380 return NULL;
381 }
382
438 va_list ap; 383 va_list ap;
439 va_start(ap, query); 384 va_start(ap, query);
440 DavQuery q = dav_ql_parse(query, ap); 385 DavResult result = dav_statement_execv(sn, stmt, ap);
441 va_end(ap); 386 va_end(ap);
442 DavResource *res = NULL; 387
443 switch(q.command) { 388 dav_free_statement(stmt);
444 case DAV_QUERY_GET: { 389 return result.result;
445 res = dav_query_get(sn, q.command_data); 390 }
446 free_get_query(q.command_data); 391
447 break; 392
448 } 393
449 case DAV_QUERY_ERROR: { 394
450 // TODO
451 break;
452 }
453 }
454 return res;
455 }
456
457
458
459

mercurial