--- a/libidav/webdav.c Tue Mar 18 13:59:02 2014 +0100 +++ b/libidav/webdav.c Thu Jun 05 15:11:29 2014 +0200 @@ -33,13 +33,13 @@ #include "utils.h" #include "webdav.h" +#include "session.h" #include "methods.h" #include "davql.h" #include "ucx/buffer.h" #include "ucx/utils.h" - DavContext* dav_context_new() { DavContext *context = malloc(sizeof(DavContext)); if(!context) { @@ -69,6 +69,24 @@ return NULL; } + DavNamespace *idavns = malloc(sizeof(DavNamespace)); + if(!idavns) { + free(davns); + ucx_map_free(context->namespaces); + free(context); + return NULL; + } + idavns->prefix = "idav"; + davns->name = DAV_NS; + if(ucx_map_cstr_put(context->namespaces, "idav", idavns)) { + free(davns); + free(idavns); + ucx_map_free(context->namespaces); + free(context); + return NULL; + } + + return context; } @@ -93,7 +111,11 @@ } DavKey* dav_context_get_key(DavContext *context, char *name) { - return ucx_map_cstr_get(context->keys, name); + if(name) { + return ucx_map_cstr_get(context->keys, name); + } else { + return NULL; + } } int dav_add_namespace(DavContext *context, char *prefix, char *name) { @@ -135,155 +157,18 @@ *name = pname; } -DavSession* dav_session_new(DavContext *context, char *base_url) { - if(!base_url) { - return NULL; - } - sstr_t url = sstr(base_url); - if(url.length == 0) { - return NULL; - } - DavSession *sn = malloc(sizeof(DavSession)); - sn->mp = ucx_mempool_new(1024); - sn->key = NULL; - sn->errorstr = NULL; - sn->error = DAV_OK; - sn->flags = 0; - if(url.ptr[url.length - 1] == '/') { - sstr_t url = sstrdup_a(sn->mp->allocator, sstr(base_url)); - sn->base_url = url.ptr; - } else { - char *url_str = malloc(url.length + 2); - memcpy(url_str, base_url, url.length); - url_str[url.length] = '/'; - url_str[url.length + 1] = '\0'; - sn->base_url = url_str; - } - sn->context = context; - sn->handle = curl_easy_init(); - //curl_easy_setopt(sn->handle, CURLOPT_VERBOSE, 1L); - //curl_easy_setopt(sn->handle, CURLOPT_STDERR, stderr); - curl_easy_setopt(sn->handle, CURLOPT_FOLLOWLOCATION, 1L); - - // set proxy - DavProxy *proxy = sstrprefix(url, S("https")) ? context->https_proxy - : context->http_proxy; - - if (proxy->url) { - curl_easy_setopt(sn->handle, CURLOPT_PROXY, proxy->url); - if (proxy->username) { - curl_easy_setopt(sn->handle, CURLOPT_PROXYUSERNAME, - proxy->username); - if (proxy->password) { - curl_easy_setopt(sn->handle, CURLOPT_PROXYPASSWORD, - proxy->password); - } else { - // TODO: prompt - } - } - if(proxy->no_proxy) { - curl_easy_setopt(sn->handle, CURLOPT_NOPROXY, - proxy->no_proxy); - } - } - - // set url - curl_easy_setopt(sn->handle, CURLOPT_URL, base_url); - - context->sessions = ucx_list_append(context->sessions, sn); - - return sn; -} - -DavSession* dav_session_new_auth( - DavContext *context, - char *base_url, - char *user, - char *password) -{ - DavSession *sn = dav_session_new(context, base_url); - if(!sn) { - return NULL; - } - dav_session_set_auth(sn, user, password); - return sn; -} - -void dav_session_set_auth(DavSession *sn, char *user, char *password) { - if(user && password) { - size_t ulen = strlen(user); - size_t plen = strlen(password); - size_t upwdlen = ulen + plen + 2; - char *upwdbuf = malloc(upwdlen); - snprintf(upwdbuf, upwdlen, "%s:%s\0", user, password); - curl_easy_setopt(sn->handle, CURLOPT_USERPWD, upwdbuf); - free(upwdbuf); - } -} - -void session_set_error(DavSession *sn, CURLcode c, int status) { - if(status > 0) { - switch(status) { - default: sn->error = DAV_ERROR; break; - case 401: sn->error = DAV_UNAUTHORIZED; break; - case 403: sn->error = DAV_FORBIDDEN; break; - case 404: sn->error = DAV_NOT_FOUND; break; - case 405: sn->error = DAV_METHOD_NOT_ALLOWED; break; - case 409: sn->error = DAV_CONFLICT; break; - } - } else { - sn->error = DAV_ERROR; - } - if(c != CURLE_OK) { - sn->errorstr = curl_easy_strerror(c); - } else { - sn->errorstr = NULL; - } -} - -void dav_session_destroy(DavSession *sn) { - // remove session from context - UcxList *sessions = sn->context->sessions; - ssize_t i = ucx_list_find(sessions, sn, ucx_ptrcmp, NULL); - if(i > 0) { - UcxList *elm = ucx_list_get(sessions, i); - if(elm) { - sn->context->sessions = ucx_list_remove(sessions, elm); - } - } - - ucx_mempool_destroy(sn->mp); - curl_easy_cleanup(sn->handle); - free(sn); -} - - -void* dav_session_malloc(DavSession *sn, size_t size) { - return ucx_mempool_malloc(sn->mp, size); -} - -void* dav_session_calloc(DavSession *sn, size_t nelm, size_t size) { - return ucx_mempool_calloc(sn->mp, nelm, size); -} - -void* dav_session_realloc(DavSession *sn, void *ptr, size_t size) { - return ucx_mempool_realloc(sn->mp, ptr, size); -} - -void dav_session_free(DavSession *sn, void *ptr) { - ucx_mempool_free(sn->mp, ptr); -} - DavResource* dav_get(DavSession *sn, char *path, char *properties) { CURL *handle = sn->handle; - util_set_url(sn, path); + char *href = dav_session_get_href(sn, path); + util_set_url(sn, href); + dav_session_free(sn, href); UcxList *proplist = NULL; if(properties) { proplist = parse_properties_string(sn->context, sstr(properties)); } - UcxBuffer *rqbuf = create_propfind_request(proplist); + UcxBuffer *rqbuf = create_propfind_request(sn, proplist); UcxBuffer *rpbuf = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND); //fwrite(rqbuf->space, 1, rqbuf->size, stdout); @@ -298,30 +183,46 @@ resource = parse_propfind_response(sn, NULL, rpbuf, NULL, 0); sn->error = DAV_OK; } else { - session_set_error(sn, ret, status); + dav_session_set_error(sn, ret, status); } + + ucx_buffer_free(rqbuf); + ucx_buffer_free(rpbuf); + return resource; } -DavResource* dav_propfind(DavSession *sn, DavResource *root, UcxBuffer *rqbuf, char *path, DavQOp *cond, size_t len) { +int dav_propfind(DavSession *sn, DavResource *root, UcxBuffer *rqbuf, DavQOp *cond, size_t len) { + // clean resource properties + DavResourceData *data = root->data; + if(data->properties->count > 0) { + UcxKey key; + void *value; + UcxMapIterator i = ucx_map_iterator(data->properties); + UCX_MAP_FOREACH(key, value, i) { + ucx_map_remove(data->properties, key); + } + } + CURL *handle = sn->handle; - util_set_url(sn, path); - + util_set_url(sn, dav_resource_get_href(root)); + UcxBuffer *rpbuf = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND); DavResource *resource = root; CURLcode ret = do_propfind_request(handle, rqbuf, rpbuf); int status = 0; + int error = 0; curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); if(ret == CURLE_OK && status == 207) { //printf("response\n%s\n", rpbuf->space); resource = parse_propfind_response(sn, resource, rpbuf, cond, len); sn->error = DAV_OK; } else { - session_set_error(sn, ret, status); - resource = NULL; + dav_session_set_error(sn, ret, status); + error = 1; } ucx_buffer_free(rpbuf); - return resource; + return error; } UcxList* propfind_stack_push(UcxList *stack, DavResource *children) { @@ -337,27 +238,36 @@ DavResource* dav_query_get(DavSession *sn, DavGetQuery *query) { char *path; int depth = 0; + /* if(parse_path_query(query->from, &path, &depth)) { sn->error = DAV_ERROR; return NULL; } + */ + path = sstrdup(query->from).ptr; sstr_t ps = query->properties; UcxBuffer *rqbuf; if(!sstrcmp(ps, S("*"))) { rqbuf = create_allprop_propfind_request(); } else if(!sstrcmp(ps, S("-"))) { - rqbuf = create_propfind_request(NULL); + rqbuf = create_propfind_request(sn, NULL); } else { UcxList *proplist = parse_properties_string(sn->context, ps); - rqbuf = create_propfind_request(proplist); + rqbuf = create_propfind_request(sn, proplist); } //fwrite(rqbuf->space, 1, rqbuf->size, stdout); //printf("\n"); - DavResource *resource = dav_propfind(sn, NULL, rqbuf, path, query->condition, query->condlen); + DavResource *resource = dav_resource_new(sn, path); free(path); + if(dav_propfind(sn, resource, rqbuf, query->condition, query->condlen)) { + dav_resource_free(resource); + resource = NULL; + } + ucx_buffer_free(rqbuf); + int error = 0; if(resource && depth == -1) { UcxList *stack = NULL; // stack with DavResource* elements @@ -366,8 +276,7 @@ DavResource *sr = stack->data; // get first element from the stack stack = ucx_list_remove(stack, stack); // remove first element // do propfind request for sr - sr = dav_propfind(sn, sr, rqbuf, sr->path, query->condition, query->condlen); - if(!sr) { + if(dav_propfind(sn, sr, rqbuf, query->condition, query->condlen)) { error = 1; printf("subrequest failed\n"); break; @@ -420,6 +329,10 @@ free_get_query(q.command_data); break; } + case DAV_QUERY_ERROR: { + // TODO + break; + } } return res; }