|
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 #ifndef WEBDAV_H |
|
30 #define WEBDAV_H |
|
31 |
|
32 #include <inttypes.h> |
|
33 #include <cx/map.h> |
|
34 #include <cx/mempool.h> |
|
35 #include <cx/linked_list.h> |
|
36 #include <cx/string.h> |
|
37 #include <cx/buffer.h> |
|
38 #include <curl/curl.h> |
|
39 #include <libxml/tree.h> |
|
40 |
|
41 #ifdef __cplusplus |
|
42 extern "C" { |
|
43 #endif |
|
44 |
|
45 typedef char DavBool; |
|
46 #ifndef TRUE |
|
47 #define TRUE 1 |
|
48 #endif |
|
49 #ifndef FALSE |
|
50 #define FALSE 0 |
|
51 #endif |
|
52 |
|
53 typedef struct DavContext DavContext; |
|
54 typedef struct DavProxy DavProxy; |
|
55 typedef struct DavSession DavSession; |
|
56 typedef struct DavResource DavResource; |
|
57 typedef struct DavResult DavResult; |
|
58 typedef struct DavNamespace DavNamespace; |
|
59 typedef struct DavProperty DavProperty; |
|
60 typedef struct DavPropName DavPropName; |
|
61 typedef struct DavKey DavKey; |
|
62 typedef struct DavNSInfo DavNSInfo; |
|
63 typedef struct DavXmlNode DavXmlNode; |
|
64 typedef struct DavXmlAttr DavXmlAttr; |
|
65 |
|
66 typedef struct DavInputStream DavInputStream; |
|
67 typedef struct DavOutputStream DavOutputStream; |
|
68 |
|
69 typedef size_t(*dav_read_func)(void*, size_t, size_t, void*); |
|
70 typedef size_t(*dav_write_func)(const void*, size_t, size_t, void*); |
|
71 typedef int(*dav_seek_func)(const void *, long, int); |
|
72 |
|
73 typedef int(*dav_auth_func)(DavSession *, void *); |
|
74 typedef void(*dav_progress_func)(DavResource *, int64_t, int64_t, void *); |
|
75 |
|
76 |
|
77 typedef void(*dav_rqlog_func)( |
|
78 DavSession *sn, |
|
79 const char *method, |
|
80 const char *url, |
|
81 const char *request_body, |
|
82 size_t request_bodylen, |
|
83 int status, |
|
84 const char *response_body, |
|
85 size_t response_bodylen); |
|
86 |
|
87 enum DavError { |
|
88 DAV_OK = 0, |
|
89 DAV_ERROR, |
|
90 DAV_NOT_FOUND, |
|
91 DAV_UNAUTHORIZED, |
|
92 DAV_FORBIDDEN, |
|
93 DAV_METHOD_NOT_ALLOWED, |
|
94 DAV_CONFLICT, |
|
95 DAV_LOCKED, |
|
96 DAV_UNSUPPORTED_PROTOCOL, |
|
97 DAV_COULDNT_RESOLVE_PROXY, |
|
98 DAV_COULDNT_RESOLVE_HOST, |
|
99 DAV_COULDNT_CONNECT, |
|
100 DAV_TIMEOUT, |
|
101 DAV_SSL_ERROR, |
|
102 DAV_QL_ERROR, |
|
103 DAV_CONTENT_VERIFICATION_ERROR, |
|
104 DAV_PRECONDITION_FAILED, |
|
105 DAV_REQUEST_ENTITY_TOO_LARGE, |
|
106 DAV_REQUEST_URL_TOO_LONG, |
|
107 DAV_PROXY_AUTH_REQUIRED, |
|
108 DAV_NET_AUTH_REQUIRED |
|
109 }; |
|
110 |
|
111 typedef enum DavError DavError; |
|
112 |
|
113 enum DavXmlNodeType { |
|
114 DAV_XML_NONE = 0, |
|
115 DAV_XML_ELEMENT, |
|
116 DAV_XML_TEXT |
|
117 }; |
|
118 |
|
119 typedef enum DavXmlNodeType DavXmlNodeType; |
|
120 |
|
121 #define DAV_SESSION_ENCRYPT_CONTENT 0x0001 |
|
122 #define DAV_SESSION_ENCRYPT_NAME 0x0002 |
|
123 #define DAV_SESSION_ENCRYPT_PROPERTIES 0x0004 |
|
124 #define DAV_SESSION_DECRYPT_CONTENT 0x0008 |
|
125 #define DAV_SESSION_DECRYPT_NAME 0x0010 |
|
126 #define DAV_SESSION_DECRYPT_PROPERTIES 0x0020 |
|
127 #define DAV_SESSION_STORE_HASH 0x0040 |
|
128 |
|
129 #define DAV_SESSION_CONTENT_ENCRYPTION 0x0009 |
|
130 #define DAV_SESSION_FULL_ENCRYPTION 0x003f |
|
131 |
|
132 |
|
133 #define DAV_NS "http://davutils.org/" |
|
134 #define DAV_PROPS_NS "http://davutils.org/props/" |
|
135 |
|
136 struct DavNamespace { |
|
137 char *prefix; |
|
138 char *name; |
|
139 }; |
|
140 |
|
141 struct DavResource { |
|
142 DavSession *session; |
|
143 DavResource *prev; |
|
144 DavResource *next; |
|
145 DavResource *parent; |
|
146 DavResource *children; |
|
147 char *name; |
|
148 char *path; |
|
149 char *href; |
|
150 uint64_t contentlength; |
|
151 char *contenttype; |
|
152 time_t creationdate; |
|
153 time_t lastmodified; |
|
154 void *data; |
|
155 int iscollection; |
|
156 int exists; |
|
157 }; |
|
158 |
|
159 struct DavSession { |
|
160 DavContext *context; |
|
161 CURL *handle; |
|
162 char *base_url; |
|
163 CxMempool *mp; |
|
164 CxMap *pathcache; |
|
165 DavKey *key; |
|
166 void *locks; |
|
167 uint32_t flags; |
|
168 DavError error; |
|
169 char *errorstr; |
|
170 |
|
171 int(*auth_prompt)(DavSession *sn, void *userdata); |
|
172 void *authprompt_userdata; |
|
173 |
|
174 dav_rqlog_func logfunc; |
|
175 |
|
176 void(*get_progress)(DavResource *res, int64_t total, int64_t now, void *userdata); |
|
177 void(*put_progress)(DavResource *res, int64_t total, int64_t now, void *userdata); |
|
178 void *progress_userdata; |
|
179 }; |
|
180 |
|
181 struct DavContext { |
|
182 CxMap *namespaces; |
|
183 CxMap *namespaceinfo; |
|
184 CxMap *keys; |
|
185 CxList *sessions; |
|
186 DavProxy *http_proxy; |
|
187 DavProxy *https_proxy; |
|
188 }; |
|
189 |
|
190 struct DavProxy { |
|
191 char *url; |
|
192 char *username; |
|
193 char *password; |
|
194 char *no_proxy; |
|
195 }; |
|
196 |
|
197 struct DavProperty { |
|
198 DavNamespace *ns; |
|
199 char *name; |
|
200 DavXmlNode *value; |
|
201 }; |
|
202 |
|
203 struct DavPropName { |
|
204 char *ns; |
|
205 char *name; |
|
206 }; |
|
207 |
|
208 struct DavResult { |
|
209 DavResource *result; |
|
210 int status; |
|
211 }; |
|
212 |
|
213 #define DAV_KEY_AES128 0 |
|
214 #define DAV_KEY_AES256 1 |
|
215 |
|
216 struct DavKey { |
|
217 char *name; |
|
218 int type; |
|
219 void *data; |
|
220 size_t length; |
|
221 }; |
|
222 |
|
223 struct DavNSInfo { |
|
224 char *prefix; |
|
225 DavBool encrypt; |
|
226 }; |
|
227 |
|
228 struct DavXmlNode { |
|
229 DavXmlNodeType type; |
|
230 |
|
231 char *namespace; |
|
232 char *name; |
|
233 |
|
234 DavXmlNode *prev; |
|
235 DavXmlNode *next; |
|
236 DavXmlNode *children; |
|
237 DavXmlNode *parent; |
|
238 |
|
239 DavXmlAttr *attributes; |
|
240 |
|
241 char *content; |
|
242 size_t contentlength; |
|
243 }; |
|
244 |
|
245 struct DavXmlAttr { |
|
246 char *name; |
|
247 char *value; |
|
248 DavXmlAttr *next; |
|
249 }; |
|
250 |
|
251 DavContext* dav_context_new(void); |
|
252 void dav_context_destroy(DavContext *ctx); |
|
253 |
|
254 void dav_context_add_key(DavContext *context, DavKey *key); |
|
255 DavKey* dav_context_get_key(DavContext *context, const char *name); |
|
256 |
|
257 int dav_add_namespace(DavContext *context, const char *prefix, const char *ns); |
|
258 DavNamespace* dav_get_namespace(DavContext *context, const char *prefix); |
|
259 DavNamespace* dav_get_namespace_s(DavContext *context, cxstring prefix); |
|
260 |
|
261 int dav_enable_namespace_encryption(DavContext *context, const char *ns, DavBool encrypt); |
|
262 int dav_namespace_is_encrypted(DavContext *context, const char *ns); |
|
263 |
|
264 DavSession* dav_session_new(DavContext *context, char *base_url); |
|
265 DavSession* dav_session_new_auth( |
|
266 DavContext *context, |
|
267 char *base_url, |
|
268 char *user, |
|
269 char *password); |
|
270 void dav_session_set_auth(DavSession *sn, char *user, char *password); |
|
271 void dav_session_set_baseurl(DavSession *sn, char *base_url); |
|
272 void dav_session_enable_encryption(DavSession *sn, DavKey *key, int flags); |
|
273 |
|
274 void dav_session_set_authcallback(DavSession *sn, dav_auth_func func, void *userdata); |
|
275 void dav_session_set_progresscallback(DavSession *sn, dav_progress_func get, dav_progress_func put, void *userdata); |
|
276 |
|
277 void dav_session_destroy(DavSession *sn); |
|
278 |
|
279 void dav_session_destructor(DavSession *sn); |
|
280 |
|
281 void* dav_session_malloc(DavSession *sn, size_t size); |
|
282 void* dav_session_calloc(DavSession *sn, size_t nelm, size_t size); |
|
283 void* dav_session_realloc(DavSession *sn, void *ptr, size_t size); |
|
284 void dav_session_free(DavSession *sn, void *ptr); |
|
285 char* dav_session_strdup(DavSession *sn, const char *str); |
|
286 |
|
287 void dav_set_effective_href(DavSession *sn, DavResource *resource); |
|
288 DavResource* dav_get(DavSession *sn, char *path, const char *properties); |
|
289 |
|
290 CxList* parse_properties_string(DavContext *context, cxstring str); |
|
291 |
|
292 DavResource* dav_query(DavSession *sn, char *query, ...); |
|
293 |
|
294 cxmutstr dav_property_key(const char *ns, const char *name); |
|
295 void dav_get_property_namespace_str( |
|
296 DavContext *ctx, |
|
297 char *prefixed_name, |
|
298 char **ns, |
|
299 char **name); |
|
300 DavNamespace* dav_get_property_namespace( |
|
301 DavContext *ctx, |
|
302 char *prefixed_name, |
|
303 char **name); |
|
304 |
|
305 /* ------------------------ resource functions ------------------------ */ |
|
306 |
|
307 DavResource* dav_resource_new(DavSession *sn, const char *path); |
|
308 DavResource* dav_resource_new_child(DavSession *sn, DavResource *parent, const char *name); |
|
309 DavResource* dav_resource_new_href(DavSession *sn, const char *href); |
|
310 |
|
311 void dav_resource_free(DavResource *res); |
|
312 void dav_resource_free_all(DavResource *res); |
|
313 |
|
314 char* dav_resource_get_href(DavResource *resource); |
|
315 |
|
316 DavResource* dav_create_child(DavResource *parent, char *name); |
|
317 int dav_delete(DavResource *res); |
|
318 int dav_create(DavResource *res); |
|
319 int dav_exists(DavResource *res); |
|
320 |
|
321 int dav_copy(DavResource *res, char *newpath); |
|
322 int dav_move(DavResource *res, char *newpath); |
|
323 int dav_copy_o(DavResource *res, char *newpath, DavBool override); |
|
324 int dav_move_o(DavResource *res, char *newpath, DavBool override); |
|
325 int dav_copyto(DavResource *res, char *url, DavBool override); |
|
326 int dav_moveto(DavResource *res, char *url, DavBool override); |
|
327 |
|
328 int dav_lock(DavResource *res); |
|
329 int dav_lock_t(DavResource *res, time_t timeout); |
|
330 int dav_unlock(DavResource *res); |
|
331 |
|
332 DavXmlNode* dav_get_property(DavResource *res, char *name); |
|
333 DavXmlNode* dav_get_property_ns(DavResource *res, const char *ns, const char *name); |
|
334 DavXmlNode* dav_get_encrypted_property_ns(DavResource *res, const char *ns, const char *name); |
|
335 char* dav_get_string_property(DavResource *res, char *name); |
|
336 char* dav_get_string_property_ns(DavResource *res, char *ns, char *name); |
|
337 void dav_set_string_property(DavResource *res, char *name, char *value); |
|
338 void dav_set_string_property_ns(DavResource *res, char *ns, char *name, char *value); |
|
339 void dav_set_property(DavResource *res, char *name, DavXmlNode *value); |
|
340 void dav_set_property_ns(DavResource *res, char *ns, char *name, DavXmlNode *value); |
|
341 void dav_remove_property(DavResource *res, char *name); |
|
342 void dav_remove_property_ns(DavResource *res, char *ns, char *name); |
|
343 void dav_set_encrypted_property_ns(DavResource *res, char *ns, char *name, DavXmlNode *value); |
|
344 void dav_set_encrypted_string_property_ns(DavResource *res, char *ns, char *name, char *value); |
|
345 void dav_remove_encrypted_property_ns(DavResource *res, char *ns, char *name); |
|
346 |
|
347 DavPropName* dav_get_property_names(DavResource *res, size_t *count); |
|
348 |
|
349 void dav_set_content(DavResource *res, void *stream, dav_read_func read_func, dav_seek_func seek_func); |
|
350 void dav_set_content_data(DavResource *res, char *content, size_t length); |
|
351 void dav_set_content_length(DavResource *res, size_t length); |
|
352 |
|
353 int dav_load(DavResource *res); |
|
354 int dav_load_prop(DavResource *res, DavPropName *properties, size_t numprop); |
|
355 int dav_store(DavResource *res); |
|
356 int dav_get_content(DavResource *res, void *stream, dav_write_func write_func); |
|
357 |
|
358 DavInputStream* dav_inputstream_open(DavResource *res); |
|
359 size_t dav_read(void *buf, size_t size, size_t nitems, DavInputStream *in); |
|
360 void dav_inputstream_close(DavInputStream *in); |
|
361 |
|
362 DavOutputStream* dav_outputstream_open(DavResource *res); |
|
363 size_t dav_write(const void *buf, size_t size, size_t nitems, DavOutputStream *out); |
|
364 int dav_outputstream_close(DavOutputStream *out); |
|
365 |
|
366 void dav_verbose_log( |
|
367 DavSession *sn, |
|
368 const char *method, |
|
369 const char *url, |
|
370 const char *request_body, |
|
371 size_t request_bodylen, |
|
372 int status, |
|
373 const char *response_body, |
|
374 size_t response_bodylen); |
|
375 |
|
376 // private |
|
377 int dav_propfind(DavSession *sn, DavResource *root, CxBuffer *rqbuf); |
|
378 |
|
379 |
|
380 /* --------------------------- DeltaV ---------------------------- */ |
|
381 |
|
382 int dav_versioncontrol(DavResource *res); |
|
383 int dav_checkout(DavResource *res); |
|
384 int dav_checkin(DavResource *res); |
|
385 int dav_uncheckout(DavResource *res); |
|
386 DavResource* dav_versiontree(DavResource *res, char *properties); |
|
387 |
|
388 /* ------------------------ xml functions ------------------------ */ |
|
389 char* dav_xml_getstring(DavXmlNode *node); |
|
390 DavBool dav_xml_isstring(DavXmlNode *node); |
|
391 DavXmlNode* dav_xml_nextelm(DavXmlNode *node); |
|
392 DavXmlNode* dav_text_node(DavSession *sn, const char *text); |
|
393 DavXmlNode* dav_text_element(DavSession *sn, const char *ns, const char *name, const char *text); |
|
394 |
|
395 DavXmlNode* dav_copy_node(DavXmlNode *node); |
|
396 |
|
397 void dav_free_xml_node_sn(DavSession *sn, DavXmlNode *node); |
|
398 void dav_free_xml_node(DavXmlNode *node); |
|
399 |
|
400 DavXmlNode* dav_xml_createnode(const char *ns, const char *name); |
|
401 DavXmlNode* dav_xml_createnode_with_text(const char *ns, const char *name, const char *text); |
|
402 DavXmlNode* dav_xml_createtextnode(const char *text); |
|
403 void dav_xml_add_child(DavXmlNode *node, DavXmlNode *child); |
|
404 void dav_xml_add_attr(DavXmlNode *node, const char *name, const char *value); |
|
405 char* dav_xml_get_attr(DavXmlNode *node, const char *name); |
|
406 |
|
407 DavXmlNode* dav_parse_xml(DavSession *sn, const char *str, size_t len); |
|
408 |
|
409 #ifdef __cplusplus |
|
410 } |
|
411 #endif |
|
412 |
|
413 #endif /* WEBDAV_H */ |
|
414 |