Thu, 03 Oct 2024 18:08:29 +0200
implement action_newfile
1 | 1 | /* |
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. | |
3 | * | |
4 | * Copyright 2018 Olaf Wintermann. All rights reserved. | |
5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions are met: | |
8 | * | |
9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | |
11 | * | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | |
15 | * | |
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | |
20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | |
28 | ||
29 | #include <stdio.h> | |
30 | #include <stdlib.h> | |
31 | #include <string.h> | |
32 | #include <libxml/tree.h> | |
33 | ||
34 | #include "utils.h" | |
35 | #include "webdav.h" | |
36 | #include "session.h" | |
37 | #include "methods.h" | |
38 | #include <cx/buffer.h> | |
39 | #include <cx/utils.h> | |
40 | #include <cx/linked_list.h> | |
41 | #include <cx/hash_map.h> | |
42 | #include <cx/compare.h> | |
43 | #include "davqlparser.h" | |
44 | #include "davqlexec.h" | |
45 | ||
46 | ||
47 | DavContext* dav_context_new(void) { | |
48 | // initialize | |
49 | DavContext *context = calloc(1, sizeof(DavContext)); | |
50 | if(!context) { | |
51 | return NULL; | |
52 | } | |
53 | context->sessions = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_intptr, CX_STORE_POINTERS); | |
54 | context->sessions->destructor_data = dav_session_destructor; | |
55 | context->http_proxy = calloc(1, sizeof(DavProxy)); | |
56 | if(!context->http_proxy) { | |
57 | dav_context_destroy(context); | |
58 | return NULL; | |
59 | } | |
60 | context->https_proxy = calloc(1, sizeof(DavProxy)); | |
61 | if(!context->https_proxy) { | |
62 | dav_context_destroy(context); | |
63 | return NULL; | |
64 | } | |
65 | context->namespaces = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16); | |
66 | if(!context->namespaces) { | |
67 | dav_context_destroy(context); | |
68 | return NULL; | |
69 | } | |
70 | context->namespaceinfo = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16); | |
71 | if(!context->namespaceinfo) { | |
72 | dav_context_destroy(context); | |
73 | } | |
74 | context->keys = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16); | |
75 | if(!context->keys) { | |
76 | dav_context_destroy(context); | |
77 | return NULL; | |
78 | } | |
79 | ||
80 | // add DAV: namespace | |
81 | if(dav_add_namespace(context, "D", "DAV:")) { | |
82 | dav_context_destroy(context); | |
83 | return NULL; | |
84 | } | |
85 | ||
86 | ||
87 | // add idav namespace | |
88 | if(dav_add_namespace(context, "idav", DAV_NS)) { | |
89 | dav_context_destroy(context); | |
90 | return NULL; | |
91 | } | |
92 | ||
93 | // add idavprops namespace | |
94 | if(dav_add_namespace(context, "idavprops", DAV_PROPS_NS)) { | |
95 | dav_context_destroy(context); | |
96 | return NULL; | |
97 | } | |
98 | ||
99 | return context; | |
100 | } | |
101 | ||
102 | void dav_context_destroy(DavContext *ctx) { | |
103 | // destroy all sessions assoziated with this context | |
104 | // ctx->sessions destructor must be dav_session_destructor | |
105 | cxListDestroy(ctx->sessions); | |
106 | ||
107 | if(ctx->http_proxy) { | |
108 | free(ctx->http_proxy); | |
109 | } | |
110 | if(ctx->https_proxy) { | |
111 | free(ctx->https_proxy); | |
112 | } | |
113 | ||
114 | if(ctx->namespaces) { | |
115 | CxIterator i = cxMapIteratorValues(ctx->namespaces); | |
116 | cx_foreach(DavNamespace*, ns, i) { | |
117 | if(!ns) continue; | |
118 | if(ns->prefix) { | |
119 | free(ns->prefix); | |
120 | } | |
121 | if(ns->name) { | |
122 | free(ns->name); | |
123 | } | |
124 | free(ns); | |
125 | } | |
126 | cxMapDestroy(ctx->namespaces); | |
127 | } | |
128 | if(ctx->namespaceinfo) { | |
129 | // TODO: implement | |
130 | } | |
131 | if(ctx->keys) { | |
132 | CxIterator i = cxMapIteratorValues(ctx->keys); | |
133 | cx_foreach(DavKey*, key, i) { | |
134 | if(!key) continue; | |
135 | if(key->name) { | |
136 | free(key->name); | |
137 | } | |
138 | if(key->data) { | |
139 | free(key->data); | |
140 | } | |
141 | free(key); | |
142 | } | |
143 | cxMapDestroy(ctx->keys); | |
144 | } | |
145 | ||
146 | free(ctx); | |
147 | } | |
148 | ||
18
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
149 | #ifndef _WIN32 |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
150 | |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
151 | void dav_context_set_mtsafe(DavContext *ctx, DavBool enable) { |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
152 | if (enable) { |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
153 | pthread_mutex_init(&ctx->mutex, NULL); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
154 | } else { |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
155 | pthread_mutex_destroy(&ctx->mutex); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
156 | } |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
157 | ctx->mtsafe = enable; |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
158 | } |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
159 | |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
160 | void dav_context_lock(DavContext *ctx) { |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
161 | if (ctx->mtsafe) { |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
162 | pthread_mutex_lock(&ctx->mutex); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
163 | } |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
164 | } |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
165 | |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
166 | void dav_context_unlock(DavContext *ctx) { |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
167 | if (ctx->mtsafe) { |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
168 | pthread_mutex_unlock(&ctx->mutex); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
169 | } |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
170 | } |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
171 | |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
172 | #else |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
173 | |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
174 | void dav_context_set_mtsafe(DavContext *ctx, DavBool enable) { |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
175 | if (enable) { |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
176 | ctx->mutex = CreateMutex(NULL, FALSE, NULL); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
177 | } else { |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
178 | CloseHandle(ctx->mutex); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
179 | } |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
180 | ctx->mtsafe = enable; |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
181 | } |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
182 | |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
183 | void dav_context_lock(DavContext *ctx) { |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
184 | if (ctx->mtsafe) { |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
185 | WaitForSingleObject(ctx->mutex, INFINITE); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
186 | } |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
187 | } |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
188 | |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
189 | void dav_context_unlock(DavContext *ctx) { |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
190 | if (ctx->mtsafe) { |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
191 | ReleaseMutex(ctx->mutex); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
192 | } |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
193 | } |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
194 | |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
195 | #endif |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
196 | |
1 | 197 | void dav_context_add_key(DavContext *context, DavKey *key) { |
18
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
198 | dav_context_lock(context); |
1 | 199 | cxMapPut(context->keys, cx_hash_key_str(key->name), key); |
18
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
200 | dav_context_unlock(context); |
1 | 201 | } |
202 | ||
203 | DavKey* dav_context_get_key(DavContext *context, const char *name) { | |
18
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
204 | DavKey *key = NULL; |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
205 | dav_context_lock(context); |
1 | 206 | if(name) { |
18
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
207 | key = cxMapGet(context->keys, cx_hash_key_str(name)); |
1 | 208 | } |
18
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
209 | dav_context_unlock(context); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
210 | return key; |
1 | 211 | } |
212 | ||
213 | int dav_add_namespace(DavContext *context, const char *prefix, const char *name) { | |
214 | DavNamespace *namespace = malloc(sizeof(DavNamespace)); | |
215 | if(!namespace) { | |
216 | return 1; | |
217 | } | |
218 | ||
219 | char *p = strdup(prefix); | |
18
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
220 | if (!p) { |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
221 | free(namespace); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
222 | return 1; |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
223 | } |
1 | 224 | char *n = strdup(name); |
18
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
225 | if (!n) { |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
226 | free(namespace); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
227 | free(p); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
228 | return 1; |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
229 | } |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
230 | |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
231 | dav_context_lock(context); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
232 | |
1 | 233 | int err = 0; |
234 | if(p && n) { | |
235 | namespace->prefix = p; | |
236 | namespace->name = n; | |
237 | err = cxMapPut(context->namespaces, cx_hash_key_str(prefix), namespace); | |
238 | } | |
239 | ||
240 | if(err) { | |
241 | free(namespace); | |
242 | if(p) free(p); | |
243 | if(n) free(n); | |
244 | } | |
18
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
245 | |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
246 | dav_context_unlock(context); |
1 | 247 | |
248 | return err; | |
249 | } | |
250 | ||
251 | DavNamespace* dav_get_namespace(DavContext *context, const char *prefix) { | |
18
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
252 | dav_context_lock(context); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
253 | DavNamespace *ns = cxMapGet(context->namespaces, cx_hash_key_str(prefix)); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
254 | dav_context_unlock(context); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
255 | return ns; |
1 | 256 | } |
257 | ||
258 | DavNamespace* dav_get_namespace_s(DavContext *context, cxstring prefix) { | |
18
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
259 | dav_context_lock(context); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
260 | DavNamespace *ns = cxMapGet(context->namespaces, cx_hash_key(prefix.ptr, prefix.length)); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
261 | dav_context_unlock(context); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
262 | return ns; |
1 | 263 | } |
264 | ||
265 | int dav_enable_namespace_encryption(DavContext *context, const char *ns, DavBool encrypt) { | |
18
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
266 | dav_context_lock(context); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
267 | |
1 | 268 | CxHashKey hkey = cx_hash_key_str(ns); |
269 | DavNSInfo *info = cxMapGet(context->namespaceinfo, hkey); | |
270 | if(!info) { | |
271 | info = calloc(1, sizeof(DavNSInfo)); | |
272 | info->encrypt = encrypt; | |
273 | cxMapPut(context->namespaceinfo, hkey, info); | |
274 | } else { | |
275 | info->encrypt = encrypt; | |
276 | } | |
18
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
277 | |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
278 | dav_context_unlock(context); |
1 | 279 | return 0; |
280 | } | |
281 | ||
282 | int dav_namespace_is_encrypted(DavContext *context, const char *ns) { | |
18
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
283 | int ret = 0; |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
284 | dav_context_lock(context); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
285 | |
1 | 286 | DavNSInfo *info = cxMapGet(context->namespaceinfo, cx_hash_key_str(ns)); |
287 | if(info) { | |
18
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
288 | ret = info->encrypt; |
1 | 289 | } |
18
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
290 | dav_context_unlock(context); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
291 | return ret; |
1 | 292 | } |
293 | ||
294 | void dav_get_property_namespace_str( | |
295 | DavContext *ctx, | |
296 | char *prefixed_name, | |
297 | char **ns, | |
298 | char **name) | |
299 | { | |
300 | // TODO: rewrite using dav_get_property_ns | |
301 | ||
302 | char *pname = strchr(prefixed_name, ':'); | |
303 | char *pns = "DAV:"; | |
304 | if(pname) { | |
305 | DavNamespace *ns = dav_get_namespace_s( | |
306 | ctx, | |
307 | cx_strn(prefixed_name, pname-prefixed_name)); | |
308 | if(ns) { | |
309 | pns = ns->name; | |
310 | pname++; | |
311 | } else { | |
312 | pns = NULL; | |
313 | pname = NULL; | |
314 | } | |
315 | } else { | |
316 | pname = prefixed_name; | |
317 | } | |
318 | *ns = pns; | |
319 | *name = pname; | |
320 | } | |
321 | ||
322 | DavNamespace* dav_get_property_namespace( | |
323 | DavContext *ctx, | |
324 | char *prefixed_name, | |
325 | char **name) | |
326 | { | |
327 | char *pname = strchr(prefixed_name, ':'); | |
328 | if(pname) { | |
329 | DavNamespace *ns = dav_get_namespace_s( | |
330 | ctx, | |
331 | cx_strn(prefixed_name, pname-prefixed_name)); | |
332 | if(ns) { | |
333 | *name = pname +1; | |
334 | return ns; | |
335 | } else { | |
336 | *name = NULL; | |
337 | return NULL; | |
338 | } | |
339 | } else { | |
340 | *name = prefixed_name; | |
341 | return dav_get_namespace_s(ctx, cx_str("D")); | |
342 | } | |
343 | } | |
344 | ||
18
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
345 | int dav_context_add_session(DavContext *context, DavSession *sn) { |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
346 | dav_context_lock(context); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
347 | int ret = cxListAdd(context->sessions, sn); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
348 | dav_context_unlock(context); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
349 | return ret; |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
350 | } |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
351 | |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
352 | int dav_context_remove_session(DavContext *context, DavSession *sn) { |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
353 | int ret = 0; |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
354 | dav_context_lock(context); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
355 | CxList *sessions = context->sessions; |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
356 | ssize_t i = cxListFind(sessions, sn); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
357 | if(i >= 0) { |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
358 | cxListRemove(sessions, i); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
359 | } else { |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
360 | ret = 1; |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
361 | } |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
362 | dav_context_unlock(context); |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
363 | return ret; |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
364 | } |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
365 | |
af411868ab9b
implement dnd upload (without progressbar)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
366 | |
1 | 367 | // TODO: add sstr_t version of dav_get_property_ns |
368 | ||
369 | void dav_set_effective_href(DavSession *sn, DavResource *resource) { | |
370 | char *eff_url; | |
371 | curl_easy_getinfo(sn->handle, CURLINFO_EFFECTIVE_URL, &eff_url); | |
372 | if(eff_url) { | |
373 | const char *href = util_url_path(eff_url); | |
374 | if(strcmp(href, resource->href)) { | |
375 | dav_session_free(sn, resource->href); | |
376 | resource->href = dav_session_strdup(sn, href); | |
377 | } | |
378 | } | |
379 | } | |
380 | ||
381 | DavResource* dav_get(DavSession *sn, char *path, const char *properties) { | |
382 | CURL *handle = sn->handle; | |
383 | DavResource *resource = dav_resource_new(sn, path); | |
384 | util_set_url(sn, dav_resource_get_href(resource)); | |
385 | ||
386 | CxList *proplist = NULL; | |
387 | if(properties) { | |
388 | proplist = parse_properties_string(sn->context, cx_str(properties)); | |
389 | } | |
390 | CxBuffer *rqbuf = create_propfind_request(sn, proplist, "propfind", 0); | |
391 | CxBuffer *rpbuf = cxBufferCreate(NULL, 4096, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); | |
392 | ||
393 | //fwrite(rqbuf->space, 1, rqbuf->size, stdout); | |
394 | //printf("\n"); | |
395 | ||
396 | CURLcode ret = do_propfind_request(sn, rqbuf, rpbuf); | |
397 | long status = 0; | |
398 | curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); | |
399 | if(ret == CURLE_OK && status == 207) { | |
400 | dav_set_effective_href(sn, resource); | |
401 | ||
402 | //printf("response\n%s\n", rpbuf->space); | |
403 | // TODO: use PropfindParser | |
404 | resource = parse_propfind_response(sn, resource, rpbuf); | |
405 | resource->exists = 1; | |
406 | sn->error = DAV_OK; | |
407 | } else { | |
408 | dav_session_set_error(sn, ret, status); | |
409 | dav_resource_free(resource); | |
410 | resource = NULL; | |
411 | } | |
412 | ||
413 | cxBufferFree(rqbuf); | |
414 | cxBufferFree(rpbuf); | |
415 | ||
416 | if(proplist) { | |
417 | CxIterator i = cxListIterator(proplist); | |
418 | cx_foreach(DavProperty*, p, i) { | |
419 | free(p->name); | |
420 | } | |
421 | cxListDestroy(proplist); | |
422 | } | |
423 | ||
424 | return resource; | |
425 | } | |
426 | ||
427 | ||
428 | int dav_propfind(DavSession *sn, DavResource *root, CxBuffer *rqbuf) { | |
429 | // clean resource properties | |
430 | DavResourceData *data = root->data; | |
431 | cxMapClear(data->properties); // TODO: free existing content | |
432 | ||
433 | CURL *handle = sn->handle; | |
434 | util_set_url(sn, dav_resource_get_href(root)); | |
435 | ||
436 | CxBuffer *rpbuf = cxBufferCreate(NULL, 4096, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); | |
437 | DavResource *resource = root; | |
438 | CURLcode ret = do_propfind_request(sn, rqbuf, rpbuf); | |
439 | long status = 0; | |
440 | long error = 0; | |
441 | curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); | |
442 | if(ret == CURLE_OK && status == 207) { | |
443 | //printf("response\n%s\n", rpbuf->space); | |
444 | dav_set_effective_href(sn, resource); | |
445 | // TODO: use PropfindParser | |
446 | resource = parse_propfind_response(sn, resource, rpbuf); | |
447 | sn->error = DAV_OK; | |
448 | root->exists = 1; | |
449 | } else { | |
450 | dav_session_set_error(sn, ret, status); | |
451 | error = 1; | |
452 | } | |
453 | cxBufferFree(rpbuf); | |
454 | return error; | |
455 | } | |
456 | ||
457 | CxList* parse_properties_string(DavContext *context, cxstring str) { | |
458 | CxList *proplist = cxLinkedListCreateSimple(sizeof(DavProperty)); | |
459 | ||
460 | CxStrtokCtx tok = cx_strtok(str, cx_str(","), INT_MAX); | |
461 | cxstring s; | |
462 | while(cx_strtok_next(&tok, &s)) { | |
463 | cxstring nsname = cx_strchr(s, ':'); | |
464 | if(nsname.length > 0) { | |
465 | cxstring nspre = cx_strsubsl(s, 0, nsname.ptr - s.ptr); | |
466 | nsname.ptr++; | |
467 | nsname.length--; | |
468 | ||
469 | DavProperty dp; | |
470 | cxstring pre = cx_strtrim(nspre); | |
471 | dp.ns = dav_get_namespace_s(context, pre); | |
472 | dp.name = cx_strdup(nsname).ptr; | |
473 | dp.value = NULL; | |
474 | if(dp.ns && dp.name) { | |
475 | cxListAdd(proplist, &dp); | |
476 | } else { | |
477 | free(dp.name); | |
478 | } | |
479 | } | |
480 | } | |
481 | ||
482 | return proplist; | |
483 | } | |
484 | ||
485 | DavResource* dav_query(DavSession *sn, char *query, ...) { | |
486 | DavQLStatement *stmt = dav_parse_statement(cx_str(query)); | |
487 | if(!stmt) { | |
488 | sn->error = DAV_ERROR; | |
489 | return NULL; | |
490 | } | |
491 | if(stmt->errorcode != 0) { | |
492 | sn->error = DAV_QL_ERROR; | |
493 | dav_free_statement(stmt); | |
494 | return NULL; | |
495 | } | |
496 | ||
497 | va_list ap; | |
498 | va_start(ap, query); | |
499 | DavResult result = dav_statement_execv(sn, stmt, ap); | |
500 | va_end(ap); | |
501 | ||
502 | dav_free_statement(stmt); | |
503 | ||
504 | if(result.status == -1) { | |
505 | if(result.result) { | |
506 | dav_resource_free(result.result); | |
507 | result.result = NULL; | |
508 | } | |
509 | } | |
510 | ||
511 | return result.result; | |
512 | } | |
513 | ||
514 | ||
515 | ||
516 | ||
517 | void dav_verbose_log( | |
518 | DavSession *sn, | |
519 | const char *method, | |
520 | const char *url, | |
521 | const char *request_body, | |
522 | size_t request_bodylen, | |
523 | int status, | |
524 | const char *response_body, | |
525 | size_t response_bodylen) | |
526 | { | |
527 | fprintf(stderr, "# method: %s url: %s status: %d\n", method, url, status); | |
528 | fprintf(stderr, "# request len: %d\n%.*s\n", (int)request_bodylen, (int)request_bodylen, request_body); | |
529 | fprintf(stderr, "# response len: %d\n%.*s\n", (int)response_bodylen, (int)response_bodylen, response_body); | |
530 | } |