moves auth prompt functionality to libidav

Mon, 18 Dec 2017 11:56:11 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Mon, 18 Dec 2017 11:56:11 +0100
changeset 354
067ea2315a8a
parent 353
e554f3d72d9e
child 355
5da2cf15eb44

moves auth prompt functionality to libidav

dav/main.c file | annotate | diff | comparison | revisions
libidav/crypto.c file | annotate | diff | comparison | revisions
libidav/davqlexec.c file | annotate | diff | comparison | revisions
libidav/methods.c file | annotate | diff | comparison | revisions
libidav/methods.h file | annotate | diff | comparison | revisions
libidav/resource.c file | annotate | diff | comparison | revisions
libidav/session.c file | annotate | diff | comparison | revisions
libidav/session.h file | annotate | diff | comparison | revisions
libidav/webdav.c file | annotate | diff | comparison | revisions
libidav/webdav.h file | annotate | diff | comparison | revisions
--- a/dav/main.c	Tue Dec 12 23:58:54 2017 +0100
+++ b/dav/main.c	Mon Dec 18 11:56:11 2017 +0100
@@ -239,15 +239,9 @@
     fprintf(stderr, "\n");
 }
 
-int request_auth(Repository *repo, DavSession *sn, CmdArgs *a) {
-    if(cmd_getoption(a, "noinput")) {
-        return 0;
-    }
-    
-    static int login = 0;
-    if(login) {
-        return 0;
-    }
+
+int request_auth2(DavSession *sn, void *userdata) {
+    Repository *repo = userdata;
     
     char *user = NULL;
     char ubuf[256];
@@ -274,8 +268,8 @@
     
     dav_session_set_auth(sn, user, password);
     free(password);
-    login = 1;
-    return 1;
+    
+    return 0;
 }
 
 static Repository* url2repo(char *url, char **path) {
@@ -374,6 +368,9 @@
         curl_easy_setopt(sn->handle, CURLOPT_SSL_VERIFYPEER, 0);
         curl_easy_setopt(sn->handle, CURLOPT_SSL_VERIFYHOST, 0);
     }
+    if(!cmd_getoption(a, "noinput")) {
+        dav_session_set_authcallback(sn, request_auth2, repo);
+    }
     return sn;
 }
 
@@ -405,25 +402,13 @@
     
     int depth = cmd_getoption(a, "recursive") ? -1 : 1;
     int ret = -1;
-    DavResource *ls;
-    while(ret != 0) {
-        ls = dav_query(
-                sn,
-                date ? LIST_QUERY_ORDER_BY_DATE : LIST_QUERY_ORDER_BY_NAME,
-                path,
-                depth,
-                t);
-        
-        if(!ls) {
-            if(sn->error == DAV_UNAUTHORIZED) {
-                if(request_auth(repo, sn, a)) {
-                    continue;
-                }
-            }
-            print_resource_error(sn, path);
-            break;
-        }
-        
+    DavResource *ls = dav_query(
+            sn,
+            date ? LIST_QUERY_ORDER_BY_DATE : LIST_QUERY_ORDER_BY_NAME,
+            path,
+            depth,
+            t);
+    if(ls) {
         // parameters
         void (*print_func)(DavResource*, char *, CmdArgs *);
         if(cmd_getoption(a, "list") || cmd_getoption(a, "extended")) {
@@ -437,9 +422,8 @@
             print_func(child, path, a);
             child = child->next;
         }
-        
-        // leave loop
-        ret = 0;
+    } else {
+        print_resource_error(sn, path);
     }
     
     free(path);
@@ -689,21 +673,12 @@
     DavResource *res;
     
     int depth = recursive ? -1 : 1;
-    for(int i=0;i<2;i++) {
-        res = dav_query(
-                sn,
-                "select - from %s with depth = %d where iscollection or lastmodified > %t",
-                path,
-                depth,
-                t);
-        if(!res && sn->error == DAV_UNAUTHORIZED) {
-            if(request_auth(repo, sn, a)) {
-                continue;
-            }
-        }
-        break;
-    }
-    
+    res = dav_query(
+            sn,
+            "select - from %s with depth = %d where iscollection or lastmodified > %t",
+            path,
+            depth,
+            t);
     if(!res) {
         print_resource_error(sn, path);
         return -1;
@@ -1059,16 +1034,7 @@
         return -1;
     }
     
-    DavResource *col = NULL;
-    for(int i=0;i<2;i++) {
-        col = dav_query(sn, "select - from %s", path);
-        if(!col && sn->error == DAV_UNAUTHORIZED) {
-            if(request_auth(repo, sn, a)) {
-                continue;
-            }
-        }
-        break;
-    }
+    DavResource *col = dav_query(sn, "select - from %s", path);
     if(!col) {
         if(sn->error == DAV_NOT_FOUND) {
             col = dav_resource_new(sn, path);
@@ -1137,16 +1103,7 @@
 }
 
 int put_file(Repository *repo, CmdArgs *a, DavSession *sn, char *path, char *name, FILE *in, off_t len) {
-    DavResource *res = NULL;
-    for(int i=0;i<2;i++) {
-        res = dav_query(sn, "select - from %s", path);
-        if(!res && sn->error == DAV_UNAUTHORIZED) {
-            if(request_auth(repo, sn, a)) {
-                continue;
-            }
-        }
-        break;
-    }
+    DavResource *res = dav_query(sn, "select - from %s", path);
     
     if(!res) {
         if(sn->error == DAV_NOT_FOUND) {
@@ -1220,17 +1177,7 @@
         return -1;
     }
     
-    int err = 0;
-    for(int i=0;i<2;i++) {
-        err = dav_delete(res);
-        if(err && sn->error == DAV_UNAUTHORIZED && request_auth(repo, sn, a)) {
-            continue;
-        } else {
-            break;
-        }
-    }
-    
-    if(err) {
+    if(dav_delete(res)) {
         print_resource_error(sn, res->path);
         fprintf(stderr, "Cannot delete resource.\n");
         return -1;
@@ -1278,17 +1225,7 @@
     }
     res->iscollection = 1;
     
-    int err = 0;
-    for(int i=0;i<2;i++) {
-        err = dav_create(res);
-        if(err && sn->error == DAV_UNAUTHORIZED && request_auth(repo, sn, a)) {
-            continue;
-        } else {
-            break;
-        }
-    }
-    
-    if(err) {
+    if(dav_create(res)) {
         print_resource_error(sn, res->path);
         fprintf(stderr, "Cannot create collection.\n");
         return -1;
@@ -1444,15 +1381,9 @@
     }
     
     DavResource *res = dav_resource_new(sn, path);
-    for(int i=0;i<2;i++) {     
-        if(dav_load_prop(res, &propname, 1)) {
-            if(i == 0 && sn->error == DAV_UNAUTHORIZED && request_auth(repo, sn, a)) {
-                continue;
-            }
-            print_resource_error(sn, res->path);
-            return -1;
-        }
-        break;
+    if(dav_load_prop(res, &propname, 1)) {
+        print_resource_error(sn, res->path);
+        return -1;
     }
     free(path);
     
@@ -1498,14 +1429,9 @@
     set_session_lock(sn, a);
     
     DavResource *res = dav_resource_new(sn, path);
-    for(int i=0;i<2;i++) {
-        if(!dav_exists(res)) {
-            if(i == 0 && sn->error == DAV_UNAUTHORIZED && request_auth(repo, sn, a)) {
-                continue;
-            }
-            print_resource_error(sn, res->path);
-            return -1;
-        }
+    if(!dav_exists(res)) {
+        print_resource_error(sn, res->path);
+        return -1;
     }
     
     char *namespace = cmd_getoption(a, "namespace");
@@ -1519,16 +1445,10 @@
     }
     
     int ret = 0;
-    for(int i=0;i<2;i++) {
-        if(dav_store(res)) {
-            if(i == 0 && sn->error == DAV_UNAUTHORIZED && request_auth(repo, sn, a)) {
-                continue;
-            }
-            print_resource_error(sn, res->path);
-            fprintf(stderr, "Cannot set property.\n");
-            ret = -1;
-        }
-        break;
+    if(dav_store(res)) {
+        print_resource_error(sn, res->path);
+        fprintf(stderr, "Cannot set property.\n");
+        ret = -1;
     }
     
     free(path);
@@ -1565,16 +1485,11 @@
     int ret = 0;
     DavResource *res = dav_resource_new(sn, path);
     dav_remove_property_ns(res, propname.ns, propname.name);
-    for(int i=0;i<2;i++) {     
-        if(dav_store(res)) {
-            if(i == 0 && sn->error == DAV_UNAUTHORIZED && request_auth(repo, sn, a)) {
-                continue;
-            }
-            print_resource_error(sn, res->path);
-            fprintf(stderr, "Cannot set property.\n");
-            ret = -1;
-        }
-        break;
+    
+    if(dav_store(res)) {
+        print_resource_error(sn, res->path);
+        fprintf(stderr, "Cannot set property.\n");
+        ret = -1;
     }
     
     free(path);
@@ -1609,13 +1524,7 @@
     }
     
     DavResource *res = dav_resource_new(sn, path);
-    for(int i=0;i<2;i++) {
-        if(!dav_lock_t(res, timeout)) {
-            break;
-        }
-        if(i == 0 && sn->error == DAV_UNAUTHORIZED && request_auth(repo, sn, a)) {
-            continue;
-        }
+    if(dav_lock_t(res, timeout)) {
         print_resource_error(sn, res->path);
         return -1;
     }
@@ -1686,16 +1595,9 @@
     
     int ret = 0;
     DavResource *res = dav_resource_new(sn, path);
-    for(int i=0;i<2;i++) {
-        if(!dav_unlock(res)) {
-            break;
-        }
-        if(i == 0 && sn->error == DAV_UNAUTHORIZED && request_auth(repo, sn, a)) {
-            continue;
-        }
+    if(dav_unlock(res)) {
         print_resource_error(sn, res->path);
         ret = -1;
-        break;
     }
     
     dav_session_destroy(sn);
@@ -1729,57 +1631,52 @@
     }
     
     DavResource *res = dav_resource_new(sn, path);
-    for(int i=0;i<2;i++) {
-        if(!dav_load(res)) {
-            printf("name: %s\n", res->name);
-            printf("path: %s\n", res->path);
+    if(!dav_load(res)) {
+        printf("name: %s\n", res->name);
+        printf("path: %s\n", res->path);
+
+        char *server = util_url_base(sn->base_url);
+        char *url = util_concat_path(server, res->href);
+        printf("url:  %s\n", url);
+        free(url);
+        free(server);
 
-            char *server = util_url_base(sn->base_url);
-            char *url = util_concat_path(server, res->href);
-            printf("url:  %s\n", url);
-            free(url);
-            free(server);
+        if(res->iscollection) {
+            printf("type: collection\n");
+            printf("size: %d\n", count_children(res));
+        } else {
+            printf("type: resource\n");
+            char *len = ls_size_str(res);
+            printf("size: %s\n", len);
+            free(len);
+        }
 
-            if(res->iscollection) {
-                printf("type: collection\n");
-                printf("size: %d\n", count_children(res));
-            } else {
-                printf("type: resource\n");
-                char *len = ls_size_str(res);
-                printf("size: %s\n", len);
-                free(len);
+        size_t count = 0;
+        DavPropName *properties = dav_get_property_names(res, &count);
+
+        char *last_ns = NULL;
+        for(int i=0;i<count;i++) {
+            DavPropName p = properties[i];
+            if(!last_ns || strcmp(last_ns, p.ns)) {
+                printf("\nnamespace: %s\n", p.ns);
+                last_ns = p.ns;
             }
 
-            size_t count = 0;
-            DavPropName *properties = dav_get_property_names(res, &count);
+            DavXmlNode *xval = dav_get_property_ns(res, p.ns, p.name);
+            if(dav_xml_isstring(xval)) {
+                sstr_t value = sstr(dav_xml_getstring(xval));
+                printf("  %s: %.*s\n", p.name, (int)value.length, value.ptr);
+            } else {
+                printf("  %s: $xml\n", p.name);
+            }
+        }
 
-            char *last_ns = NULL;
-            for(int i=0;i<count;i++) {
-                DavPropName p = properties[i];
-                if(!last_ns || strcmp(last_ns, p.ns)) {
-                    printf("\nnamespace: %s\n", p.ns);
-                    last_ns = p.ns;
-                }
-                
-                DavXmlNode *xval = dav_get_property_ns(res, p.ns, p.name);
-                if(dav_xml_isstring(xval)) {
-                    sstr_t value = sstr(dav_xml_getstring(xval));
-                    printf("  %s: %.*s\n", p.name, (int)value.length, value.ptr);
-                } else {
-                    printf("  %s: $xml\n", p.name);
-                }
-            }
-
-            dav_session_free(sn, properties);
-            return 0;
-        } else {
-            if(i == 0 && sn->error == DAV_UNAUTHORIZED && request_auth(repo, sn, a)) {
-                continue;
-            }
-            print_resource_error(sn, res->path);
-            break;
-        }
+        dav_session_free(sn, properties);
+        return 0;
+    } else {
+        print_resource_error(sn, res->path);
     }
+        
     return -1;
 }
 
--- a/libidav/crypto.c	Tue Dec 12 23:58:54 2017 +0100
+++ b/libidav/crypto.c	Mon Dec 18 11:56:11 2017 +0100
@@ -328,7 +328,7 @@
 }
 
 
-void dav_get_hash(SHA_CTX *sha256, unsigned char *buf) {
+void dav_get_hash(DAV_SHA_CTX *sha256, unsigned char *buf){
     SHA256_Final((unsigned char*)buf, sha256);
 }
 
--- a/libidav/davqlexec.c	Tue Dec 12 23:58:54 2017 +0100
+++ b/libidav/davqlexec.c	Mon Dec 18 11:56:11 2017 +0100
@@ -488,7 +488,7 @@
         DavResource *root = sr->resource;
         
         util_set_url(sn, dav_resource_get_href(sr->resource));
-        CURLcode ret = do_propfind_request(sn->handle, rqbuf, rpbuf);
+        CURLcode ret = do_propfind_request(sn, rqbuf, rpbuf);
         long http_status = 0;
         curl_easy_getinfo(sn->handle, CURLINFO_RESPONSE_CODE, &http_status);
         //printf("rpbuf: %s %s\n%.*s\n\n", sr->resource->path, sr->resource->href, rpbuf->pos, rpbuf->space);
--- a/libidav/methods.c	Tue Dec 12 23:58:54 2017 +0100
+++ b/libidav/methods.c	Mon Dec 18 11:56:11 2017 +0100
@@ -43,10 +43,11 @@
 /* ----------------------------- PROPFIND ----------------------------- */
 
 CURLcode do_propfind_request(
-        CURL *handle,
+        DavSession *sn,
         UcxBuffer *request,
         UcxBuffer *response)
 {
+    CURL *handle = sn->handle;
     curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, "PROPFIND");
     
     // always try to get information about possible children
@@ -81,7 +82,7 @@
         // reset buffers and perform request
         request->pos = 0;
         response->size = response->pos = 0;
-        ret = curl_easy_perform(handle);
+        ret = dav_session_curl_perform_buf(sn, request, response, NULL);
         curl_slist_free_all(headers);
         headers = NULL;
         
@@ -709,11 +710,12 @@
 /* ----------------------------- PROPPATCH ----------------------------- */
 
 CURLcode do_proppatch_request(
-        CURL *handle,
+        DavSession *sn,
         char *lock,
         UcxBuffer *request,
         UcxBuffer *response)
 {  
+    CURL *handle = sn->handle;
     curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, "PROPPATCH");
     
     struct curl_slist *headers = NULL;
@@ -737,7 +739,7 @@
     curl_easy_setopt(handle, CURLOPT_WRITEDATA, response);
     
     ucx_buffer_seek(request, 0, SEEK_SET);
-    CURLcode ret = curl_easy_perform(handle);
+    CURLcode ret = dav_session_curl_perform_buf(sn, request, response, NULL);
     curl_slist_free_all(headers);
     return ret;
 }
@@ -915,7 +917,8 @@
     return s*n;
 }
 
-CURLcode do_put_request(CURL *handle, char *lock, DavBool create, void *data, dav_read_func read_func, size_t length) {
+CURLcode do_put_request(DavSession *sn, char *lock, DavBool create, void *data, dav_read_func read_func, size_t length) {
+    CURL *handle = sn->handle;
     curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, NULL);
     curl_easy_setopt(handle, CURLOPT_UPLOAD, 1L);
     
@@ -959,7 +962,7 @@
     curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, dummy_write);
     curl_easy_setopt(handle, CURLOPT_WRITEDATA, NULL);
     
-    CURLcode ret = curl_easy_perform(handle);
+    CURLcode ret = dav_session_curl_perform(sn, NULL);
     curl_slist_free_all(headers);
     if(buf) {
         ucx_buffer_free(buf);
@@ -968,7 +971,8 @@
     return ret;
 }
 
-CURLcode do_delete_request(CURL *handle, char *lock, UcxBuffer *response) { 
+CURLcode do_delete_request(DavSession *sn, char *lock, UcxBuffer *response) { 
+    CURL *handle = sn->handle;
     struct curl_slist *headers = NULL;
     if(lock) {
         char *url = NULL;
@@ -987,12 +991,13 @@
     curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, ucx_buffer_write);
     curl_easy_setopt(handle, CURLOPT_WRITEDATA, response);
     
-    CURLcode ret = curl_easy_perform(handle);
+    CURLcode ret = dav_session_curl_perform(sn, NULL);
     curl_slist_free_all(headers);
     return ret;
 }
 
-CURLcode do_mkcol_request(CURL *handle, char *lock) {
+CURLcode do_mkcol_request(DavSession *sn, char *lock) {
+    CURL *handle = sn->handle;
     struct curl_slist *headers = NULL;
     if(lock) {
         char *url = NULL;
@@ -1014,13 +1019,14 @@
     curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, dummy_write);
     curl_easy_setopt(handle, CURLOPT_WRITEDATA, NULL);
     
-    CURLcode ret = curl_easy_perform(handle);
+    CURLcode ret = dav_session_curl_perform(sn, NULL);
     curl_slist_free_all(headers);
     return ret;
 }
 
 
-CURLcode do_head_request(CURL *handle) {
+CURLcode do_head_request(DavSession *sn) {
+    CURL *handle = sn->handle;
     curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, "HEAD");
     curl_easy_setopt(handle, CURLOPT_UPLOAD, 0L);
     curl_easy_setopt(handle, CURLOPT_NOBODY, 1L);
@@ -1032,13 +1038,14 @@
     curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, dummy_write);
     curl_easy_setopt(handle, CURLOPT_WRITEDATA, NULL);
     
-    CURLcode ret = curl_easy_perform(handle);
+    CURLcode ret = dav_session_curl_perform(sn, NULL);
     curl_easy_setopt(handle, CURLOPT_NOBODY, 0L);
     return ret;
 }
 
 
-CURLcode do_copy_move_request(CURL *handle, char *dest, char *lock, DavBool copy, DavBool override) { 
+CURLcode do_copy_move_request(DavSession *sn, char *dest, char *lock, DavBool copy, DavBool override) { 
+    CURL *handle = sn->handle;
     if(copy) {
         curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, "COPY");
     } else {
@@ -1068,7 +1075,7 @@
     }
     curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
     
-    CURLcode ret = curl_easy_perform(handle);
+    CURLcode ret = dav_session_curl_perform(sn, NULL);
     free(deststr.ptr);
     curl_slist_free_all(headers);
     headers = NULL;
@@ -1156,7 +1163,8 @@
     return ret;
 }
 
-CURLcode do_lock_request(CURL *handle, UcxBuffer *request, UcxBuffer *response, time_t timeout) { 
+CURLcode do_lock_request(DavSession *sn, UcxBuffer *request, UcxBuffer *response, time_t timeout) { 
+    CURL *handle = sn->handle;
     curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, "LOCK");  
     curl_easy_setopt(handle, CURLOPT_UPLOAD, 1L);
     request->pos = 0;
@@ -1184,7 +1192,7 @@
     curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, ucx_buffer_write);
     curl_easy_setopt(handle, CURLOPT_WRITEDATA, response);
     
-    CURLcode ret = curl_easy_perform(handle);
+    CURLcode ret = dav_session_curl_perform_buf(sn, request, response, NULL);
     
     if(headers) {
         curl_slist_free_all(headers);
@@ -1193,7 +1201,8 @@
     return ret;
 }
 
-CURLcode do_unlock_request(CURL *handle, char *locktoken) {   
+CURLcode do_unlock_request(DavSession *sn, char *locktoken) {   
+    CURL *handle = sn->handle;
     curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, "UNLOCK");
     curl_easy_setopt(handle, CURLOPT_UPLOAD, 0L);
     
@@ -1205,7 +1214,7 @@
     struct curl_slist *headers = curl_slist_append(NULL, ltheader.ptr);
     curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
     
-    CURLcode ret = curl_easy_perform(handle);
+    CURLcode ret = dav_session_curl_perform(sn, NULL);
     curl_slist_free_all(headers);
     free(ltheader.ptr);
     
--- a/libidav/methods.h	Tue Dec 12 23:58:54 2017 +0100
+++ b/libidav/methods.h	Mon Dec 18 11:56:11 2017 +0100
@@ -61,18 +61,18 @@
 };
 
 CURLcode do_propfind_request(
-        CURL *handle,
+        DavSession *sn,
         UcxBuffer *request,
         UcxBuffer *response);
 
 CURLcode do_proppatch_request(
-        CURL *handle,
+        DavSession *sn,
         char *lock,
         UcxBuffer *request,
         UcxBuffer *response);
 
 CURLcode do_put_request(
-        CURL *handle,
+        DavSession *sn,
         char *lock,
         DavBool create,
         void *data,
@@ -105,18 +105,18 @@
 UcxBuffer* create_proppatch_request(DavResourceData *data);
 UcxBuffer* create_crypto_proppatch_request(DavSession *sn, DavKey *key, char *name, char *hash);
 
-CURLcode do_delete_request(CURL *handle, char *lock, UcxBuffer *response);
+CURLcode do_delete_request(DavSession *sn, char *lock, UcxBuffer *response);
 
-CURLcode do_mkcol_request(CURL *handle, char *lock);
+CURLcode do_mkcol_request(DavSession *sn, char *lock);
 
-CURLcode do_head_request(CURL *handle);
+CURLcode do_head_request(DavSession *sn);
 
-CURLcode do_copy_move_request(CURL *handle, char *dest, char *lock, DavBool copy, DavBool override);
+CURLcode do_copy_move_request(DavSession *sn, char *dest, char *lock, DavBool copy, DavBool override);
 
 UcxBuffer* create_lock_request(void);
 int parse_lock_response(DavSession *sn, UcxBuffer *response, LockDiscovery *lock);
-CURLcode do_lock_request(CURL *handle, UcxBuffer *request, UcxBuffer *response, time_t timeout);
-CURLcode do_unlock_request(CURL *handle, char *locktoken);
+CURLcode do_lock_request(DavSession *sn, UcxBuffer *request, UcxBuffer *response, time_t timeout);
+CURLcode do_unlock_request(DavSession *sn, char *locktoken);
 
 #ifdef	__cplusplus
 }
--- a/libidav/resource.c	Tue Dec 12 23:58:54 2017 +0100
+++ b/libidav/resource.c	Mon Dec 18 11:56:11 2017 +0100
@@ -656,7 +656,7 @@
               
             // put resource
             ret = do_put_request(
-                    sn->handle,
+                    sn,
                     locktoken,
                     TRUE,
                     enc,
@@ -683,7 +683,7 @@
             free(enc_hash);
         } else {
             ret = do_put_request(
-                    sn->handle,
+                    sn,
                     locktoken,
                     TRUE,
                     data->content,
@@ -716,7 +716,7 @@
         UcxBuffer *response = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND);
         //printf("request:\n%.*s\n\n", request->pos, request->space);
 
-        CURLcode ret = do_proppatch_request(sn->handle, locktoken, request, response);
+        CURLcode ret = do_proppatch_request(sn, locktoken, request, response);
         long status = 0;
         curl_easy_getinfo (sn->handle, CURLINFO_RESPONSE_CODE, &status);
         if(ret == CURLE_OK && status == 207) {
@@ -765,7 +765,8 @@
     curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_fnc);
     curl_easy_setopt(handle, CURLOPT_WRITEDATA, stream);
     
-    CURLcode ret = curl_easy_perform(handle);
+    long status = 0;
+    CURLcode ret = dav_session_curl_perform(sn, &status);
     
     char *hash = NULL;
     if(dec) {
@@ -779,8 +780,6 @@
         aes_decrypter_close(dec);
     }
     
-    long status = 0;
-    curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
     if(ret == CURLE_OK && (status >= 200 && status < 300)) {
         int verify_failed = 0;
         if(DAV_DECRYPT_CONTENT(sn) && key) {
@@ -836,7 +835,7 @@
     char *locktoken = lock ? lock->token : NULL;
     
     UcxBuffer *response = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND);
-    CURLcode ret = do_delete_request(handle, locktoken, response);
+    CURLcode ret = do_delete_request(res->session, locktoken, response);
     long status = 0;
     curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
     int r = 0;
@@ -873,7 +872,7 @@
     
     for(int i=0;i<2;i++) {
         util_set_url(sn, h);
-        code = do_mkcol_request(handle, locktoken);
+        code = do_mkcol_request(sn, locktoken);
         curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &status);
         if(status == 201) {
             // resource successfully created
@@ -918,9 +917,9 @@
     
     CURLcode code;
     if(res->iscollection) {
-        code = do_mkcol_request(handle, locktoken);
+        code = do_mkcol_request(sn, locktoken);
     } else {
-        code = do_put_request(handle, locktoken, TRUE, "", NULL, 0); 
+        code = do_put_request(sn, locktoken, TRUE, "", NULL, 0); 
     }
     long s = 0;
     curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &s);
@@ -965,7 +964,7 @@
     CURL *handle = sn->handle;
     util_set_url(sn, dav_resource_get_href(res));
     
-    CURLcode ret = do_head_request(handle);
+    CURLcode ret = do_head_request(sn);
     long status = 0;
     curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
     if(ret == CURLE_OK && (status >= 200 && status < 300)) {
@@ -984,7 +983,7 @@
     DavLock *lock = dav_get_lock(sn, res->path);
     char *locktoken = lock ? lock->token : NULL;
     
-    CURLcode ret = do_copy_move_request(handle, desturl, locktoken, copy, override);
+    CURLcode ret = do_copy_move_request(sn, desturl, locktoken, copy, override);
     
     long status = 0;
     curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
@@ -1041,7 +1040,7 @@
     
     UcxBuffer *request = create_lock_request();
     UcxBuffer *response = ucx_buffer_new(NULL, 512, UCX_BUFFER_AUTOEXTEND);
-    CURLcode ret = do_lock_request(handle, request, response, timeout);
+    CURLcode ret = do_lock_request(sn, request, response, timeout);
     
     //printf("\nlock\n");
     //printf("%.*s\n\n", request->size, request->space);
@@ -1097,7 +1096,7 @@
         return -1;
     }
     
-    CURLcode ret = do_unlock_request(handle, lock->token);
+    CURLcode ret = do_unlock_request(sn, lock->token);
     long status = 0;
     curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
     if(ret == CURLE_OK && (status >= 200 && status < 300)) {
@@ -1121,7 +1120,7 @@
     
     util_set_url(sn, href);
     // TODO: lock
-    CURLcode ret = do_proppatch_request(sn->handle, NULL, request, response);
+    CURLcode ret = do_proppatch_request(sn, NULL, request, response);
     ucx_buffer_free(request);
     long status = 0;
     curl_easy_getinfo (sn->handle, CURLINFO_RESPONSE_CODE, &status);
--- a/libidav/session.c	Tue Dec 12 23:58:54 2017 +0100
+++ b/libidav/session.c	Mon Dec 18 11:56:11 2017 +0100
@@ -140,6 +140,37 @@
     }
 }
 
+void dav_session_set_authcallback(DavSession *sn, dav_auth_func func, void *userdata) {
+    sn->auth_prompt = func;
+    sn->authprompt_userdata = userdata;
+}
+
+CURLcode dav_session_curl_perform(DavSession *sn, long *status) {
+    return dav_session_curl_perform_buf(sn, NULL, NULL, status);
+}
+
+CURLcode dav_session_curl_perform_buf(DavSession *sn, UcxBuffer *request, UcxBuffer *response, long *status) {
+    CURLcode ret = curl_easy_perform(sn->handle);
+    long http_status;
+    curl_easy_getinfo(sn->handle, CURLINFO_RESPONSE_CODE, &http_status);
+    if(ret == CURLE_OK && http_status == 401 && sn->auth_prompt) {
+        if(!sn->auth_prompt(sn, sn->authprompt_userdata)) {
+            if(request) {
+                ucx_buffer_seek(request, 0, SEEK_SET);
+            }
+            if(response) {
+                ucx_buffer_seek(response, 0, SEEK_SET);
+            }
+            ret = curl_easy_perform(sn->handle);
+            curl_easy_getinfo(sn->handle, CURLINFO_RESPONSE_CODE, &http_status);
+        }
+    }
+    if(status) {
+        *status = http_status;
+    }
+    return ret;
+}
+
 void dav_session_set_error(DavSession *sn, CURLcode c, int status) {
     if(status > 0) {
         switch(status) {
--- a/libidav/session.h	Tue Dec 12 23:58:54 2017 +0100
+++ b/libidav/session.h	Mon Dec 18 11:56:11 2017 +0100
@@ -29,6 +29,7 @@
 #ifndef DAV_SESSION_H
 #define	DAV_SESSION_H
 
+#include <ucx/buffer.h>
 #include "webdav.h"
 
 #ifdef	__cplusplus
@@ -78,6 +79,9 @@
     UcxList *collection_locks;
 } DavLockManager;
 
+CURLcode dav_session_curl_perform(DavSession *sn, long *status);
+CURLcode dav_session_curl_perform_buf(DavSession *sn, UcxBuffer *request, UcxBuffer *response, long *status);
+
 void dav_session_set_error(DavSession *sn, CURLcode c, int status);
 void dav_session_set_errstr(DavSession *sn, const char *str);
 
--- a/libidav/webdav.c	Tue Dec 12 23:58:54 2017 +0100
+++ b/libidav/webdav.c	Mon Dec 18 11:56:11 2017 +0100
@@ -277,7 +277,7 @@
     //fwrite(rqbuf->space, 1, rqbuf->size, stdout);
     //printf("\n");
     
-    CURLcode ret = do_propfind_request(handle, rqbuf, rpbuf);
+    CURLcode ret = do_propfind_request(sn, rqbuf, rpbuf);
     long status = 0;
     curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
     if(ret == CURLE_OK && status == 207) {
@@ -316,7 +316,7 @@
      
     UcxBuffer *rpbuf = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND);
     DavResource *resource = root;
-    CURLcode ret = do_propfind_request(handle, rqbuf, rpbuf);
+    CURLcode ret = do_propfind_request(sn, rqbuf, rpbuf);
     long status = 0;
     long error = 0;
     curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
--- a/libidav/webdav.h	Tue Dec 12 23:58:54 2017 +0100
+++ b/libidav/webdav.h	Mon Dec 18 11:56:11 2017 +0100
@@ -63,6 +63,8 @@
 typedef size_t(*dav_read_func)(void*, size_t, size_t, void*);
 typedef size_t(*dav_write_func)(const void*, size_t, size_t, void*);
 
+typedef int(*dav_auth_func)(DavSession *, void *);
+
 enum DavError {
     DAV_OK = 0,
     DAV_ERROR,
@@ -140,12 +142,15 @@
     uint32_t      flags;
     DavError      error;
     char          *errorstr;
+    
+    int(*auth_prompt)(DavSession *sn, void *userdata);
+    void *authprompt_userdata;
 };
 
 struct DavContext {
-    UcxMap  *namespaces;
-    UcxMap  *keys;
-    UcxList *sessions;
+    UcxMap   *namespaces;
+    UcxMap   *keys;
+    UcxList  *sessions;
     DavProxy *http_proxy;
     DavProxy *https_proxy;
 };
@@ -218,6 +223,8 @@
 void dav_session_set_auth(DavSession *sn, char *user, char *password);
 void dav_session_enable_encryption(DavSession *sn, DavKey *key, int flags);
 
+void dav_session_set_authcallback(DavSession *sn, dav_auth_func func, void *userdata);
+
 void dav_session_destroy(DavSession *sn);
 
 void* dav_session_malloc(DavSession *sn, size_t size);

mercurial