Sat, 25 Jan 2020 09:00:27 +0100
fix multistatus response and add propfind tests
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * 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: * * 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 WS_WEBDAV_H #define WS_WEBDAV_H #include "nsapi.h" #include "vfs.h" #include <sys/file.h> #include <sys/stat.h> #include <inttypes.h> #ifdef __cplusplus 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 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 */ /* * Don't use the vfs to stat files or read the directory children */ #define WS_PROPFIND_NO_VFS 0x01 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 WebdavProperty { WSNamespace *namespace; const char *name; char *lang; union { WSXmlNode *node; WSXmlData *data; WSText text; } value; WebdavValueType vtype; }; struct WSXmlData { WebdavNSList *namespaces; char *data; size_t length; }; 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; void *doc; /* * list of requested properties */ WebdavPList *properties; /* * number of properties */ size_t propcount; WSBool allprop; WSBool propname; int depth; /* * custom userdata for the backend */ void *userdata; }; struct WebdavProppatchRequest { Session *sn; Request *rq; void *doc; WebdavPList *set; size_t setcount; WebdavPList *remove; size_t removecount; }; 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 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, * 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 *, 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 *); /* * See the WS_PROPFIND_ macros for informations about the settings */ uint32_t settings; /* * next Backend */ WebdavBackend *next; }; /* * 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); 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_dav_property( pool_handle_t *pool, const char *name); int webdav_property_set_value( WebdavProperty *property, pool_handle_t *pool, char *value); WebdavVFSProperties webdav_vfs_properties( WebdavPList **plistInOut, WSBool removefromlist, 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); #ifdef __cplusplus } #endif #endif /* WS_WEBDAV_H */