dav/sync.c

changeset 541
e59a989d890d
parent 539
8deb52292c99
child 542
060a8cda7f62
equal deleted inserted replaced
540:d18f92483945 541:e59a989d890d
78 { "DAV:", "getetag" }, 78 { "DAV:", "getetag" },
79 { DAV_NS, "status" }, 79 { DAV_NS, "status" },
80 { DAV_NS, "finfo" }, 80 { DAV_NS, "finfo" },
81 { DAV_NS, "tags" }, 81 { DAV_NS, "tags" },
82 { DAV_NS, "xattributes" }, 82 { DAV_NS, "xattributes" },
83 { DAV_NS, "content-hash" },
83 { DAV_NS, "split" } 84 { DAV_NS, "split" }
84 }; 85 };
85 static size_t numdefprops = 6; 86 static size_t numdefprops = 6;
86 87
87 /* 88 /*
2040 { 2041 {
2041 DavPropName properties[] = { 2042 DavPropName properties[] = {
2042 {"DAV:", "getetag"}, 2043 {"DAV:", "getetag"},
2043 {DAV_NS, "tags"}, 2044 {DAV_NS, "tags"},
2044 {DAV_NS, "version-collection"}, 2045 {DAV_NS, "version-collection"},
2046 {DAV_NS, "content-hash"},
2045 {DAV_NS, "split" } 2047 {DAV_NS, "split" }
2046 }; 2048 };
2047 int err = dav_load_prop(remote, properties, 4); 2049 int err = dav_load_prop(remote, properties, 4);
2048 2050
2049 if(res->restore) { 2051 if(res->restore) {
2051 } 2053 }
2052 2054
2053 int ret = 0; 2055 int ret = 0;
2054 if(err == 0) { 2056 if(err == 0) {
2055 char *etag = dav_get_string_property(remote, "D:getetag"); 2057 char *etag = dav_get_string_property(remote, "D:getetag");
2056 if(!res->etag) { 2058 char *hash = dav_get_string_property(remote, "idav:content-hash");
2059 if(hash || res->hash) {
2060 if(!nullstrcmp(hash, res->hash)) {
2061 ret = 1;
2062 }
2063 } else if(!res->etag) {
2057 // the resource is on the server and the client has no etag 2064 // the resource is on the server and the client has no etag
2058 ret = 1; 2065 ret = 1;
2059 } else if(etag) { 2066 } else if(etag) {
2060 sstr_t e = sstr(etag); 2067 sstr_t e = sstr(etag);
2061 if(sstrprefix(e, S("W/"))) { 2068 if(sstrprefix(e, S("W/"))) {
2733 // temporarly disable name encryption, because we don't need it for 2740 // temporarly disable name encryption, because we don't need it for
2734 // part names 2741 // part names
2735 uint32_t session_flags = res->session->flags; 2742 uint32_t session_flags = res->session->flags;
2736 res->session->flags ^= DAV_SESSION_ENCRYPT_NAME; 2743 res->session->flags ^= DAV_SESSION_ENCRYPT_NAME;
2737 2744
2745 DAV_SHA_CTX *sha = dav_hash_init();
2746
2738 while((r = fread(buffer, 1, blocksize, in)) > 0) { 2747 while((r = fread(buffer, 1, blocksize, in)) > 0) {
2748 dav_hash_update(sha, buffer, r);
2749
2739 int upload_block = 0; 2750 int upload_block = 0;
2740 char *block_hash = dav_create_hash(buffer, r); 2751 char *block_hash = dav_create_hash(buffer, r);
2741 if(blockindex >= local->numparts) { 2752 if(blockindex >= local->numparts) {
2742 // we don't have a hash for this block, therefore it must be new 2753 // we don't have a hash for this block, therefore it must be new
2743 upload_block = 1; 2754 upload_block = 1;
2794 ucx_map_free_content(updated_parts_map, (ucx_destructor)filepart_free); 2805 ucx_map_free_content(updated_parts_map, (ucx_destructor)filepart_free);
2795 ucx_map_free(updated_parts_map); 2806 ucx_map_free(updated_parts_map);
2796 return NULL; 2807 return NULL;
2797 } 2808 }
2798 2809
2810 // set content-hash
2811 char content_hash[DAV_SHA256_DIGEST_LENGTH];
2812 dav_hash_final(sha, content_hash);
2813 char *hash_hex = util_hexstr(content_hash, DAV_SHA256_DIGEST_LENGTH);
2814 dav_set_string_property_ns(res, DAV_NS, "content-hash", hash_hex);
2815 local->hash = hash_hex;
2816
2817 // get etags from uploaded resources
2818 // also delete everything, that is not part of the file
2799 UcxList *updated_parts = NULL; 2819 UcxList *updated_parts = NULL;
2800 DavResource *parts = dav_query(res->session, "select D:getetag from %s order by name", res->path); 2820 DavResource *parts = dav_query(res->session, "select D:getetag from %s order by name", res->path);
2801 if(!parts) { 2821 if(!parts) {
2802 print_resource_error(res->session, parts->path); 2822 print_resource_error(res->session, parts->path);
2803 *err = 1; 2823 *err = 1;
2930 if(!issplit) { 2950 if(!issplit) {
2931 // regular file upload 2951 // regular file upload
2932 dav_set_content(res, in, (dav_read_func)myread, (dav_seek_func)file_seek); 2952 dav_set_content(res, in, (dav_read_func)myread, (dav_seek_func)file_seek);
2933 dav_set_content_length(res, s.st_size); 2953 dav_set_content_length(res, s.st_size);
2934 } else { 2954 } else {
2955 // set split property
2956 char blocksize_str[32];
2957 snprintf(blocksize_str, 32, "%zu", split_blocksize);
2958 dav_set_string_property_ns(res, DAV_NS, "split", blocksize_str);
2959
2935 // splitted/partial upload 2960 // splitted/partial upload
2936 parts = upload_parts( 2961 parts = upload_parts(
2937 local, 2962 local,
2938 res, 2963 res,
2939 in, 2964 in,

mercurial