Thu, 01 Feb 2024 10:41:39 +0100
make DavContext mt-safe
/* * 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 <inttypes.h> #include <stdbool.h> #include <cx/map.h> #include <cx/mempool.h> #include <cx/linked_list.h> #include <cx/string.h> #include <cx/buffer.h> #include <curl/curl.h> #include <libxml/tree.h> #ifndef _WIN32 #include <pthread.h> #else #include <Windows.h> #endif #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; #ifndef _WIN32 #define DAV_MUTEX pthread_mutex_t #else #define DAV_MUTEX HANDLE #endif 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; DAV_MUTEX mutex; DavBool mtsafe; }; 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_set_mtsafe(DavContext *ctx, DavBool enable); void dav_context_lock(DavContext *ctx); void dav_context_unlock(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); int dav_context_add_session(DavContext *context, DavSession *sn); int dav_context_remove_session(DavContext *context, DavSession *sn); 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, const char *user, const char *password); void dav_session_set_auth_s(DavSession *sn, cxstring user, cxstring 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 */