diff -r 21274e5950af -r a1f4cb076d2f src/server/public/webdav.h --- a/src/server/public/webdav.h Tue Aug 13 22:14:32 2019 +0200 +++ b/src/server/public/webdav.h Sat Sep 24 16:26:10 2022 +0200 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2020 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: @@ -30,6 +30,7 @@ #define WS_WEBDAV_H #include "nsapi.h" +#include "vfs.h" #include #include @@ -39,7 +40,463 @@ extern "C" { #endif +typedef struct WebdavBackend WebdavBackend; + +typedef struct WebdavProperty WebdavProperty; +typedef struct WebdavPList WebdavPList; +typedef struct WebdavNSList WebdavNSList; +typedef struct WebdavPListIterator WebdavPListIterator; + +typedef enum WebdavLockScope WebdavLockScope; +typedef enum WebdavLockType WebdavLockType; + +typedef enum WebdavValueType WebdavValueType; + +typedef struct WebdavPropfindRequest WebdavPropfindRequest; +typedef struct WebdavProppatchRequest WebdavProppatchRequest; +typedef struct WebdavLockRequest WebdavLockRequest; + +typedef struct WebdavVFSRequest WebdavVFSRequest; + +typedef struct WebdavResponse WebdavResponse; +typedef struct WebdavResource WebdavResource; + +typedef struct WebdavVFSProperties WebdavVFSProperties; + +typedef struct WebdavOperation WebdavOperation; + +typedef struct WSXmlData WSXmlData; +typedef struct WSText WSText; + +typedef struct _xmlNs WSNamespace; +typedef struct _xmlNode WSXmlNode; + +#define WS_NODE_ELEMENT 1 +#define WS_NODE_TEXT 3 +#define WS_NODE_CDATA 4 +#define WS_NODE_ENTITY_REF 5 + +typedef int(*wsxml_func)(WSXmlNode *, void *); + +/* propfind settings */ + +/* + * Use the vfs to stat files or read the directory children + */ +#define WS_WEBDAV_PROPFIND_USE_VFS 0x01 + +/* + * Use the vfs to open a file for proppatch + */ +#define WS_WEBDAV_PROPPATCH_USE_VFS 0x02 + + +typedef void*(*webdav_init_func)(ServerConfiguration *cfg, pool_handle_t *pool, WSConfigNode *config); +typedef WebdavBackend*(*webdav_create_func)(Session *sn, Request *rq, pblock *pb, void *initData); + +enum WebdavValueType { + WS_VALUE_NO_TYPE = 0, + WS_VALUE_XML_NODE, + WS_VALUE_XML_DATA, + WS_VALUE_TEXT +}; + +struct WSText { + char *str; + size_t length; +}; + +struct WSXmlData { + WebdavNSList *namespaces; + char *data; + size_t length; +}; + +struct WebdavProperty { + WSNamespace *namespace; + + const char *name; + + char *lang; + + union { + WSXmlNode *node; + WSXmlData data; + WSText text; + } value; + WebdavValueType vtype; +}; + +struct WebdavPList { + WebdavProperty *property; + WebdavPList *prev; + WebdavPList *next; +}; + +struct WebdavNSList { + WSNamespace *namespace; + WebdavNSList *prev; + WebdavNSList *next; +}; + +struct WebdavPListIterator { + WebdavPList **list; + WebdavPList *cur; + WebdavPList *next; + size_t index; +}; + +enum WebdavLockScope { + WEBDAV_LOCK_EXCLUSIVE = 0, + WEBDAV_LOCK_SHARED, + WEBDAV_LOCK_SCOPE_UNKNOWN +}; + +enum WebdavLockType { + WEBDAV_LOCK_WRITE = 0, + WEBDAV_LOCK_TYPE_UNKNOWN +}; + +struct WebdavPropfindRequest { + Session *sn; + Request *rq; + + WebdavBackend *dav; + + void *doc; + + /* + * list of requested properties + */ + WebdavPList *properties; + + /* + * number of properties + */ + size_t propcount; + + WSBool allprop; + WSBool propname; + WSBool deadproperties; + + int depth; + + /* + * custom userdata for the backend + */ + void *userdata; +}; + +struct WebdavProppatchRequest { + Session *sn; + Request *rq; + + WebdavBackend *dav; + + void *doc; + + WebdavPList *set; + size_t setcount; + + WebdavPList *remove; + size_t removecount; + + /* + * custom userdata for the backend + */ + void *userdata; +}; + +struct WebdavVFSRequest { + Session *sn; + Request *rq; + + char *path; + + /* + * custom userdata for the backend + */ + void *userdata; +}; + +struct WebdavLockRequest { + Session *sn; + Request *rq; + + void *doc; + + WebdavLockScope scope; + WebdavLockType type; + + WSXmlNode *owner; +}; + +struct WebdavVFSProperties { + uint32_t getcontentlength:1; + uint32_t getlastmodified:1; + uint32_t getresourcetype:1; + uint32_t getetag:1; + uint32_t creationdate:1; +}; + +struct WebdavResponse { + WebdavOperation *op; + + WebdavResource* (*addresource)(WebdavResponse*, const char*); +}; + +struct WebdavResource { + char *href; + + WSBool isclosed; + + int err; + + /* + * int addprop(WebdavResource *res, WebdavProperty *property, int status); + * + * Adds a property to the resource + */ + int (*addproperty)(WebdavResource*, WebdavProperty*, int); + + /* + * int close(WebdavResource *res); + * + * Closes a resource object + */ + int (*close)(WebdavResource*); +}; + +struct WebdavBackend { + /* + * int propfind_init( + * WebdavPropfindRequest *rq, + * const char *path, + * const char *href, + * WebdavPList **outplist); + * + * Initializes a propfind request. This is called once for each propfind + * request and should initialize everything needed for generating the + * multistatus response. + * + */ + int (*propfind_init)(WebdavPropfindRequest *, const char *, const char *, WebdavPList **); + + /* + * int propfind_do( + * WebdavPropfindRequest *rq, + * WebdavResponse *response, + * VFS_DIR parent, + * WebdavResource *resource, + * struct stat *s); + * + * This function is called for the requsted resource and for all children + * if WS_PROPFIND_NO_VFS_CHILDREN is not set. + */ + int (*propfind_do)( + WebdavPropfindRequest *, + WebdavResponse *, + VFS_DIR, + WebdavResource *, + struct stat *); + + /* + * int propfind_finish(WebdavPropfindRequest *rq); + * + * Finishes a propfind request. + */ + int (*propfind_finish)(WebdavPropfindRequest *); + + /* + * int proppatch_do( + * WebdavProppatchRequest *request, + * WebdavResource *response, + * VFSFile *file, + * WebdavPList **out_set, + * WebdavPList **out_remove); + * + * Modifies properties of the requsted resource. + */ + int (*proppatch_do)( + WebdavProppatchRequest *, + WebdavResource *, + VFSFile *, + WebdavPList **, + WebdavPList **); + + /* + * int proppatch_finish( + * WebdavProppatchRequest *request, + * WebdavResource *response, + * VFSFile *file, + * WSBool commit); + * + * Called after all proppatch_do functions of all backends are executed + * and should either permanently store the properties (commit == true) or + * revert all changed (commit == false). + */ + int (*proppatch_finish)( + WebdavProppatchRequest *, + WebdavResource *, + VFSFile *, + WSBool); + + /* + * int opt_mkcol(WebdavVFSRequest *request, WSBool *out_created); + * + * Optional mkcol callback that is called before vfs_mkdir. If the function + * sets out_created to TRUE, vfs_mkdir will not be executed. + */ + int (*opt_mkcol)(WebdavVFSRequest *, WSBool *); + + /* + * int opt_mkcol_finish(WebdavVFSRequest *request, WSBool success); + * + * Optional callback for finishing a MKCOL request. + */ + int(*opt_mkcol_finish)(WebdavVFSRequest *, WSBool); + + /* + * int opt_delete(WebdavVFSRequest *request, WSBool *out_deleted); + * + * Optional delete callback that is called once before any VFS deletions. + * When the callback sets out_deleted to TRUE, no VFS unlink operations + * will be done. + * + */ + int (*opt_delete)(WebdavVFSRequest *, WSBool *); + + /* + * int opt_delete_finish(WebdavVFSRequest *request, WSBool success); + * + * Optional callback for finishing a DELETE request. + */ + int (*opt_delete_finish)(WebdavVFSRequest *, WSBool); + + /* + * See the WS_WEBDAV_* macros for informations about the settings + */ + uint32_t settings; + + /* + * private instance data + */ + void *instance; + + /* + * next Backend + */ + WebdavBackend *next; +}; + +/* + * register a webdav backend + */ +int webdav_register_backend(const char *name, webdav_init_func webdavInit, webdav_create_func webdavCreate); + +WebdavBackend* webdav_create(Session *sn, Request *rq, const char *dav_class, pblock *pb, void *initData); + +/* + * gets the requested depth + * + * in case of infinity, -1 is returned + * if no depth is specified, 0 is returned + */ +int webdav_getdepth(Request *rq); + +int webdav_plist_add( + pool_handle_t *pool, + WebdavPList **begin, + WebdavPList **end, + WebdavProperty *prop); + +WebdavPList* webdav_plist_clone(pool_handle_t *pool, WebdavPList *list); +WebdavPList* webdav_plist_clone_s( + pool_handle_t *pool, + WebdavPList *list, + size_t *newlen); + +size_t webdav_plist_size(WebdavPList *list); + +int webdav_nslist_add( + pool_handle_t *pool, + WebdavNSList **begin, + WebdavNSList **end, + WSNamespace *ns); + +WebdavPListIterator webdav_plist_iterator(WebdavPList **list); +int webdav_plist_iterator_next(WebdavPListIterator *i, WebdavPList **cur); +void webdav_plist_iterator_remove_current(WebdavPListIterator *i); + +WSNamespace* webdav_dav_namespace(void); +WebdavProperty* webdav_resourcetype_collection(void); +WebdavProperty* webdav_resourcetype_empty(void); +WebdavProperty* webdav_dav_property( + pool_handle_t *pool, + const char *name); + +int webdav_resource_add_dav_stringproperty( + WebdavResource *res, + pool_handle_t pool, + const char *name, + const char *str, + size_t len); +int webdav_resource_add_stringproperty( + WebdavResource *res, + pool_handle_t pool, + const char *xmlns_prefix, + const char *xmlns_href, + const char *name, + const char *str, + size_t len); + +int webdav_property_set_value( + WebdavProperty *property, + pool_handle_t *pool, + char *value); + +WebdavVFSProperties webdav_vfs_properties( + WebdavPList **plistInOut, + WSBool removefromlist, + WSBool appprop, + uint32_t flags); + +int webdav_add_vfs_properties( + WebdavResource *res, + pool_handle_t *pool, + WebdavVFSProperties properties, + struct stat *s); + +int wsxml_iterator( + pool_handle_t *pool, + WSXmlNode *node, + wsxml_func begincb, + wsxml_func endcb, + void *udata); + +WebdavNSList* wsxml_get_required_namespaces( + pool_handle_t *pool, + WSXmlNode *node, + int *error); + +WSXmlData* wsxml_node2data( + pool_handle_t *pool, + WSXmlNode *node); + +/* + * converts a property list to a string + * + * namespaces are separated by a newline character and have the format: + * : + */ +char* wsxml_nslist2string(pool_handle_t *pool, WebdavNSList *nslist); + +/* + * converts a namespace list string (created by wsxml_nslist2string) to + * a WebdavNSList object + */ +WebdavNSList* wsxml_string2nslist(pool_handle_t *pool, char *nsliststr); #ifdef __cplusplus }