34 |
34 |
35 #include "utils.h" |
35 #include "utils.h" |
36 #include "session.h" |
36 #include "session.h" |
37 #include "methods.h" |
37 #include "methods.h" |
38 #include "crypto.h" |
38 #include "crypto.h" |
39 #include "ucx/buffer.h" |
39 #include <cx/buffer.h> |
40 #include "ucx/utils.h" |
40 #include <cx/utils.h> |
|
41 #include <cx/hash_map.h> |
|
42 #include <cx/printf.h> |
|
43 #include <cx/basic_mempool.h> |
|
44 #include <cx/array_list.h> |
41 |
45 |
42 #include "resource.h" |
46 #include "resource.h" |
43 #include "xml.h" |
47 #include "xml.h" |
44 #include "davqlexec.h" |
48 #include "davqlexec.h" |
45 |
49 |
46 #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b) |
50 #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b) |
47 |
51 |
48 DavResource* dav_resource_new(DavSession *sn, char *path) { |
52 DavResource* dav_resource_new(DavSession *sn, const char *path) { |
49 //char *href = util_url_path(url); |
53 //char *href = util_url_path(url); |
50 //DavResource *res = dav_resource_new_href(sn, href); |
54 //DavResource *res = dav_resource_new_href(sn, href); |
51 char *parent = util_parent_path(path); |
55 char *parent = util_parent_path(path); |
52 char *name = util_resource_name(path); |
56 const char *name = util_resource_name(path); |
53 char *href = dav_session_create_plain_href(sn, path); |
57 char *href = dav_session_create_plain_href(sn, path); |
54 |
58 |
55 DavResource *res = dav_resource_new_full(sn, parent, name, href); |
59 DavResource *res = dav_resource_new_full(sn, parent, name, href); |
56 free(parent); |
60 free(parent); |
57 return res; |
61 return res; |
58 } |
62 } |
59 |
63 |
60 DavResource* dav_resource_new_child(DavSession *sn, DavResource *parent, char *name) { |
64 DavResource* dav_resource_new_child(DavSession *sn, DavResource *parent, const char *name) { |
61 char *path = util_concat_path(parent->path, name); |
65 char *path = util_concat_path(parent->path, name); |
62 char *href = dav_session_create_plain_href(sn, path); |
66 char *href = dav_session_create_plain_href(sn, path); |
63 DavResource *res = dav_resource_new_full(sn, parent->path, name, href); |
67 DavResource *res = dav_resource_new_full(sn, parent->path, name, href); |
64 free(path); |
68 free(path); |
65 return res; |
69 return res; |
66 } |
70 } |
67 |
71 |
68 |
72 |
69 DavResource* dav_resource_new_href(DavSession *sn, char *href) { |
73 DavResource* dav_resource_new_href(DavSession *sn, const char *href) { |
70 DavResource *res = ucx_mempool_calloc(sn->mp, 1, sizeof(DavResource)); |
74 DavResource *res = cxCalloc(sn->mp->allocator, 1, sizeof(DavResource)); |
71 res->session = sn; |
75 res->session = sn; |
72 |
76 |
73 // set name, path and href |
77 // set name, path and href |
74 resource_set_info(res, href); |
78 resource_set_info(res, href); |
75 |
79 |
77 res->data = resource_data_new(sn); |
81 res->data = resource_data_new(sn); |
78 |
82 |
79 return res; |
83 return res; |
80 } |
84 } |
81 |
85 |
82 DavResource* dav_resource_new_full(DavSession *sn, char *parent_path, char *name, char *href) { |
86 DavResource* dav_resource_new_full(DavSession *sn, const char *parent_path, const char *name, char *href) { |
83 sstr_t n = sstr(name); |
87 cxstring n = cx_str(name); |
84 // the name must not contain path separators |
88 // the name must not contain path separators |
85 if(n.length > 0 && href) { |
89 if(n.length > 0 && href) { |
86 for(int i=0;i<n.length-1;i++) { |
90 for(int i=0;i<n.length-1;i++) { |
87 char c = n.ptr[i]; |
91 char c = n.ptr[i]; |
88 if(c == '/' || c == '\\') { |
92 if(c == '/' || c == '\\') { |
89 n = sstr(util_resource_name(href)); |
93 n = cx_str(util_resource_name(href)); |
90 break; |
94 break; |
91 } |
95 } |
92 } |
96 } |
93 } |
97 } |
94 // remove trailing '/' |
98 // remove trailing '/' |
95 if(n.length > 0 && n.ptr[n.length-1] == '/') { |
99 if(n.length > 0 && n.ptr[n.length-1] == '/') { |
96 n.length--; |
100 n.length--; |
97 } |
101 } |
98 |
102 |
99 DavResource *res = ucx_mempool_calloc(sn->mp, 1, sizeof(DavResource)); |
103 DavResource *res = cxCalloc(sn->mp->allocator, 1, sizeof(DavResource)); |
100 res->session = sn; |
104 res->session = sn; |
101 |
105 |
102 // set name, path and href |
106 // set name, path and href |
103 res->name = sstrdup_a(sn->mp->allocator, n).ptr; |
107 res->name = cx_strdup_a(sn->mp->allocator, n).ptr; |
104 |
108 |
105 char *path = util_concat_path(parent_path, name); |
109 char *path = util_concat_path(parent_path, name); |
106 res->path = dav_session_strdup(sn, path); |
110 res->path = dav_session_strdup(sn, path); |
107 |
111 |
108 res->href = href; |
112 res->href = href; |
110 // initialize resource data |
114 // initialize resource data |
111 res->data = resource_data_new(sn); |
115 res->data = resource_data_new(sn); |
112 |
116 |
113 // cache href/path |
117 // cache href/path |
114 if(href) { |
118 if(href) { |
115 dav_session_cache_path(sn, sstr(path), sstr(href)); |
119 dav_session_cache_path(sn, cx_str(path), cx_str(href)); |
116 } |
120 } |
117 free(path); |
121 free(path); |
118 |
122 |
119 return res; |
123 return res; |
120 } |
124 } |
121 |
125 |
122 void resource_free_properties(DavSession *sn, UcxMap *properties) { |
126 void resource_free_properties(DavSession *sn, CxMap *properties) { |
123 if(!properties) return; |
127 if(!properties) return; |
124 |
128 |
125 UcxMapIterator i = ucx_map_iterator(properties); |
129 CxIterator i = cxMapIteratorValues(properties); |
126 DavProperty *property; |
130 DavProperty *property; |
127 UCX_MAP_FOREACH(key, property, i) { |
131 cx_foreach(DavProperty*, property, i) { |
128 // TODO: free everything |
132 // TODO: free everything |
129 dav_session_free(sn, property); |
133 dav_session_free(sn, property); |
130 } |
134 } |
131 ucx_map_free(properties); |
135 cxMapDestroy(properties); |
132 } |
136 } |
133 |
137 |
134 void dav_resource_free(DavResource *res) { |
138 void dav_resource_free(DavResource *res) { |
135 DavSession *sn = res->session; |
139 DavSession *sn = res->session; |
136 |
140 |
142 |
146 |
143 DavResourceData *data = res->data; |
147 DavResourceData *data = res->data; |
144 resource_free_properties(sn, data->properties); |
148 resource_free_properties(sn, data->properties); |
145 resource_free_properties(sn, data->crypto_properties); |
149 resource_free_properties(sn, data->crypto_properties); |
146 |
150 |
147 UCX_FOREACH(elm, data->set) { |
151 if(data->set) { |
148 DavProperty *p = elm->data; |
152 CxIterator i = cxListIterator(data->set); |
149 dav_session_free(sn, p->ns->name); |
153 cx_foreach(DavProperty *, p, i) { |
150 if(p->ns->prefix) { |
154 dav_session_free(sn, p->ns->name); |
151 dav_session_free(sn, p->ns->prefix); |
155 if(p->ns->prefix) { |
152 } |
156 dav_session_free(sn, p->ns->prefix); |
153 dav_session_free(sn, p->ns); |
157 } |
154 |
158 dav_session_free(sn, p->ns); |
155 dav_session_free(sn, p->name); |
159 |
156 dav_free_xml_node_sn(sn, p->value); |
160 dav_session_free(sn, p->name); |
157 dav_session_free(sn, p); |
161 dav_free_xml_node_sn(sn, p->value); |
158 } |
162 dav_session_free(sn, p); |
159 |
163 } |
160 UCX_FOREACH(elm, data->remove) { |
164 } |
161 DavProperty *p = elm->data; |
165 |
162 dav_session_free(sn, p->ns->name); |
166 if(data->remove) { |
163 if(p->ns->prefix) { |
167 CxIterator i = cxListIterator(data->remove); |
164 dav_session_free(sn, p->ns->prefix); |
168 cx_foreach(DavProperty *, p, i) { |
165 } |
169 dav_session_free(sn, p->ns->name); |
166 dav_session_free(sn, p->ns); |
170 if(p->ns->prefix) { |
167 |
171 dav_session_free(sn, p->ns->prefix); |
168 dav_session_free(sn, p->name); |
172 } |
169 dav_session_free(sn, p); |
173 dav_session_free(sn, p->ns); |
|
174 |
|
175 dav_session_free(sn, p->name); |
|
176 dav_session_free(sn, p); |
|
177 } |
|
178 } |
|
179 |
|
180 if(data->crypto_set) { |
|
181 CxIterator i = cxListIterator(data->crypto_set); |
|
182 cx_foreach(DavProperty *, p, i) { |
|
183 dav_session_free(sn, p->ns->name); |
|
184 if(p->ns->prefix) { |
|
185 dav_session_free(sn, p->ns->prefix); |
|
186 } |
|
187 dav_session_free(sn, p->ns); |
|
188 |
|
189 dav_session_free(sn, p->name); |
|
190 dav_free_xml_node_sn(sn, p->value); |
|
191 dav_session_free(sn, p); |
|
192 } |
|
193 } |
|
194 |
|
195 if(data->crypto_remove) { |
|
196 CxIterator i = cxListIterator(data->crypto_remove); |
|
197 cx_foreach(DavProperty *, p, i) { |
|
198 dav_session_free(sn, p->ns->name); |
|
199 if(p->ns->prefix) { |
|
200 dav_session_free(sn, p->ns->prefix); |
|
201 } |
|
202 dav_session_free(sn, p->ns); |
|
203 |
|
204 dav_session_free(sn, p->name); |
|
205 dav_session_free(sn, p); |
|
206 } |
170 } |
207 } |
171 |
208 |
172 if(!data->read && data->content) { |
209 if(!data->read && data->content) { |
173 dav_session_free(sn, data->content); |
210 dav_session_free(sn, data->content); |
174 } |
211 } |
185 dav_resource_free_all(child); |
222 dav_resource_free_all(child); |
186 child = next; |
223 child = next; |
187 } |
224 } |
188 } |
225 } |
189 |
226 |
190 void resource_set_href(DavResource *res, sstr_t href) { |
227 void resource_set_href(DavResource *res, cxstring href) { |
191 res->href = sstrdup_a(res->session->mp->allocator, href).ptr; |
228 res->href = cx_strdup_a(res->session->mp->allocator, href).ptr; |
192 } |
229 } |
193 |
230 |
194 void resource_set_info(DavResource *res, char *href_str) { |
231 void resource_set_info(DavResource *res, const char *href_str) { |
195 char *url_str = NULL; |
232 char *url_str = NULL; |
196 curl_easy_getinfo(res->session->handle, CURLINFO_EFFECTIVE_URL, &url_str); |
233 curl_easy_getinfo(res->session->handle, CURLINFO_EFFECTIVE_URL, &url_str); |
197 sstr_t name = sstr(util_resource_name(href_str)); |
234 cxstring name = cx_str(util_resource_name(href_str)); |
198 sstr_t href = sstr(href_str); |
235 cxstring href = cx_str(href_str); |
199 |
236 |
200 sstr_t base_href = sstr(util_url_path(res->session->base_url)); |
237 cxstring base_href = cx_str(util_url_path(res->session->base_url)); |
201 sstr_t path = sstrsubs(href, base_href.length - 1); |
238 cxstring path = cx_strsubs(href, base_href.length - 1); |
202 |
239 |
203 UcxAllocator *a = res->session->mp->allocator; |
240 const CxAllocator *a = res->session->mp->allocator; |
204 CURL *handle = res->session->handle; |
241 CURL *handle = res->session->handle; |
205 |
242 |
206 int nlen = 0; |
243 int nlen = 0; |
207 char *uname = curl_easy_unescape(handle, name.ptr, name.length , &nlen); |
244 char *uname = curl_easy_unescape(handle, name.ptr, name.length , &nlen); |
208 int plen = 0; |
245 int plen = 0; |
209 char *upath = curl_easy_unescape(handle, path.ptr, path.length, &plen); |
246 char *upath = curl_easy_unescape(handle, path.ptr, path.length, &plen); |
210 |
247 |
211 res->name = sstrdup_a(a, sstrn(uname, nlen)).ptr; |
248 res->name = cx_strdup_a(a, cx_strn(uname, nlen)).ptr; |
212 res->href = sstrdup_a(a, href).ptr; |
249 res->href = cx_strdup_a(a, href).ptr; |
213 res->path = sstrdup_a(a, sstrn(upath, plen)).ptr; |
250 res->path = cx_strdup_a(a, cx_strn(upath, plen)).ptr; |
214 |
251 |
215 curl_free(uname); |
252 curl_free(uname); |
216 curl_free(upath); |
253 curl_free(upath); |
217 } |
254 } |
218 |
255 |
219 DavResourceData* resource_data_new(DavSession *sn) { |
256 DavResourceData* resource_data_new(DavSession *sn) { |
220 DavResourceData *data = ucx_mempool_malloc( |
257 DavResourceData *data = cxMalloc( |
221 sn->mp, |
258 sn->mp->allocator, |
222 sizeof(DavResourceData)); |
259 sizeof(DavResourceData)); |
223 if(!data) { |
260 if(!data) { |
224 return NULL; |
261 return NULL; |
225 } |
262 } |
226 data->properties = ucx_map_new_a(sn->mp->allocator, 32); |
263 data->properties = cxHashMapCreate(sn->mp->allocator, CX_STORE_POINTERS, 32); |
227 data->crypto_properties = NULL; |
264 data->crypto_properties = NULL; |
228 data->set = NULL; |
265 data->set = NULL; |
229 data->remove = NULL; |
266 data->remove = NULL; |
230 data->crypto_set = NULL; |
267 data->crypto_set = NULL; |
231 data->crypto_remove = NULL; |
268 data->crypto_remove = NULL; |
255 DavProperty *prop = dav_session_malloc(sn, sizeof(DavProperty)); |
292 DavProperty *prop = dav_session_malloc(sn, sizeof(DavProperty)); |
256 prop->name = dav_session_strdup(sn, name); |
293 prop->name = dav_session_strdup(sn, name); |
257 prop->ns = namespace; |
294 prop->ns = namespace; |
258 prop->value = val; |
295 prop->value = val; |
259 |
296 |
260 sstr_t key = dav_property_key(ns, name); |
297 cxmutstr keystr = dav_property_key(ns, name); |
261 ucx_map_sstr_put(((DavResourceData*)res->data)->properties, key, prop); |
298 CxHashKey key = cx_hash_key(keystr.ptr, keystr.length); |
262 free(key.ptr); |
299 cxMapPut(((DavResourceData*)res->data)->properties, key, prop); |
|
300 free(keystr.ptr); |
263 } |
301 } |
264 |
302 |
265 void resource_add_property(DavResource *res, const char *ns, const char *name, xmlNode *val) { |
303 void resource_add_property(DavResource *res, const char *ns, const char *name, xmlNode *val) { |
266 if(!val) { |
304 if(!val) { |
267 return; |
305 return; |
276 } |
314 } |
277 |
315 |
278 resource_add_prop(res, ns, name, dav_text_node(res->session, val)); |
316 resource_add_prop(res, ns, name, dav_text_node(res->session, val)); |
279 } |
317 } |
280 |
318 |
281 void resource_set_crypto_properties(DavResource *res, UcxMap *cprops) { |
319 void resource_set_crypto_properties(DavResource *res, CxMap *cprops) { |
282 DavResourceData *data = res->data; |
320 DavResourceData *data = res->data; |
283 resource_free_properties(res->session, data->crypto_properties); |
321 resource_free_properties(res->session, data->crypto_properties); |
284 data->crypto_properties = cprops; |
322 data->crypto_properties = cprops; |
285 } |
323 } |
286 |
324 |
287 DavXmlNode* resource_get_property(DavResource *res, const char *ns, const char *name) { |
325 DavXmlNode* resource_get_property(DavResource *res, const char *ns, const char *name) { |
288 sstr_t keystr = dav_property_key(ns, name); |
326 cxmutstr keystr = dav_property_key(ns, name); |
289 UcxKey key = ucx_key(keystr.ptr, keystr.length); |
327 CxHashKey key = cx_hash_key(keystr.ptr, keystr.length); |
290 DavXmlNode *ret = resource_get_property_k(res, key); |
328 DavXmlNode *ret = resource_get_property_k(res, key); |
291 free(keystr.ptr); |
329 free(keystr.ptr); |
292 |
330 |
293 return ret; |
331 return ret; |
294 } |
332 } |
295 |
333 |
296 DavXmlNode* resource_get_encrypted_property(DavResource *res, const char *ns, const char *name) { |
334 DavXmlNode* resource_get_encrypted_property(DavResource *res, const char *ns, const char *name) { |
297 sstr_t keystr = dav_property_key(ns, name); |
335 cxmutstr keystr = dav_property_key(ns, name); |
298 UcxKey key = ucx_key(keystr.ptr, keystr.length); |
336 CxHashKey key = cx_hash_key(keystr.ptr, keystr.length); |
299 DavXmlNode *ret = resource_get_encrypted_property_k(res, key); |
337 DavXmlNode *ret = resource_get_encrypted_property_k(res, key); |
300 free(keystr.ptr); |
338 free(keystr.ptr); |
301 |
339 |
302 return ret; |
340 return ret; |
303 } |
341 } |
304 |
342 |
305 DavXmlNode* resource_get_property_k(DavResource *res, UcxKey key) { |
343 DavXmlNode* resource_get_property_k(DavResource *res, CxHashKey key) { |
306 DavResourceData *data = (DavResourceData*)res->data; |
344 DavResourceData *data = (DavResourceData*)res->data; |
307 DavProperty *property = ucx_map_get(data->properties, key); |
345 DavProperty *property = cxMapGet(data->properties, key); |
308 |
346 |
309 return property ? property->value : NULL; |
347 return property ? property->value : NULL; |
310 } |
348 } |
311 |
349 |
312 DavXmlNode* resource_get_encrypted_property_k(DavResource *res, UcxKey key) { |
350 DavXmlNode* resource_get_encrypted_property_k(DavResource *res, CxHashKey key) { |
313 DavResourceData *data = (DavResourceData*)res->data; |
351 DavResourceData *data = (DavResourceData*)res->data; |
314 DavProperty *property = ucx_map_get(data->crypto_properties, key); |
352 DavProperty *property = cxMapGet(data->crypto_properties, key); |
315 |
353 |
316 return property ? property->value : NULL; |
354 return property ? property->value : NULL; |
317 } |
355 } |
318 |
356 |
319 sstr_t dav_property_key(const char *ns, const char *name) { |
357 cxmutstr dav_property_key(const char *ns, const char *name) { |
320 return dav_property_key_a(ucx_default_allocator(), ns, name); |
358 return dav_property_key_a(cxDefaultAllocator, ns, name); |
321 } |
359 } |
322 |
360 |
323 sstr_t dav_property_key_a(UcxAllocator *a, const char *ns, const char *name) { |
361 cxmutstr dav_property_key_a(const CxAllocator *a, const char *ns, const char *name) { |
324 scstr_t ns_str = scstr(ns); |
362 cxstring ns_str = cx_str(ns); |
325 scstr_t name_str = scstr(name); |
363 cxstring name_str = cx_str(name); |
326 |
364 |
327 return sstrcat_a(a, 4, ns_str, S("\0"), name_str, S("\0")); |
365 return cx_strcat_a(a, 4, ns_str, CX_STR("\0"), name_str, CX_STR("\0")); |
328 } |
366 } |
329 |
367 |
330 |
368 |
331 |
369 |
332 |
370 |
513 set_list = data->set; |
551 set_list = data->set; |
514 } |
552 } |
515 |
553 |
516 // resource_get_property only returns persistent properties |
554 // resource_get_property only returns persistent properties |
517 // check the remove and set list |
555 // check the remove and set list |
518 if(property) { |
556 if(property && remove_list) { |
519 // if the property is in the remove list, we return NULL |
557 // if the property is in the remove list, we return NULL |
520 UCX_FOREACH(elm, remove_list) { |
558 CxIterator i = cxListIterator(remove_list); |
521 DavProperty *p = elm->data; |
559 cx_foreach(DavProperty*, p, i) { |
522 if(!strcmp(p->name, name) && !strcmp(p->ns->name, ns)) { |
560 if(!strcmp(p->name, name) && !strcmp(p->ns->name, ns)) { |
523 return NULL; |
561 return NULL; |
524 } |
562 } |
525 } |
563 } |
526 } |
564 } |
|
565 |
527 // the set list contains property updates |
566 // the set list contains property updates |
528 // we return an updated property if possible |
567 // we return an updated property if possible |
529 UCX_FOREACH(elm, set_list) { |
568 if(set_list) { |
530 DavProperty *p = elm->data; |
569 CxIterator i = cxListIterator(set_list); |
531 if(!strcmp(p->name, name) && !strcmp(p->ns->name, ns)) { |
570 cx_foreach(DavProperty*, p, i) { |
532 return p->value; // TODO: fix |
571 if(!strcmp(p->name, name) && !strcmp(p->ns->name, ns)) { |
533 } |
572 return p->value; // TODO: fix |
534 } |
573 } |
|
574 } |
|
575 } |
|
576 |
535 // no property update |
577 // no property update |
536 |
578 |
537 return property; |
579 return property; |
538 } |
580 } |
539 |
581 |
570 char *pname; |
612 char *pname; |
571 dav_get_property_namespace_str(res->session->context, name, &pns, &pname); |
613 dav_get_property_namespace_str(res->session->context, name, &pns, &pname); |
572 dav_set_string_property_ns(res, pns, pname, value); |
614 dav_set_string_property_ns(res, pns, pname, value); |
573 } |
615 } |
574 |
616 |
|
617 static int add2propertylist(const CxAllocator *a, CxList **list, DavProperty *property) { |
|
618 if(!*list) { |
|
619 CxList *newlist = cxLinkedListCreate(a, NULL, CX_STORE_POINTERS); |
|
620 if(!newlist) { |
|
621 return 1; |
|
622 } |
|
623 *list = newlist; |
|
624 } |
|
625 cxListAdd(*list, property); |
|
626 return 0; |
|
627 } |
|
628 |
575 void dav_set_string_property_ns(DavResource *res, char *ns, char *name, char *value) { |
629 void dav_set_string_property_ns(DavResource *res, char *ns, char *name, char *value) { |
576 DavSession *sn = res->session; |
630 DavSession *sn = res->session; |
577 UcxAllocator *a = res->session->mp->allocator; |
631 const CxAllocator *a = res->session->mp->allocator; |
578 DavResourceData *data = res->data; |
632 DavResourceData *data = res->data; |
579 |
633 |
580 DavProperty *property = createprop(res->session, ns, name); |
634 DavProperty *property = createprop(res->session, ns, name); |
581 property->value = dav_text_node(res->session, value); |
635 property->value = dav_text_node(res->session, value); |
582 |
636 |
583 if(DAV_ENCRYPT_PROPERTIES(sn) && dav_namespace_is_encrypted(sn->context, ns)) { |
637 if(DAV_ENCRYPT_PROPERTIES(sn) && dav_namespace_is_encrypted(sn->context, ns)) { |
584 data->crypto_set = ucx_list_append_a(a, data->crypto_set, property); |
638 add2propertylist(a, &data->crypto_set, property); |
585 } else { |
639 } else { |
586 data->set = ucx_list_append_a(a, data->set, property); |
640 add2propertylist(a, &data->set, property); |
587 } |
641 } |
588 } |
642 } |
589 |
643 |
590 void dav_set_property(DavResource *res, char *name, DavXmlNode *value) { |
644 void dav_set_property(DavResource *res, char *name, DavXmlNode *value) { |
591 char *pns; |
645 char *pns; |
594 dav_set_property_ns(res, pns, pname, value); |
648 dav_set_property_ns(res, pns, pname, value); |
595 } |
649 } |
596 |
650 |
597 void dav_set_property_ns(DavResource *res, char *ns, char *name, DavXmlNode *value) { |
651 void dav_set_property_ns(DavResource *res, char *ns, char *name, DavXmlNode *value) { |
598 DavSession *sn = res->session; |
652 DavSession *sn = res->session; |
599 UcxAllocator *a = sn->mp->allocator; |
653 const CxAllocator *a = sn->mp->allocator; |
600 DavResourceData *data = res->data; |
654 DavResourceData *data = res->data; |
601 |
655 |
602 DavProperty *property = createprop(sn, ns, name); |
656 DavProperty *property = createprop(sn, ns, name); |
603 // TODO: this function should copy the value |
657 // TODO: this function should copy the value |
604 // but we also need a function, that doesn't create a copy |
658 // but we also need a function, that doesn't create a copy |
605 property->value = value; |
659 property->value = value; |
606 |
660 |
607 if(DAV_ENCRYPT_PROPERTIES(sn) && dav_namespace_is_encrypted(sn->context, ns)) { |
661 if(DAV_ENCRYPT_PROPERTIES(sn) && dav_namespace_is_encrypted(sn->context, ns)) { |
608 data->crypto_set = ucx_list_append_a(a, data->crypto_set, property); |
662 add2propertylist(a, &data->crypto_set, property); |
609 } else { |
663 } else { |
610 data->set = ucx_list_append_a(a, data->set, property); |
664 add2propertylist(a, &data->set, property); |
611 } |
665 } |
612 } |
666 } |
613 |
667 |
614 void dav_remove_property(DavResource *res, char *name) { |
668 void dav_remove_property(DavResource *res, char *name) { |
615 char *pns; |
669 char *pns; |
619 } |
673 } |
620 |
674 |
621 void dav_remove_property_ns(DavResource *res, char *ns, char *name) { |
675 void dav_remove_property_ns(DavResource *res, char *ns, char *name) { |
622 DavSession *sn = res->session; |
676 DavSession *sn = res->session; |
623 DavResourceData *data = res->data; |
677 DavResourceData *data = res->data; |
624 UcxAllocator *a = res->session->mp->allocator; |
678 const CxAllocator *a = res->session->mp->allocator; |
625 |
679 |
626 DavProperty *property = createprop(res->session, ns, name); |
680 DavProperty *property = createprop(res->session, ns, name); |
627 |
681 |
628 if(DAV_ENCRYPT_PROPERTIES(sn) && dav_namespace_is_encrypted(sn->context, ns)) { |
682 if(DAV_ENCRYPT_PROPERTIES(sn) && dav_namespace_is_encrypted(sn->context, ns)) { |
629 data->crypto_remove = ucx_list_append_a(a, data->crypto_remove, property); |
683 add2propertylist(a, &data->crypto_remove, property); |
630 } else { |
684 } else { |
631 data->remove = ucx_list_append_a(a, data->remove, property); |
685 add2propertylist(a, &data->remove, property); |
632 } |
686 } |
633 } |
687 } |
634 |
688 |
635 void dav_set_encrypted_property_ns(DavResource *res, char *ns, char *name, DavXmlNode *value) { |
689 void dav_set_encrypted_property_ns(DavResource *res, char *ns, char *name, DavXmlNode *value) { |
636 UcxAllocator *a = res->session->mp->allocator; |
690 const CxAllocator *a = res->session->mp->allocator; |
637 DavResourceData *data = res->data; |
691 DavResourceData *data = res->data; |
638 |
692 |
639 DavProperty *property = createprop(res->session, ns, name); |
693 DavProperty *property = createprop(res->session, ns, name); |
640 property->value = value; // TODO: copy node? |
694 property->value = value; // TODO: copy node? |
641 |
695 |
642 data->crypto_set = ucx_list_append_a(a, data->crypto_set, property); |
696 add2propertylist(a, &data->crypto_set, property); |
643 } |
697 } |
644 |
698 |
645 void dav_set_encrypted_string_property_ns(DavResource *res, char *ns, char *name, char *value) { |
699 void dav_set_encrypted_string_property_ns(DavResource *res, char *ns, char *name, char *value) { |
646 UcxAllocator *a = res->session->mp->allocator; |
700 const CxAllocator *a = res->session->mp->allocator; |
647 DavResourceData *data = res->data; |
701 DavResourceData *data = res->data; |
648 |
702 |
649 DavProperty *property = createprop(res->session, ns, name); |
703 DavProperty *property = createprop(res->session, ns, name); |
650 property->value = dav_text_node(res->session, value); |
704 property->value = dav_text_node(res->session, value); |
651 |
705 |
652 data->crypto_set = ucx_list_append_a(a, data->crypto_set, property); |
706 add2propertylist(a, &data->crypto_set, property); |
653 } |
707 } |
654 |
708 |
655 void dav_remove_encrypted_property_ns(DavResource *res, char *ns, char *name) { |
709 void dav_remove_encrypted_property_ns(DavResource *res, char *ns, char *name) { |
656 DavResourceData *data = res->data; |
710 DavResourceData *data = res->data; |
657 UcxAllocator *a = res->session->mp->allocator; |
711 const CxAllocator *a = res->session->mp->allocator; |
658 |
712 |
659 DavProperty *property = createprop(res->session, ns, name); |
713 DavProperty *property = createprop(res->session, ns, name); |
660 |
714 |
661 data->crypto_remove = ucx_list_append_a(a, data->crypto_remove, property); |
715 add2propertylist(a, &data->crypto_remove, property); |
662 } |
716 } |
663 |
717 |
664 static int compare_propname(const void *a, const void *b) { |
718 static int compare_propname(const void *a, const void *b) { |
665 const DavPropName *p1 = a; |
719 const DavPropName *p1 = a; |
666 const DavPropName *p2 = b; |
720 const DavPropName *p2 = b; |
674 } |
728 } |
675 |
729 |
676 DavPropName* dav_get_property_names(DavResource *res, size_t *count) { |
730 DavPropName* dav_get_property_names(DavResource *res, size_t *count) { |
677 DavResourceData *data = res->data; |
731 DavResourceData *data = res->data; |
678 |
732 |
679 *count = data->properties->count; |
733 *count = data->properties->size; |
680 DavPropName *names = dav_session_calloc( |
734 DavPropName *names = dav_session_calloc( |
681 res->session, |
735 res->session, |
682 *count, |
736 *count, |
683 sizeof(DavPropName)); |
737 sizeof(DavPropName)); |
684 |
738 |
685 |
739 |
686 UcxMapIterator i = ucx_map_iterator(data->properties); |
740 CxIterator i = cxMapIteratorValues(data->properties); |
687 DavProperty *value; |
741 DavProperty *value; |
688 int j = 0; |
742 int j = 0; |
689 UCX_MAP_FOREACH(key, value, i) { |
743 cx_foreach(DavProperty*, value, i) { |
690 DavPropName *name = &names[j]; |
744 DavPropName *name = &names[j]; |
691 |
745 |
692 name->ns = value->ns->name; |
746 name->ns = value->ns->name; |
693 name->name = value->name; |
747 name->name = value->name; |
694 |
748 |
724 data->length = length; |
778 data->length = length; |
725 } |
779 } |
726 |
780 |
727 |
781 |
728 int dav_load(DavResource *res) { |
782 int dav_load(DavResource *res) { |
729 UcxBuffer *rqbuf = create_allprop_propfind_request(); |
783 CxBuffer *rqbuf = create_allprop_propfind_request(); |
730 int ret = dav_propfind(res->session, res, rqbuf); |
784 int ret = dav_propfind(res->session, res, rqbuf); |
731 ucx_buffer_free(rqbuf); |
785 cxBufferFree(rqbuf); |
732 return ret; |
786 return ret; |
733 } |
787 } |
734 |
788 |
735 int dav_load_prop(DavResource *res, DavPropName *properties, size_t numprop) { |
789 int dav_load_prop(DavResource *res, DavPropName *properties, size_t numprop) { |
736 UcxMempool *mp = ucx_mempool_new(64); |
790 CxMempool *mp = cxBasicMempoolCreate(64); |
737 |
791 const CxAllocator *a = mp->allocator; |
738 UcxList *proplist = NULL; |
792 |
|
793 CxList *proplist = cxArrayListCreate(a, NULL, sizeof(DavProperty), numprop); |
739 for(size_t i=0;i<numprop;i++) { |
794 for(size_t i=0;i<numprop;i++) { |
740 DavProperty *p = ucx_mempool_malloc(mp, sizeof(DavProperty)); |
795 DavProperty p; |
741 p->name = properties[i].name; |
796 p.name = properties[i].name; |
742 p->ns = ucx_mempool_malloc(mp, sizeof(DavNamespace)); |
797 p.ns = cxMalloc(a, sizeof(DavNamespace)); |
743 p->ns->name = properties[i].ns; |
798 p.ns->name = properties[i].ns; |
744 if(!strcmp(properties[i].ns, "DAV:")) { |
799 if(!strcmp(properties[i].ns, "DAV:")) { |
745 p->ns->prefix = "D"; |
800 p.ns->prefix = "D"; |
746 } else { |
801 } else { |
747 p->ns->prefix = ucx_asprintf(mp->allocator, "x%d", i).ptr; |
802 p.ns->prefix = cx_asprintf_a(a, "x%d", (int)i).ptr; |
748 } |
803 } |
749 p->value = NULL; |
804 p.value = NULL; |
750 proplist = ucx_list_append_a(mp->allocator, proplist, p); |
805 cxListAdd(proplist, &p); |
751 } |
806 } |
752 |
807 |
753 UcxBuffer *rqbuf = create_propfind_request(res->session, proplist, "propfind", 0); |
808 CxBuffer *rqbuf = create_propfind_request(res->session, proplist, "propfind", 0); |
754 int ret = dav_propfind(res->session, res, rqbuf); |
809 int ret = dav_propfind(res->session, res, rqbuf); |
755 ucx_buffer_free(rqbuf); |
810 cxBufferFree(rqbuf); |
756 ucx_mempool_destroy(mp); |
811 cxMempoolDestroy(mp); |
757 return ret; |
812 return ret; |
758 } |
813 } |
759 |
814 |
760 |
815 |
761 static void init_hash_stream(HashStream *hstr, void *stream, dav_read_func readfn, dav_seek_func seekfn) { |
816 static void init_hash_stream(HashStream *hstr, void *stream, dav_read_func readfn, dav_seek_func seekfn) { |
803 if(data->content) { |
858 if(data->content) { |
804 int encryption = DAV_ENCRYPT_CONTENT(sn) && sn->key; |
859 int encryption = DAV_ENCRYPT_CONTENT(sn) && sn->key; |
805 CURLcode ret; |
860 CURLcode ret; |
806 if(encryption) { |
861 if(encryption) { |
807 AESEncrypter *enc = NULL; |
862 AESEncrypter *enc = NULL; |
808 UcxBuffer *buf = NULL; |
863 CxBuffer *buf = NULL; |
809 if(data->read) { |
864 if(data->read) { |
810 enc = aes_encrypter_new( |
865 enc = aes_encrypter_new( |
811 sn->key, |
866 sn->key, |
812 data->content, |
867 data->content, |
813 data->read, |
868 data->read, |
814 data->seek); |
869 data->seek); |
815 } else { |
870 } else { |
816 buf = ucx_buffer_new(data->content, data->length, 0); |
871 buf = cxBufferCreate(data->content, data->length, cxDefaultAllocator, 0); |
817 buf->size = data->length; |
872 buf->size = data->length; |
818 enc = aes_encrypter_new( |
873 enc = aes_encrypter_new( |
819 sn->key, |
874 sn->key, |
820 buf, |
875 buf, |
821 (dav_read_func)ucx_buffer_read, |
876 (dav_read_func)cxBufferRead, |
822 (dav_seek_func)dav_buffer_seek); |
877 (dav_seek_func)cxBufferSeek); |
823 } |
878 } |
824 |
879 |
825 // put resource |
880 // put resource |
826 ret = do_put_request( |
881 ret = do_put_request( |
827 sn, |
882 sn, |
836 dav_get_hash(&enc->sha256, (unsigned char*)data->hash); |
891 dav_get_hash(&enc->sha256, (unsigned char*)data->hash); |
837 char *enc_hash = aes_encrypt(data->hash, DAV_SHA256_DIGEST_LENGTH, sn->key); |
892 char *enc_hash = aes_encrypt(data->hash, DAV_SHA256_DIGEST_LENGTH, sn->key); |
838 |
893 |
839 aes_encrypter_close(enc); |
894 aes_encrypter_close(enc); |
840 if(buf) { |
895 if(buf) { |
841 ucx_buffer_free(buf); |
896 cxBufferFree(buf); |
842 } |
897 } |
843 |
898 |
844 // add crypto properties |
899 // add crypto properties |
845 // TODO: store the properties later |
900 // TODO: store the properties later |
846 if(resource_add_crypto_info(sn, res->href, res->name, enc_hash)) { |
901 if(resource_add_crypto_info(sn, res->href, res->name, enc_hash)) { |
849 } |
904 } |
850 resource_add_string_property(res, DAV_NS, "crypto-hash", enc_hash); |
905 resource_add_string_property(res, DAV_NS, "crypto-hash", enc_hash); |
851 free(enc_hash); |
906 free(enc_hash); |
852 } else if((sn->flags & DAV_SESSION_STORE_HASH) == DAV_SESSION_STORE_HASH) { |
907 } else if((sn->flags & DAV_SESSION_STORE_HASH) == DAV_SESSION_STORE_HASH) { |
853 HashStream hstr; |
908 HashStream hstr; |
854 UcxBuffer *iobuf = NULL; |
909 CxBuffer *iobuf = NULL; |
855 if(!data->read) { |
910 if(!data->read) { |
856 iobuf = ucx_buffer_new(data->content, data->length, 0); |
911 iobuf = cxBufferCreate(data->content, data->length, cxDefaultAllocator, 0); |
857 iobuf->size = data->length; |
912 iobuf->size = data->length; |
858 init_hash_stream( |
913 init_hash_stream( |
859 &hstr, |
914 &hstr, |
860 iobuf, |
915 iobuf, |
861 (dav_read_func)ucx_buffer_read, |
916 (dav_read_func)cxBufferRead, |
862 (dav_seek_func)ucx_buffer_seek); |
917 (dav_seek_func)cxBufferSeek); |
863 } else { |
918 } else { |
864 init_hash_stream( |
919 init_hash_stream( |
865 &hstr, |
920 &hstr, |
866 data->content, |
921 data->content, |
867 data->read, |
922 data->read, |
915 if(DAV_ENCRYPT_PROPERTIES(sn) && sn->key && (data->crypto_set || data->crypto_remove)) { |
970 if(DAV_ENCRYPT_PROPERTIES(sn) && sn->key && (data->crypto_set || data->crypto_remove)) { |
916 DavResource *crypto_res = dav_resource_new_href(sn, res->href); |
971 DavResource *crypto_res = dav_resource_new_href(sn, res->href); |
917 int ret = 1; |
972 int ret = 1; |
918 |
973 |
919 if(crypto_res) { |
974 if(crypto_res) { |
920 UcxBuffer *rqbuf = create_cryptoprop_propfind_request(); |
975 CxBuffer *rqbuf = create_cryptoprop_propfind_request(); |
921 ret = dav_propfind(res->session, res, rqbuf); |
976 ret = dav_propfind(res->session, res, rqbuf); |
922 ucx_buffer_free(rqbuf); |
977 cxBufferFree(rqbuf); |
923 } |
978 } |
924 |
979 |
925 if(!ret) { |
980 if(!ret) { |
926 DavXmlNode *crypto_prop_node = dav_get_property_ns(crypto_res, DAV_NS, "crypto-prop"); |
981 DavXmlNode *crypto_prop_node = dav_get_property_ns(crypto_res, DAV_NS, "crypto-prop"); |
927 UcxMap *crypto_props = parse_crypto_prop(sn, sn->key, crypto_prop_node); |
982 CxMap *crypto_props = parse_crypto_prop(sn, sn->key, crypto_prop_node); |
928 if(!crypto_props) { |
983 if(!crypto_props) { |
929 // resource hasn't encrypted properties yet |
984 // resource hasn't encrypted properties yet |
930 crypto_props = ucx_map_new(32); // create new map |
985 crypto_props = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 32); // create new map |
931 } |
986 } |
932 |
987 |
933 // remove all properties |
988 // remove all properties |
934 UCX_FOREACH(elm, data->crypto_remove) { |
989 if(data->crypto_remove) { |
935 if(crypto_props->count == 0) { |
990 CxIterator i = cxListIterator(data->crypto_remove); |
936 break; // map already empty, can't remove any more |
991 cx_foreach(DavProperty *, property, i) { |
|
992 if(crypto_props->size == 0) { |
|
993 break; // map already empty, can't remove any more |
|
994 } |
|
995 |
|
996 cxmutstr key = dav_property_key(property->ns->name, property->name); |
|
997 DavProperty *existing_prop = cxMapGet(crypto_props, cx_hash_key(key.ptr, key.length)); |
|
998 if(existing_prop) { |
|
999 // TODO: free existing_prop |
|
1000 } |
|
1001 free(key.ptr); |
937 } |
1002 } |
938 |
|
939 DavProperty *property = elm->data; |
|
940 sstr_t key = dav_property_key(property->ns->name, property->name); |
|
941 DavProperty *existing_prop = ucx_map_sstr_remove(crypto_props, key); |
|
942 if(existing_prop) { |
|
943 // TODO: free existing_prop |
|
944 } |
|
945 free(key.ptr); |
|
946 } |
1003 } |
947 |
1004 |
948 // set properties |
1005 // set properties |
949 UCX_FOREACH(elm, data->crypto_set) { |
1006 if(data->crypto_set) { |
950 DavProperty *property = elm->data; |
1007 CxIterator i = cxListIterator(data->crypto_set); |
951 sstr_t key = dav_property_key(property->ns->name, property->name); |
1008 cx_foreach(DavProperty *, property, i) { |
952 DavProperty *existing_prop = ucx_map_sstr_remove(crypto_props, key); |
1009 cxmutstr keystr = dav_property_key(property->ns->name, property->name); |
953 ucx_map_sstr_put(crypto_props, key, property); |
1010 CxHashKey key = cx_hash_key(keystr.ptr, keystr.length); |
954 if(existing_prop) { |
1011 DavProperty *existing_prop = cxMapRemoveAndGet(crypto_props, key); |
955 // TODO: free existing_prop |
1012 cxMapPut(crypto_props, key, property); |
956 } |
1013 if(existing_prop) { |
957 free(key.ptr); |
1014 // TODO: free existing_prop |
|
1015 } |
|
1016 free(keystr.ptr); |
|
1017 } |
958 } |
1018 } |
959 |
1019 |
960 DavXmlNode *crypto_prop_value = create_crypto_prop(sn, crypto_props); |
1020 DavXmlNode *crypto_prop_value = create_crypto_prop(sn, crypto_props); |
961 if(crypto_prop_value) { |
1021 if(crypto_prop_value) { |
962 DavProperty *new_crypto_prop = createprop(sn, DAV_NS, "crypto-prop"); |
1022 DavProperty *new_crypto_prop = createprop(sn, DAV_NS, "crypto-prop"); |
963 new_crypto_prop->value = crypto_prop_value; |
1023 new_crypto_prop->value = crypto_prop_value; |
964 data->set = ucx_list_prepend_a(sn->mp->allocator, data->set, new_crypto_prop); |
1024 add2propertylist(sn->mp->allocator, &data->set, new_crypto_prop); |
965 } |
1025 } |
966 |
1026 |
967 dav_resource_free(crypto_res); |
1027 dav_resource_free(crypto_res); |
968 } |
1028 } |
969 |
1029 |
974 |
1034 |
975 // store properties |
1035 // store properties |
976 int r = 0; |
1036 int r = 0; |
977 sn->error = DAV_OK; |
1037 sn->error = DAV_OK; |
978 if(data->set || data->remove) { |
1038 if(data->set || data->remove) { |
979 UcxBuffer *request = create_proppatch_request(data); |
1039 CxBuffer *request = create_proppatch_request(data); |
980 UcxBuffer *response = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND); |
1040 CxBuffer *response = cxBufferCreate(NULL, 1024, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
981 //printf("request:\n%.*s\n\n", request->pos, request->space); |
1041 //printf("request:\n%.*s\n\n", request->pos, request->space); |
982 |
1042 |
983 CURLcode ret = do_proppatch_request(sn, locktoken, request, response); |
1043 CURLcode ret = do_proppatch_request(sn, locktoken, request, response); |
984 long status = 0; |
1044 long status = 0; |
985 curl_easy_getinfo (sn->handle, CURLINFO_RESPONSE_CODE, &status); |
1045 curl_easy_getinfo (sn->handle, CURLINFO_RESPONSE_CODE, &status); |
1127 util_set_url(res->session, dav_resource_get_href(res)); |
1187 util_set_url(res->session, dav_resource_get_href(res)); |
1128 |
1188 |
1129 DavLock *lock = dav_get_lock(res->session, res->path); |
1189 DavLock *lock = dav_get_lock(res->session, res->path); |
1130 char *locktoken = lock ? lock->token : NULL; |
1190 char *locktoken = lock ? lock->token : NULL; |
1131 |
1191 |
1132 UcxBuffer *response = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND); |
1192 CxBuffer *response = cxBufferCreate(NULL, 4096, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
1133 CURLcode ret = do_delete_request(res->session, locktoken, response); |
1193 CURLcode ret = do_delete_request(res->session, locktoken, response); |
1134 long status = 0; |
1194 long status = 0; |
1135 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); |
1195 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); |
1136 int r = 0; |
1196 int r = 0; |
1137 if(ret == CURLE_OK && (status >= 200 && status < 300)) { |
1197 if(ret == CURLE_OK && (status >= 200 && status < 300)) { |
1170 util_set_url(sn, h); |
1230 util_set_url(sn, h); |
1171 code = do_mkcol_request(sn, locktoken); |
1231 code = do_mkcol_request(sn, locktoken); |
1172 curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &status); |
1232 curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &status); |
1173 if(status == 201) { |
1233 if(status == 201) { |
1174 // resource successfully created |
1234 // resource successfully created |
1175 char *name = util_resource_name(p); |
1235 char *name = (char*)util_resource_name(p); |
1176 int len = strlen(name); |
1236 int len = strlen(name); |
1177 if(name[len - 1] == '/') { |
1237 if(name[len - 1] == '/') { |
1178 name[len - 1] = '\0'; |
1238 name[len - 1] = '\0'; |
1179 } |
1239 } |
1180 if(resource_add_crypto_info(sn, h, name, NULL)) { |
1240 if(resource_add_crypto_info(sn, h, name, NULL)) { |
1223 if(code == CURLE_OK && (s >= 200 && s < 300)) { |
1283 if(code == CURLE_OK && (s >= 200 && s < 300)) { |
1224 sn->error = DAV_OK; |
1284 sn->error = DAV_OK; |
1225 // if the session has encrypted file names, add crypto infos |
1285 // if the session has encrypted file names, add crypto infos |
1226 if(!resource_add_crypto_info(sn, res->href, res->name, NULL)) { |
1286 if(!resource_add_crypto_info(sn, res->href, res->name, NULL)) { |
1227 // do a minimal propfind request |
1287 // do a minimal propfind request |
1228 UcxBuffer *rqbuf = create_propfind_request(sn, NULL, "propfind", 0); |
1288 CxBuffer *rqbuf = create_propfind_request(sn, NULL, "propfind", 0); |
1229 int ret = dav_propfind(sn, res, rqbuf); |
1289 int ret = dav_propfind(sn, res, rqbuf); |
1230 ucx_buffer_free(rqbuf); |
1290 cxBufferFree(rqbuf); |
1231 return ret; |
1291 return ret; |
1232 } else { |
1292 } else { |
1233 return 1; |
1293 return 1; |
1234 } |
1294 } |
1235 } else { |
1295 } else { |
1329 int dav_lock_t(DavResource *res, time_t timeout) { |
1389 int dav_lock_t(DavResource *res, time_t timeout) { |
1330 DavSession *sn = res->session; |
1390 DavSession *sn = res->session; |
1331 CURL *handle = sn->handle; |
1391 CURL *handle = sn->handle; |
1332 util_set_url(sn, dav_resource_get_href(res)); |
1392 util_set_url(sn, dav_resource_get_href(res)); |
1333 |
1393 |
1334 UcxBuffer *request = create_lock_request(); |
1394 CxBuffer *request = create_lock_request(); |
1335 UcxBuffer *response = ucx_buffer_new(NULL, 512, UCX_BUFFER_AUTOEXTEND); |
1395 CxBuffer *response = cxBufferCreate(NULL, 512, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
1336 CURLcode ret = do_lock_request(sn, request, response, timeout); |
1396 CURLcode ret = do_lock_request(sn, request, response, timeout); |
1337 |
1397 |
1338 //printf("\nlock\n"); |
1398 //printf("\nlock\n"); |
1339 //printf("%.*s\n\n", request->size, request->space); |
1399 //printf("%.*s\n\n", request->size, request->space); |
1340 //printf("%.*s\n\n", response->size, response->space); |
1400 //printf("%.*s\n\n", response->size, response->space); |
1341 |
1401 |
1342 ucx_buffer_free(request); |
1402 cxBufferFree(request); |
1343 |
1403 |
1344 long status = 0; |
1404 long status = 0; |
1345 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); |
1405 curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); |
1346 if(ret == CURLE_OK && (status >= 200 && status < 300)) { |
1406 if(ret == CURLE_OK && (status >= 200 && status < 300)) { |
1347 LockDiscovery lock; |
1407 LockDiscovery lock; |
1348 if(parse_lock_response(sn, response, &lock)) { |
1408 int parse_error = parse_lock_response(sn, response, &lock); |
|
1409 cxBufferFree(response); |
|
1410 if(parse_error) { |
1349 sn->error = DAV_ERROR; |
1411 sn->error = DAV_ERROR; |
1350 ucx_buffer_free(response); |
|
1351 return -1; |
1412 return -1; |
1352 } |
1413 } |
1353 ucx_buffer_free(response); |
|
1354 |
1414 |
1355 DavLock *l = dav_create_lock(sn, lock.locktoken, lock.timeout); |
1415 DavLock *l = dav_create_lock(sn, lock.locktoken, lock.timeout); |
1356 free(lock.locktoken); |
1416 free(lock.locktoken); |
1357 free(lock.timeout); |
1417 free(lock.timeout); |
1358 |
1418 |
1406 int resource_add_crypto_info(DavSession *sn, const char *href, const char *name, const char *hash) { |
1466 int resource_add_crypto_info(DavSession *sn, const char *href, const char *name, const char *hash) { |
1407 if(!DAV_IS_ENCRYPTED(sn)) { |
1467 if(!DAV_IS_ENCRYPTED(sn)) { |
1408 return 0; |
1468 return 0; |
1409 } |
1469 } |
1410 |
1470 |
1411 UcxBuffer *request = create_crypto_proppatch_request(sn, sn->key, name, hash); |
1471 CxBuffer *request = create_crypto_proppatch_request(sn, sn->key, name, hash); |
1412 UcxBuffer *response = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND); |
1472 CxBuffer *response = cxBufferCreate(NULL, 1024, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
1413 |
1473 |
1414 util_set_url(sn, href); |
1474 util_set_url(sn, href); |
1415 // TODO: lock |
1475 // TODO: lock |
1416 CURLcode ret = do_proppatch_request(sn, NULL, request, response); |
1476 CURLcode ret = do_proppatch_request(sn, NULL, request, response); |
1417 ucx_buffer_free(request); |
1477 cxBufferFree(request); |
1418 long status = 0; |
1478 long status = 0; |
1419 curl_easy_getinfo (sn->handle, CURLINFO_RESPONSE_CODE, &status); |
1479 curl_easy_getinfo (sn->handle, CURLINFO_RESPONSE_CODE, &status); |
1420 if(ret == CURLE_OK && status == 207) { |
1480 if(ret == CURLE_OK && status == 207) { |
1421 // TODO: parse response |
1481 // TODO: parse response |
1422 sn->error = DAV_OK; |
1482 sn->error = DAV_OK; |
1423 ucx_buffer_free(response); |
1483 cxBufferFree(response); |
1424 return 0; |
1484 return 0; |
1425 } else { |
1485 } else { |
1426 dav_session_set_error(sn, ret, status); |
1486 dav_session_set_error(sn, ret, status); |
1427 ucx_buffer_free(response); |
1487 cxBufferFree(response); |
1428 return 1; |
1488 return 1; |
1429 } |
1489 } |
1430 } |
1490 } |
1431 |
1491 |
1432 /* ----------------------------- crypto-prop ----------------------------- */ |
1492 /* ----------------------------- crypto-prop ----------------------------- */ |
1433 |
1493 |
1434 DavXmlNode* create_crypto_prop(DavSession *sn, UcxMap *properties) { |
1494 DavXmlNode* create_crypto_prop(DavSession *sn, CxMap *properties) { |
1435 if(!sn->key) { |
1495 if(!sn->key) { |
1436 return NULL; |
1496 return NULL; |
1437 } |
1497 } |
1438 |
1498 |
1439 UcxBuffer *content = ucx_buffer_new(NULL, 2048, UCX_BUFFER_AUTOEXTEND); |
1499 CxBuffer *content = cxBufferCreate(NULL, 2048, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
1440 |
1500 |
1441 // create an xml document containing all properties |
1501 // create an xml document containing all properties |
1442 UcxMap *nsmap = ucx_map_new(8); |
1502 CxMap *nsmap = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 8); |
1443 ucx_map_cstr_put(nsmap, "DAV:", strdup("D")); |
1503 nsmap->simple_destructor = free; |
1444 |
1504 cxMapPut(nsmap, cx_hash_key_str("DAV:"), strdup("D")); |
1445 ucx_buffer_puts(content, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); |
1505 |
1446 ucx_buffer_puts(content, "<D:prop xmlns:D=\"DAV:\">\n"); |
1506 cxBufferPutString(content, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); |
1447 |
1507 cxBufferPutString(content, "<D:prop xmlns:D=\"DAV:\">\n"); |
1448 UcxMapIterator i = ucx_map_iterator(properties); |
1508 |
|
1509 CxIterator i = cxMapIteratorValues(properties); |
1449 DavProperty *prop; |
1510 DavProperty *prop; |
1450 UCX_MAP_FOREACH(key, prop, i) { |
1511 cx_foreach(DavProperty*, prop, i) { |
1451 DavXmlNode pnode; |
1512 DavXmlNode pnode; |
1452 pnode.type = DAV_XML_ELEMENT; |
1513 pnode.type = DAV_XML_ELEMENT; |
1453 pnode.namespace = prop->ns->name; |
1514 pnode.namespace = prop->ns->name; |
1454 pnode.name = prop->name; |
1515 pnode.name = prop->name; |
1455 pnode.prev = NULL; |
1516 pnode.prev = NULL; |
1458 pnode.parent = NULL; |
1519 pnode.parent = NULL; |
1459 pnode.attributes = NULL; |
1520 pnode.attributes = NULL; |
1460 pnode.content = NULL; |
1521 pnode.content = NULL; |
1461 pnode.contentlength = 0; |
1522 pnode.contentlength = 0; |
1462 |
1523 |
1463 dav_print_node(content, (write_func)ucx_buffer_write, nsmap, &pnode); |
1524 dav_print_node(content, (cx_write_func)cxBufferWrite, nsmap, &pnode); |
1464 ucx_buffer_putc(content, '\n'); |
1525 cxBufferPut(content, '\n'); |
1465 } |
1526 } |
1466 |
1527 |
1467 ucx_buffer_puts(content, "</D:prop>"); |
1528 cxBufferPutString(content, "</D:prop>"); |
1468 |
1529 |
1469 ucx_map_free_content(nsmap, (ucx_destructor)free); |
1530 cxMapDestroy(nsmap); |
1470 ucx_map_free(nsmap); |
|
1471 |
1531 |
1472 // encrypt xml document |
1532 // encrypt xml document |
1473 char *crypto_prop_content = aes_encrypt(content->space, content->size, sn->key); |
1533 char *crypto_prop_content = aes_encrypt(content->space, content->size, sn->key); |
1474 ucx_buffer_free(content); |
1534 cxBufferDestroy(content); |
1475 |
1535 |
1476 DavXmlNode *ret = NULL; |
1536 DavXmlNode *ret = NULL; |
1477 if(crypto_prop_content) { |
1537 if(crypto_prop_content) { |
1478 ret = dav_text_node(sn, crypto_prop_content); |
1538 ret = dav_text_node(sn, crypto_prop_content); |
1479 free(crypto_prop_content); |
1539 free(crypto_prop_content); |
1480 } |
1540 } |
1481 return ret; |
1541 return ret; |
1482 } |
1542 } |
1483 |
1543 |
1484 UcxMap* parse_crypto_prop(DavSession *sn, DavKey *key, DavXmlNode *node) { |
1544 CxMap* parse_crypto_prop(DavSession *sn, DavKey *key, DavXmlNode *node) { |
1485 if(!node || node->type != DAV_XML_TEXT || node->contentlength == 0) { |
1545 if(!node || node->type != DAV_XML_TEXT || node->contentlength == 0) { |
1486 return NULL; |
1546 return NULL; |
1487 } |
1547 } |
1488 |
1548 |
1489 return parse_crypto_prop_str(sn, key, node->content); |
1549 return parse_crypto_prop_str(sn, key, node->content); |
1490 } |
1550 } |
1491 |
1551 |
1492 UcxMap* parse_crypto_prop_str(DavSession *sn, DavKey *key, const char *content) { |
1552 CxMap* parse_crypto_prop_str(DavSession *sn, DavKey *key, const char *content) { |
1493 size_t len = 0; |
1553 size_t len = 0; |
1494 char *dec_str = aes_decrypt(content, &len, key); |
1554 char *dec_str = aes_decrypt(content, &len, key); |
1495 |
1555 |
1496 xmlDoc *doc = xmlReadMemory(dec_str, len, NULL, NULL, 0); |
1556 xmlDoc *doc = xmlReadMemory(dec_str, len, NULL, NULL, 0); |
1497 free(dec_str); |
1557 free(dec_str); |
1529 property->ns->name = dav_session_strdup(sn, (const char*)n->ns->href); |
1589 property->ns->name = dav_session_strdup(sn, (const char*)n->ns->href); |
1530 property->ns->prefix = n->ns->prefix ? |
1590 property->ns->prefix = n->ns->prefix ? |
1531 dav_session_strdup(sn, (const char*)n->ns->prefix) : NULL; |
1591 dav_session_strdup(sn, (const char*)n->ns->prefix) : NULL; |
1532 property->value = n->children ? dav_convert_xml(sn, n->children) : NULL; |
1592 property->value = n->children ? dav_convert_xml(sn, n->children) : NULL; |
1533 |
1593 |
1534 sstr_t key = dav_property_key(property->ns->name, property->name); |
1594 cxmutstr key = dav_property_key(property->ns->name, property->name); |
1535 ucx_map_sstr_put(map, key, property); |
1595 cxMapPut(map, cx_hash_key(key.ptr, key.length), property); |
1536 free(key.ptr); |
1596 free(key.ptr); |
1537 } |
1597 } |
1538 n = n->next; |
1598 n = n->next; |
1539 } |
1599 } |
1540 |
1600 |
1541 xmlFreeDoc(doc); |
1601 xmlFreeDoc(doc); |
1542 if(map->count == 0) { |
1602 if(map->size == 0) { |
1543 ucx_map_free(map); |
1603 cxMapDestroy(map); |
1544 return NULL; |
1604 return NULL; |
1545 } |
1605 } |
1546 return map; |
1606 return map; |
1547 } |
1607 } |
1548 |
1608 |