src/server/public/webdav.h

changeset 385
a1f4cb076d2f
parent 378
0344108db255
child 479
2a42ba73ecdd
--- 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 <sys/file.h>
 #include <sys/stat.h>
@@ -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:
+ * <prefix>:<href>
+ */
+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
 }

mercurial