libidav/webdav.c

changeset 43
03076907b58a
parent 41
1c598ee0d3d9
child 45
e3839719b079
--- 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;
 }

mercurial