diff -r d18f92483945 -r e59a989d890d dav/sync.c --- 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,