dav/sync.c

changeset 541
e59a989d890d
parent 539
8deb52292c99
child 542
060a8cda7f62
--- a/dav/sync.c	Tue Mar 26 18:28:37 2019 +0100
+++ b/dav/sync.c	Thu Mar 28 11:19:13 2019 +0100
@@ -80,6 +80,7 @@
     { DAV_NS, "finfo" },
     { DAV_NS, "tags" },
     { DAV_NS, "xattributes" },
+    { DAV_NS, "content-hash" },
     { DAV_NS, "split" }
 };
 static size_t numdefprops = 6;
@@ -2042,6 +2043,7 @@
         {"DAV:", "getetag"},
         {DAV_NS, "tags"},
         {DAV_NS, "version-collection"},
+        {DAV_NS, "content-hash"},
         {DAV_NS, "split" }
     };
     int err = dav_load_prop(remote, properties, 4);
@@ -2053,7 +2055,12 @@
     int ret = 0;
     if(err == 0) {
         char *etag = dav_get_string_property(remote, "D:getetag");
-        if(!res->etag) {
+        char *hash = dav_get_string_property(remote, "idav:content-hash");
+        if(hash || res->hash) {
+            if(!nullstrcmp(hash, res->hash)) {
+                ret = 1;
+            }
+        } else if(!res->etag) {
             // the resource is on the server and the client has no etag
             ret = 1;
         } else if(etag) {
@@ -2735,7 +2742,11 @@
     uint32_t session_flags = res->session->flags;
     res->session->flags ^= DAV_SESSION_ENCRYPT_NAME;
     
+    DAV_SHA_CTX *sha = dav_hash_init();
+    
     while((r = fread(buffer, 1, blocksize, in)) > 0) {
+        dav_hash_update(sha, buffer, r);
+        
         int upload_block = 0;
         char *block_hash = dav_create_hash(buffer, r);
         if(blockindex >= local->numparts) {
@@ -2796,6 +2807,15 @@
         return NULL;
     }
     
+    // set content-hash
+    char content_hash[DAV_SHA256_DIGEST_LENGTH];
+    dav_hash_final(sha, content_hash);
+    char *hash_hex = util_hexstr(content_hash, DAV_SHA256_DIGEST_LENGTH);
+    dav_set_string_property_ns(res, DAV_NS, "content-hash", hash_hex);
+    local->hash = hash_hex;
+    
+    // get etags from uploaded resources
+    // also delete everything, that is not part of the file
     UcxList *updated_parts = NULL;
     DavResource *parts = dav_query(res->session, "select D:getetag from %s order by name", res->path);
     if(!parts) {
@@ -2932,6 +2952,11 @@
         dav_set_content(res, in, (dav_read_func)myread, (dav_seek_func)file_seek);
         dav_set_content_length(res, s.st_size);
     } else {
+        // set split property
+        char blocksize_str[32];
+        snprintf(blocksize_str, 32, "%zu", split_blocksize);
+        dav_set_string_property_ns(res, DAV_NS, "split", blocksize_str);
+        
         // splitted/partial upload
         parts = upload_parts(
                 local,

mercurial