diff -r 2483f517c562 -r b5bb7b3cd597 libidav/webdav.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libidav/webdav.h Mon Jan 22 17:27:47 2024 +0100 @@ -0,0 +1,414 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2018 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WEBDAV_H +#define WEBDAV_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef char DavBool; +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +typedef struct DavContext DavContext; +typedef struct DavProxy DavProxy; +typedef struct DavSession DavSession; +typedef struct DavResource DavResource; +typedef struct DavResult DavResult; +typedef struct DavNamespace DavNamespace; +typedef struct DavProperty DavProperty; +typedef struct DavPropName DavPropName; +typedef struct DavKey DavKey; +typedef struct DavNSInfo DavNSInfo; +typedef struct DavXmlNode DavXmlNode; +typedef struct DavXmlAttr DavXmlAttr; + +typedef struct DavInputStream DavInputStream; +typedef struct DavOutputStream DavOutputStream; + +typedef size_t(*dav_read_func)(void*, size_t, size_t, void*); +typedef size_t(*dav_write_func)(const void*, size_t, size_t, void*); +typedef int(*dav_seek_func)(const void *, long, int); + +typedef int(*dav_auth_func)(DavSession *, void *); +typedef void(*dav_progress_func)(DavResource *, int64_t, int64_t, void *); + + +typedef void(*dav_rqlog_func)( + DavSession *sn, + const char *method, + const char *url, + const char *request_body, + size_t request_bodylen, + int status, + const char *response_body, + size_t response_bodylen); + +enum DavError { + DAV_OK = 0, + DAV_ERROR, + DAV_NOT_FOUND, + DAV_UNAUTHORIZED, + DAV_FORBIDDEN, + DAV_METHOD_NOT_ALLOWED, + DAV_CONFLICT, + DAV_LOCKED, + DAV_UNSUPPORTED_PROTOCOL, + DAV_COULDNT_RESOLVE_PROXY, + DAV_COULDNT_RESOLVE_HOST, + DAV_COULDNT_CONNECT, + DAV_TIMEOUT, + DAV_SSL_ERROR, + DAV_QL_ERROR, + DAV_CONTENT_VERIFICATION_ERROR, + DAV_PRECONDITION_FAILED, + DAV_REQUEST_ENTITY_TOO_LARGE, + DAV_REQUEST_URL_TOO_LONG, + DAV_PROXY_AUTH_REQUIRED, + DAV_NET_AUTH_REQUIRED +}; + +typedef enum DavError DavError; + +enum DavXmlNodeType { + DAV_XML_NONE = 0, + DAV_XML_ELEMENT, + DAV_XML_TEXT +}; + +typedef enum DavXmlNodeType DavXmlNodeType; + +#define DAV_SESSION_ENCRYPT_CONTENT 0x0001 +#define DAV_SESSION_ENCRYPT_NAME 0x0002 +#define DAV_SESSION_ENCRYPT_PROPERTIES 0x0004 +#define DAV_SESSION_DECRYPT_CONTENT 0x0008 +#define DAV_SESSION_DECRYPT_NAME 0x0010 +#define DAV_SESSION_DECRYPT_PROPERTIES 0x0020 +#define DAV_SESSION_STORE_HASH 0x0040 + +#define DAV_SESSION_CONTENT_ENCRYPTION 0x0009 +#define DAV_SESSION_FULL_ENCRYPTION 0x003f + + +#define DAV_NS "http://davutils.org/" +#define DAV_PROPS_NS "http://davutils.org/props/" + +struct DavNamespace { + char *prefix; + char *name; +}; + +struct DavResource { + DavSession *session; + DavResource *prev; + DavResource *next; + DavResource *parent; + DavResource *children; + char *name; + char *path; + char *href; + uint64_t contentlength; + char *contenttype; + time_t creationdate; + time_t lastmodified; + void *data; + int iscollection; + int exists; +}; + +struct DavSession { + DavContext *context; + CURL *handle; + char *base_url; + CxMempool *mp; + CxMap *pathcache; + DavKey *key; + void *locks; + uint32_t flags; + DavError error; + char *errorstr; + + int(*auth_prompt)(DavSession *sn, void *userdata); + void *authprompt_userdata; + + dav_rqlog_func logfunc; + + void(*get_progress)(DavResource *res, int64_t total, int64_t now, void *userdata); + void(*put_progress)(DavResource *res, int64_t total, int64_t now, void *userdata); + void *progress_userdata; +}; + +struct DavContext { + CxMap *namespaces; + CxMap *namespaceinfo; + CxMap *keys; + CxList *sessions; + DavProxy *http_proxy; + DavProxy *https_proxy; +}; + +struct DavProxy { + char *url; + char *username; + char *password; + char *no_proxy; +}; + +struct DavProperty { + DavNamespace *ns; + char *name; + DavXmlNode *value; +}; + +struct DavPropName { + char *ns; + char *name; +}; + +struct DavResult { + DavResource *result; + int status; +}; + +#define DAV_KEY_AES128 0 +#define DAV_KEY_AES256 1 + +struct DavKey { + char *name; + int type; + void *data; + size_t length; +}; + +struct DavNSInfo { + char *prefix; + DavBool encrypt; +}; + +struct DavXmlNode { + DavXmlNodeType type; + + char *namespace; + char *name; + + DavXmlNode *prev; + DavXmlNode *next; + DavXmlNode *children; + DavXmlNode *parent; + + DavXmlAttr *attributes; + + char *content; + size_t contentlength; +}; + +struct DavXmlAttr { + char *name; + char *value; + DavXmlAttr *next; +}; + +DavContext* dav_context_new(void); +void dav_context_destroy(DavContext *ctx); + +void dav_context_add_key(DavContext *context, DavKey *key); +DavKey* dav_context_get_key(DavContext *context, const char *name); + +int dav_add_namespace(DavContext *context, const char *prefix, const char *ns); +DavNamespace* dav_get_namespace(DavContext *context, const char *prefix); +DavNamespace* dav_get_namespace_s(DavContext *context, cxstring prefix); + +int dav_enable_namespace_encryption(DavContext *context, const char *ns, DavBool encrypt); +int dav_namespace_is_encrypted(DavContext *context, const char *ns); + +DavSession* dav_session_new(DavContext *context, char *base_url); +DavSession* dav_session_new_auth( + DavContext *context, + char *base_url, + char *user, + char *password); +void dav_session_set_auth(DavSession *sn, char *user, char *password); +void dav_session_set_baseurl(DavSession *sn, char *base_url); +void dav_session_enable_encryption(DavSession *sn, DavKey *key, int flags); + +void dav_session_set_authcallback(DavSession *sn, dav_auth_func func, void *userdata); +void dav_session_set_progresscallback(DavSession *sn, dav_progress_func get, dav_progress_func put, void *userdata); + +void dav_session_destroy(DavSession *sn); + +void dav_session_destructor(DavSession *sn); + +void* dav_session_malloc(DavSession *sn, size_t size); +void* dav_session_calloc(DavSession *sn, size_t nelm, size_t size); +void* dav_session_realloc(DavSession *sn, void *ptr, size_t size); +void dav_session_free(DavSession *sn, void *ptr); +char* dav_session_strdup(DavSession *sn, const char *str); + +void dav_set_effective_href(DavSession *sn, DavResource *resource); +DavResource* dav_get(DavSession *sn, char *path, const char *properties); + +CxList* parse_properties_string(DavContext *context, cxstring str); + +DavResource* dav_query(DavSession *sn, char *query, ...); + +cxmutstr dav_property_key(const char *ns, const char *name); +void dav_get_property_namespace_str( + DavContext *ctx, + char *prefixed_name, + char **ns, + char **name); +DavNamespace* dav_get_property_namespace( + DavContext *ctx, + char *prefixed_name, + char **name); + +/* ------------------------ resource functions ------------------------ */ + +DavResource* dav_resource_new(DavSession *sn, const char *path); +DavResource* dav_resource_new_child(DavSession *sn, DavResource *parent, const char *name); +DavResource* dav_resource_new_href(DavSession *sn, const char *href); + +void dav_resource_free(DavResource *res); +void dav_resource_free_all(DavResource *res); + +char* dav_resource_get_href(DavResource *resource); + +DavResource* dav_create_child(DavResource *parent, char *name); +int dav_delete(DavResource *res); +int dav_create(DavResource *res); +int dav_exists(DavResource *res); + +int dav_copy(DavResource *res, char *newpath); +int dav_move(DavResource *res, char *newpath); +int dav_copy_o(DavResource *res, char *newpath, DavBool override); +int dav_move_o(DavResource *res, char *newpath, DavBool override); +int dav_copyto(DavResource *res, char *url, DavBool override); +int dav_moveto(DavResource *res, char *url, DavBool override); + +int dav_lock(DavResource *res); +int dav_lock_t(DavResource *res, time_t timeout); +int dav_unlock(DavResource *res); + +DavXmlNode* dav_get_property(DavResource *res, char *name); +DavXmlNode* dav_get_property_ns(DavResource *res, const char *ns, const char *name); +DavXmlNode* dav_get_encrypted_property_ns(DavResource *res, const char *ns, const char *name); +char* dav_get_string_property(DavResource *res, char *name); +char* dav_get_string_property_ns(DavResource *res, char *ns, char *name); +void dav_set_string_property(DavResource *res, char *name, char *value); +void dav_set_string_property_ns(DavResource *res, char *ns, char *name, char *value); +void dav_set_property(DavResource *res, char *name, DavXmlNode *value); +void dav_set_property_ns(DavResource *res, char *ns, char *name, DavXmlNode *value); +void dav_remove_property(DavResource *res, char *name); +void dav_remove_property_ns(DavResource *res, char *ns, char *name); +void dav_set_encrypted_property_ns(DavResource *res, char *ns, char *name, DavXmlNode *value); +void dav_set_encrypted_string_property_ns(DavResource *res, char *ns, char *name, char *value); +void dav_remove_encrypted_property_ns(DavResource *res, char *ns, char *name); + +DavPropName* dav_get_property_names(DavResource *res, size_t *count); + +void dav_set_content(DavResource *res, void *stream, dav_read_func read_func, dav_seek_func seek_func); +void dav_set_content_data(DavResource *res, char *content, size_t length); +void dav_set_content_length(DavResource *res, size_t length); + +int dav_load(DavResource *res); +int dav_load_prop(DavResource *res, DavPropName *properties, size_t numprop); +int dav_store(DavResource *res); +int dav_get_content(DavResource *res, void *stream, dav_write_func write_func); + +DavInputStream* dav_inputstream_open(DavResource *res); +size_t dav_read(void *buf, size_t size, size_t nitems, DavInputStream *in); +void dav_inputstream_close(DavInputStream *in); + +DavOutputStream* dav_outputstream_open(DavResource *res); +size_t dav_write(const void *buf, size_t size, size_t nitems, DavOutputStream *out); +int dav_outputstream_close(DavOutputStream *out); + +void dav_verbose_log( + DavSession *sn, + const char *method, + const char *url, + const char *request_body, + size_t request_bodylen, + int status, + const char *response_body, + size_t response_bodylen); + +// private +int dav_propfind(DavSession *sn, DavResource *root, CxBuffer *rqbuf); + + +/* --------------------------- DeltaV ---------------------------- */ + +int dav_versioncontrol(DavResource *res); +int dav_checkout(DavResource *res); +int dav_checkin(DavResource *res); +int dav_uncheckout(DavResource *res); +DavResource* dav_versiontree(DavResource *res, char *properties); + +/* ------------------------ xml functions ------------------------ */ +char* dav_xml_getstring(DavXmlNode *node); +DavBool dav_xml_isstring(DavXmlNode *node); +DavXmlNode* dav_xml_nextelm(DavXmlNode *node); +DavXmlNode* dav_text_node(DavSession *sn, const char *text); +DavXmlNode* dav_text_element(DavSession *sn, const char *ns, const char *name, const char *text); + +DavXmlNode* dav_copy_node(DavXmlNode *node); + +void dav_free_xml_node_sn(DavSession *sn, DavXmlNode *node); +void dav_free_xml_node(DavXmlNode *node); + +DavXmlNode* dav_xml_createnode(const char *ns, const char *name); +DavXmlNode* dav_xml_createnode_with_text(const char *ns, const char *name, const char *text); +DavXmlNode* dav_xml_createtextnode(const char *text); +void dav_xml_add_child(DavXmlNode *node, DavXmlNode *child); +void dav_xml_add_attr(DavXmlNode *node, const char *name, const char *value); +char* dav_xml_get_attr(DavXmlNode *node, const char *name); + +DavXmlNode* dav_parse_xml(DavSession *sn, const char *str, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif /* WEBDAV_H */ +