add new dav config element webdav

Sun, 07 Aug 2022 13:46:43 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 07 Aug 2022 13:46:43 +0200
branch
webdav
changeset 366
47bc686fafe4
parent 361
570026d3a685
child 367
1592224f6059

add new dav config element

doc/development/postgresql_vfs.sql file | annotate | diff | comparison | revisions
src/server/config/serverconfig.c file | annotate | diff | comparison | revisions
src/server/daemon/config.c file | annotate | diff | comparison | revisions
src/server/daemon/config.h file | annotate | diff | comparison | revisions
src/server/daemon/resourcepool.c file | annotate | diff | comparison | revisions
src/server/daemon/vfs.c file | annotate | diff | comparison | revisions
src/server/daemon/vfs.h file | annotate | diff | comparison | revisions
src/server/plugins/postgresql/Makefile file | annotate | diff | comparison | revisions
src/server/plugins/postgresql/config.c file | annotate | diff | comparison | revisions
src/server/plugins/postgresql/config.h file | annotate | diff | comparison | revisions
src/server/plugins/postgresql/init.c file | annotate | diff | comparison | revisions
src/server/plugins/postgresql/vfs.c file | annotate | diff | comparison | revisions
src/server/plugins/postgresql/vfs.h file | annotate | diff | comparison | revisions
src/server/plugins/postgresql/webdav.c file | annotate | diff | comparison | revisions
src/server/plugins/postgresql/webdav.h file | annotate | diff | comparison | revisions
src/server/public/nsapi.h file | annotate | diff | comparison | revisions
src/server/public/vfs.h file | annotate | diff | comparison | revisions
src/server/public/webdav.h file | annotate | diff | comparison | revisions
src/server/safs/nametrans.c file | annotate | diff | comparison | revisions
src/server/webdav/webdav.c file | annotate | diff | comparison | revisions
src/server/webdav/webdav.h file | annotate | diff | comparison | revisions
--- a/doc/development/postgresql_vfs.sql	Sun May 15 08:56:00 2022 +0200
+++ b/doc/development/postgresql_vfs.sql	Sun Aug 07 13:46:43 2022 +0200
@@ -1,4 +1,3 @@
-
 create table Resource (
     resource_id       serial    primary key,
     parent_id         int       references Resource(resource_id),
--- a/src/server/config/serverconfig.c	Sun May 15 08:56:00 2022 +0200
+++ b/src/server/config/serverconfig.c	Sun Aug 07 13:46:43 2022 +0200
@@ -293,7 +293,7 @@
 ConfigNode* serverconfig_get_node(ConfigNode *parent, ConfigNodeType type, scstr_t name) {
     UCX_FOREACH(elm, parent->children) {
         ConfigNode *node = elm->data;
-        if(node->type == type && !sstrcmp(node->name, name)) {
+        if(node->type == type && !sstrcasecmp(node->name, name)) {
             return node;
         }
     }
@@ -305,7 +305,7 @@
     
     UCX_FOREACH(elm, parent->children) {
         ConfigNode *node = elm->data;
-        if(node->type == type && !sstrcmp(node->name, name)) {
+        if(node->type == type && !sstrcasecmp(node->name, name)) {
             nodes = ucx_list_append(nodes, node);
         }
     }
--- a/src/server/daemon/config.c	Sun May 15 08:56:00 2022 +0200
+++ b/src/server/daemon/config.c	Sun Aug 07 13:46:43 2022 +0200
@@ -276,6 +276,14 @@
             return NULL;
         }
     }
+    
+    list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, SC("Dav"));
+    UCX_FOREACH(elm, list) {
+        ConfigNode *scfgobj = elm->data;
+        if(cfg_handle_dav(serverconfig, scfgobj)) {
+            return NULL;
+        }
+    }
 
     // set VirtualServer for all listeners
     UcxList *ls = serverconfig->listeners;
@@ -668,6 +676,97 @@
     return 0;
 }
 
+int cfg_handle_dav(ServerConfiguration *cfg, ConfigNode *obj) {
+    UcxList *backends = NULL; // list of ConfigArg*
+    UcxAllocator a = util_pool_allocator(cfg->pool);
+    int init_error;
+    
+    // get a list of all DavBackends
+    UCX_FOREACH(elm, obj->children) {
+        ConfigNode *node = elm->data;
+        if(!sstrcasecmp(node->name, SC("DavBackend"))) {
+            if(node->type == CONFIG_NODE_DIRECTIVE) {
+                if(ucx_list_size(node->args) == 1) {
+                    ConfigArg *arg = node->args->data;
+                    backends = ucx_list_append(backends, arg);
+                } else {
+                    log_ereport(LOG_MISCONFIG, "DavBackend must have only one value");
+                    ucx_list_free(backends);
+                    return 1;
+                }
+            } else {
+                log_ereport(LOG_MISCONFIG, "DavBackend must be a directive");
+                ucx_list_free(backends);
+                return 1;
+            }
+        }
+    }
+    
+    int ret = 0;
+    WebdavRepository *repository = pool_malloc(cfg->pool, sizeof(WebdavRepository));
+    repository->vfs = NULL;
+    repository->vfsInitData = NULL;
+    repository->davBackends = NULL;
+    
+    // initialize backends
+    UCX_FOREACH(elm, backends) {
+        // the DavBackend value should contain the dav class name
+        ConfigArg *backendArg = elm->data;
+        
+        WebdavType *dav = webdav_get_type((scstr_t){backendArg->value.ptr, backendArg->value.length});
+        if(!dav) {
+            log_ereport(LOG_MISCONFIG, "Unknown webdav backend type '%s'", backendArg->value.ptr);
+            ret = 1;
+            break;
+        }
+        
+        // call backend init
+        // init_data can be NULL, errors will be indicated by init_error
+        void *init_data = webdav_init_backend(cfg, cfg->pool, dav, obj, &init_error);
+        if(init_error) {
+            log_ereport(LOG_FAILURE, "Failed to initialize webdav backend %s", backendArg->value.ptr);
+            ret = 1;
+            break;
+        }
+        
+        WebdavBackendInitData *davInit = pool_malloc(cfg->pool, sizeof(WebdavBackendInitData));
+        if(!davInit) {
+            log_ereport(LOG_FAILURE, "Failed to initialize webdav backend %s: OOM", backendArg->value.ptr);
+            ret = 1;
+            break;
+        }
+        davInit->davType = dav;
+        davInit->davInitData = init_data;
+        
+        repository->davBackends = ucx_list_append_a(&a, repository->davBackends, davInit);
+    }
+    
+    // initialize vfs
+    scstr_t vfs_class = serverconfig_directive_value(obj, SC("VFS"));
+    if(vfs_class.length > 0) {
+        VfsType *vfs = vfs_get_type((scstr_t){vfs_class.ptr, vfs_class.length});
+        if(vfs) {
+            repository->vfs = vfs;
+            repository->vfsInitData = vfs_init_backend(cfg, cfg->pool, vfs, obj, &init_error);
+            ret = init_error;
+        } else {
+            log_ereport(LOG_FAILURE, "Unknown vfs type '%s'", vfs_class.ptr);
+            ret = 1;
+        }
+    }
+    
+    scstr_t object = serverconfig_directive_value(obj, SC("Object"));
+    if(object.length > 0) {
+        repository->object = sstrdup_a(&a, object);
+        if(repository->object.length != object.length) {
+            // OOM
+            log_ereport(LOG_FAILURE, "Cannot create webdav repository: OOM");
+            ret = 1;
+        }
+    }
+    
+    return ret;    
+}
 
 static int convert_objconf(ServerConfiguration *scfg, ObjectConfig *cfg, HTTPObjectConfig *conf, sstr_t file) {
     pool_handle_t *pool = conf->pool;
--- a/src/server/daemon/config.h	Sun May 15 08:56:00 2022 +0200
+++ b/src/server/daemon/config.h	Sun Aug 07 13:46:43 2022 +0200
@@ -43,6 +43,9 @@
 #include "acldata.h"
 #include "keyfile_auth.h"
 #include "log.h"
+#include "vfs.h"
+
+#include "../webdav/webdav.h"
 
 #include <ucx/list.h>
 #include <ucx/map.h>
@@ -54,8 +57,11 @@
 #endif
 
 typedef struct mime_map MimeMap;
+
+typedef struct WebdavRepository      WebdavRepository;
+typedef struct WebdavBackendInitData WebdavBackendInitData;
     
-typedef struct _server_configuration {
+struct ServerConfiguration {
     pool_handle_t   *pool;
     UcxAllocator    *a;
     
@@ -69,8 +75,19 @@
     sstr_t          tmp;
     sstr_t          user;
     uint32_t        ref;        // reference counter
-} ServerConfiguration;
+};
 
+struct WebdavRepository {
+    VfsType *vfs;
+    void *vfsInitData;
+    UcxList *davBackends; // list of WebdavBackendInitData*
+    sstr_t object;
+};
+
+struct WebdavBackendInitData {
+    WebdavType *davType;
+    void *davInitData;
+};
 
 struct mime_map {
     UcxMap   *map;
@@ -98,6 +115,8 @@
 
 int cfg_handle_vs(ServerConfiguration *cfg, ConfigNode *obj);
 
+int cfg_handle_dav(ServerConfiguration *cfg, ConfigNode *obj);
+
 ServerConfiguration* load_server_conf(char *file);
 void cfg_ref(ServerConfiguration *cfg);
 void cfg_unref(ServerConfiguration *cfg);
--- a/src/server/daemon/resourcepool.c	Sun May 15 08:56:00 2022 +0200
+++ b/src/server/daemon/resourcepool.c	Sun Aug 07 13:46:43 2022 +0200
@@ -122,7 +122,7 @@
     ResourceDataPrivate *resource = NULL;
     
     // was this resource already used by this request?
-    if(request->resources) {
+    if(request && request->resources) {
         resource = ucx_map_cstr_get(request->resources, name);
         if(resource) {
             return &resource->data;
@@ -170,17 +170,19 @@
     // for cleanup later
     int err = 0;
     if(resource) {
-        if(!request->resources) {
-            request->resources = ucx_map_new_a(&session->allocator, 8);
-        }
-        
-        if(request->resources) {
-            if(ucx_map_cstr_put(request->resources, name, resource)) {
+        if(request) {
+            if(!request->resources) {
+                request->resources = ucx_map_new_a(&session->allocator, 8);
+            }
+
+            if(request->resources) {
+                if(ucx_map_cstr_put(request->resources, name, resource)) {
+                    err = 1;
+                }
+            } else {
                 err = 1;
             }
-        } else {
-            err = 1;
-        }
+        } // else: lookup is outside of any request context
         
         if(respool->type->prepare(respool->data, resource->resdata)) {
             err = -1;
--- a/src/server/daemon/vfs.c	Sun May 15 08:56:00 2022 +0200
+++ b/src/server/daemon/vfs.c	Sun Aug 07 13:46:43 2022 +0200
@@ -87,7 +87,7 @@
     return 0;
 }
 
-int vfs_register_type(const char *name, vfs_create_func vfsCreate) {
+int vfs_register_type(const char *name, vfs_init_func vfsInit, vfs_create_func vfsCreate) {
     WS_ASSERT(name);
     
     if(!vfs_type_map) {
@@ -95,18 +95,42 @@
             return 1;
         }
     }
-    return ucx_map_cstr_put(vfs_type_map, name, vfsCreate);
+    
+    VfsType *vfsType = malloc(sizeof(VfsType));
+    if(!vfsType) {
+        return 1;
+    }
+    vfsType->init = vfsInit;
+    vfsType->create = vfsCreate;
+    
+    return ucx_map_cstr_put(vfs_type_map, name, vfsType);
+}
+
+VfsType* vfs_get_type(scstr_t vfs_class) {
+    return ucx_map_sstr_get(vfs_type_map, vfs_class);
 }
 
+void* vfs_init_backend(ServerConfiguration *cfg, pool_handle_t *pool, VfsType *vfs_class, WSConfigNode *config, int *error) {
+    *error = 0;
+    if(vfs_class->init) {
+        void *initData = vfs_class->init(cfg, pool, config);
+        if(!initData) {
+            *error = 1;
+        }
+        return initData;
+    } else {
+        return NULL;
+    }
+}
 
-VFS* vfs_create(Session *sn, Request *rq, const char *vfs_class, pblock *pb) {
-    vfs_create_func createVFS = ucx_map_cstr_get(vfs_type_map, vfs_class);
-    if(!createVFS) {
+VFS* vfs_create(Session *sn, Request *rq, const char *vfs_class, pblock *pb, void *initData) {
+    VfsType *vfsType = ucx_map_cstr_get(vfs_type_map, vfs_class);
+    if(!vfsType) {
         log_ereport(LOG_MISCONFIG, "vfs_create: unkown VFS type %s", vfs_class);
         return NULL;
     }
     
-    return createVFS(sn, rq, pb);
+    return vfsType->create(sn, rq, pb, initData);
 }
 
 VFSContext* vfs_request_context(Session *sn, Request *rq) {
--- a/src/server/daemon/vfs.h	Sun May 15 08:56:00 2022 +0200
+++ b/src/server/daemon/vfs.h	Sun Aug 07 13:46:43 2022 +0200
@@ -32,10 +32,17 @@
 #include "../public/vfs.h"
 #include "acl.h"
 
+#include <ucx/string.h>
+
 #ifdef	__cplusplus
 extern "C" {
 #endif
 
+typedef struct VfsType {
+    vfs_init_func      init;
+    vfs_create_func    create;
+} VfsType;
+    
 typedef struct SysVFSDir {
     DIR           *dir;
     struct dirent *cur;
@@ -48,6 +55,9 @@
 typedef enum VFSAioOp VFSAioOp;
     
 int vfs_init(void);
+VfsType* vfs_get_type(scstr_t vfs_class);
+
+void* vfs_init_backend(ServerConfiguration *cfg, pool_handle_t *pool, VfsType *vfs_class, WSConfigNode *config, int *error);
 
 typedef int(*vfs_op_f)(VFSContext *, const char *);
 typedef int(*sys_op_f)(VFSContext *, const char *, SysACL *);
--- a/src/server/plugins/postgresql/Makefile	Sun May 15 08:56:00 2022 +0200
+++ b/src/server/plugins/postgresql/Makefile	Sun Aug 07 13:46:43 2022 +0200
@@ -36,6 +36,7 @@
 SRC += service.c
 SRC += vfs.c
 SRC += webdav.c
+SRC += config.c
 
 TEST_SRC  = pgtest.c
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/plugins/postgresql/config.c	Sun Aug 07 13:46:43 2022 +0200
@@ -0,0 +1,66 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2022 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.
+ */
+
+#include "config.h"
+
+#include "../../util/util.h"
+
+PgRepository* pg_init_repo(pool_handle_t *pool, WSConfigNode *config) {
+    UcxAllocator a = util_pool_allocator(pool);
+    
+    ConfigNode *pg = serverconfig_get_node(config, CONFIG_NODE_OBJECT, SC("Postgresql"));
+    if(!pg) {
+        log_ereport(LOG_MISCONFIG, "pg_init_repo: missing postgresql config object");
+        return NULL;
+    }
+    
+    scstr_t cfg_respool = serverconfig_directive_value(pg, SC("ResourcePool"));
+    scstr_t cfg_rootid = serverconfig_directive_value(pg, SC("RootId"));
+    scstr_t cfg_dav = serverconfig_directive_value(pg, SC("PGDavConfig"));
+    
+    // minimum requirement is a resource pool
+    if(cfg_respool.length == 0) {
+        return NULL;
+    }
+    
+    // check rootid
+    int64_t root_id = 1;
+    if(cfg_rootid.length > 0) {
+        if(!util_strtoint(cfg_rootid.ptr, &root_id)) {
+            log_ereport(LOG_MISCONFIG, "pg_init_repo: RootId parameter is not an integer: %s", cfg_rootid.ptr);
+            return NULL;
+        }
+    }
+    
+    PgRepository *repo = pool_malloc(pool, sizeof(PgRepository));
+    ZERO(repo, sizeof(PgRepository));
+    
+    repo->resourcepool = sstrdup_a(&a, cfg_respool);
+    
+    return repo;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/plugins/postgresql/config.h	Sun Aug 07 13:46:43 2022 +0200
@@ -0,0 +1,61 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2022 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_PG_CONFIG_H
+#define WS_PG_CONFIG_H
+
+#include "../../public/nsapi.h"
+#include "../../public/webdav.h"
+
+#include "../../daemon/config.h"
+#include "../../config/serverconfig.h"
+
+#include <inttypes.h>
+
+#include <libpq-fe.h>
+
+#include <ucx/string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct PgRepository {
+    int64_t root_resource_id;
+    sstr_t resourcepool;
+} PgRepository;
+
+PgRepository* pg_init_repo(pool_handle_t *pool, WSConfigNode *config);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WS_PG_CONFIG_H */
+
--- a/src/server/plugins/postgresql/init.c	Sun May 15 08:56:00 2022 +0200
+++ b/src/server/plugins/postgresql/init.c	Sun Aug 07 13:46:43 2022 +0200
@@ -52,11 +52,11 @@
 }
 
 int pg_register_vfs(pblock *pb) {
-    return vfs_register_type("postgresql", pg_vfs_create);
+    return vfs_register_type("postgresql", pg_vfs_init, pg_vfs_create);
 }
 
 int pg_register_webdav_backend(pblock *pb) {
-    if(webdav_register_backend("postgresql", pg_webdav_create)) {
+    if(webdav_register_backend("postgresql", pg_webdav_init, pg_webdav_create)) {
         return 1;
     }
     return 0;
--- a/src/server/plugins/postgresql/vfs.c	Sun May 15 08:56:00 2022 +0200
+++ b/src/server/plugins/postgresql/vfs.c	Sun Aug 07 13:46:43 2022 +0200
@@ -27,6 +27,7 @@
  */
 
 #include "vfs.h"
+#include "config.h"
 
 #include <inttypes.h>
 
@@ -140,7 +141,12 @@
 // params: $1: resource_id
 static const char *sql_delete_res = "delete from Resource where parent_id is not null and resource_id = $1;";
 
-VFS* pg_vfs_create(Session *sn, Request *rq, pblock *pb) {
+
+void* pg_vfs_init(ServerConfiguration *cfg, pool_handle_t *pool, WSConfigNode *config) {
+    return pg_init_repo(pool, config);
+}
+
+VFS* pg_vfs_create(Session *sn, Request *rq, pblock *pb, void *initData) {
     // resourcepool is required
     char *resource_pool = pblock_findval("resourcepool", pb);
     if(!resource_pool) {
--- a/src/server/plugins/postgresql/vfs.h	Sun May 15 08:56:00 2022 +0200
+++ b/src/server/plugins/postgresql/vfs.h	Sun Aug 07 13:46:43 2022 +0200
@@ -44,6 +44,7 @@
 typedef struct PgVFS {
     ResourceData *pg_resource;
     PGconn *connection;
+    int64_t root_resource_id;
 } PgVFS;
 
 typedef struct PgFile {
@@ -64,7 +65,9 @@
     int          nrows;
 } PgDir;
 
-VFS* pg_vfs_create(Session *sn, Request *rq, pblock *pb);
+void* pg_vfs_init(ServerConfiguration *cfg, pool_handle_t *pool, WSConfigNode *config);
+
+VFS* pg_vfs_create(Session *sn, Request *rq, pblock *pb, void *initData);
 
 VFS* pg_vfs_create_from_resourcedata(Session *sn, Request *rq, ResourceData *resdata);
 
--- a/src/server/plugins/postgresql/webdav.c	Sun May 15 08:56:00 2022 +0200
+++ b/src/server/plugins/postgresql/webdav.c	Sun Aug 07 13:46:43 2022 +0200
@@ -28,6 +28,7 @@
 
 #include "webdav.h"
 #include "vfs.h"
+#include "config.h"
 
 #include "../../util/util.h"
 #include "../../util/pblock.h"
@@ -269,7 +270,11 @@
 delete from Property where resource_id = $1 and xmlns = $2 and pname = $3";
 
 
-WebdavBackend* pg_webdav_create(Session *sn, Request *rq, pblock *pb) {
+void* pg_webdav_init(ServerConfiguration *cfg, pool_handle_t *pool, WSConfigNode *config) {
+    return pg_init_repo(pool, config);
+}
+
+WebdavBackend* pg_webdav_create(Session *sn, Request *rq, pblock *pb, void *initData) {
     // resourcepool is required
     char *resource_pool = pblock_findval("resourcepool", pb);
     if(!resource_pool) {
--- a/src/server/plugins/postgresql/webdav.h	Sun May 15 08:56:00 2022 +0200
+++ b/src/server/plugins/postgresql/webdav.h	Sun Aug 07 13:46:43 2022 +0200
@@ -44,6 +44,7 @@
 typedef struct PgWebdavBackend {
     ResourceData *pg_resource;
     PGconn *connection;
+    int64_t root_resource_id;
 } PgWebdavBackend;
     
 typedef struct PgPropfind {
@@ -54,7 +55,8 @@
     int nrows;
 } PgPropfind;
 
-WebdavBackend* pg_webdav_create(Session *sn, Request *rq, pblock *pb);
+void* pg_webdav_init(ServerConfiguration *cfg, pool_handle_t *pool, WSConfigNode *config);
+WebdavBackend* pg_webdav_create(Session *sn, Request *rq, pblock *pb, void *initData);
 WebdavBackend* pg_webdav_create_from_resdata(Session *sn, Request *rq, ResourceData *resdata);
 
 WebdavBackend* pg_webdav_prop_create(Session *sn, Request *rq, pblock *pb);
--- a/src/server/public/nsapi.h	Sun May 15 08:56:00 2022 +0200
+++ b/src/server/public/nsapi.h	Sun Aug 07 13:46:43 2022 +0200
@@ -691,6 +691,15 @@
 typedef struct VFS           VFS;
 typedef struct VFSContext    VFSContext;
 
+enum WSConfigNodeType {
+    WS_CONFIG_NODE_OBJECT = 0,
+    WS_CONFIG_NODE_DIRECTIVE
+};
+
+typedef struct ServerConfiguration ServerConfiguration;
+typedef struct ConfigNode          WSConfigNode;
+typedef enum WSConfigNodeType      WSConfigNodeType;
+
 #ifndef PR_AF_INET
 typedef union PRNetAddr PRNetAddr;
 #endif
--- a/src/server/public/vfs.h	Sun May 15 08:56:00 2022 +0200
+++ b/src/server/public/vfs.h	Sun Aug 07 13:46:43 2022 +0200
@@ -110,17 +110,18 @@
     void (*close)(VFS_DIR dir);
 };
 
-typedef VFS*(*vfs_create_func)(Session *sn, Request *rq, pblock *pb);
+typedef void*(*vfs_init_func)(ServerConfiguration *cfg, pool_handle_t *pool, WSConfigNode *config);
+typedef VFS*(*vfs_create_func)(Session *sn, Request *rq, pblock *pb, void *initData);
 
 /*
  * registers a new VFS
  */
-int vfs_register_type(const char *name, vfs_create_func vfsCreate);
+int vfs_register_type(const char *name, vfs_init_func vfsInit, vfs_create_func vfsCreate);
 
 /*
  * Create a new VFS instance
  */
-VFS* vfs_create(Session *sn, Request *rq, const char *vfs_class, pblock *pb);
+VFS* vfs_create(Session *sn, Request *rq, const char *vfs_class, pblock *pb, void *initData);
 
 /*
  * creates a VFSContext for a Request
--- a/src/server/public/webdav.h	Sun May 15 08:56:00 2022 +0200
+++ b/src/server/public/webdav.h	Sun Aug 07 13:46:43 2022 +0200
@@ -92,7 +92,8 @@
 #define WS_WEBDAV_PROPPATCH_USE_VFS   0x02
 
 
-typedef WebdavBackend*(*webdav_create_func)(Session *sn, Request *rq, pblock *pb);
+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,
@@ -392,9 +393,9 @@
 /*
  * register a webdav backend
  */
-int webdav_register_backend(const char *name, webdav_create_func vfsCreate);
+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);
+WebdavBackend* webdav_create(Session *sn, Request *rq, const char *dav_class, pblock *pb, void *initData);
 
 /*
  * gets the requested depth
--- a/src/server/safs/nametrans.c	Sun May 15 08:56:00 2022 +0200
+++ b/src/server/safs/nametrans.c	Sun Aug 07 13:46:43 2022 +0200
@@ -40,7 +40,7 @@
     char *vfsclass = pblock_findkeyval(pb_key_vfsclass, pb);
     if(!vfsclass) return 0;
     
-    VFS *vfs = vfs_create(sn, rq, vfsclass, pb);
+    VFS *vfs = vfs_create(sn, rq, vfsclass, pb, NULL);
     if(!vfs) {
         return 1;
     }
@@ -52,7 +52,7 @@
     char *davclass = pblock_findkeyval(pb_key_davclass, pb);
     if(!davclass) return 0;
     
-    WebdavBackend *dav = webdav_create(sn, rq, davclass, pb);
+    WebdavBackend *dav = webdav_create(sn, rq, davclass, pb, NULL);
     
     rq->davCollection = dav;
     return 0;
--- a/src/server/webdav/webdav.c	Sun May 15 08:56:00 2022 +0200
+++ b/src/server/webdav/webdav.c	Sun Aug 07 13:46:43 2022 +0200
@@ -85,19 +85,38 @@
     default_backend.instance = NULL;
 }
 
-int webdav_register_backend(const char *name, webdav_create_func webdavCreate) {
-    return ucx_map_cstr_put(webdav_type_map, name, webdavCreate);
+int webdav_register_backend(const char *name, webdav_init_func webdavInit, webdav_create_func webdavCreate) {
+    WebdavType *webdavType = malloc(sizeof(WebdavType));
+    webdavType->init = webdavInit;
+    webdavType->create = webdavCreate;
+    return ucx_map_cstr_put(webdav_type_map, name, webdavType);
+}
+
+WebdavType* webdav_get_type(scstr_t dav_class) {
+    return ucx_map_sstr_get(webdav_type_map, dav_class);
 }
 
+void* webdav_init_backend(ServerConfiguration *cfg, pool_handle_t *pool, WebdavType *dav_class, WSConfigNode *config, int *error) {
+    *error = 0;
+    if(dav_class->init) {
+        void *initData = dav_class->init(cfg, pool, config);
+        if(!initData) {
+            *error = 1;
+        }
+        return initData;
+    } else {
+        return NULL;
+    }
+}
 
-WebdavBackend* webdav_create(Session *sn, Request *rq, const char *dav_class, pblock *pb) {
-    webdav_create_func createDav = ucx_map_cstr_get(webdav_type_map, dav_class);
-    if(!createDav) {
+WebdavBackend* webdav_create(Session *sn, Request *rq, const char *dav_class, pblock *pb, void *initData) {
+    WebdavType *webdavType = ucx_map_cstr_get(webdav_type_map, dav_class);
+    if(!webdavType) {
         log_ereport(LOG_MISCONFIG, "webdav_create: unkown dav type %s", dav_class);
         return NULL;
     }
     
-    return createDav(sn, rq, pb);
+    return webdavType->create(sn, rq, pb, initData);
 }
 
 static WSBool webdav_is_initialized = FALSE;
--- a/src/server/webdav/webdav.h	Sun May 15 08:56:00 2022 +0200
+++ b/src/server/webdav/webdav.h	Sun Aug 07 13:46:43 2022 +0200
@@ -33,18 +33,25 @@
 
 #include <ucx/map.h>
 #include <ucx/list.h>
+#include <ucx/buffer.h>
 
 #ifdef	__cplusplus
 extern "C" {
 #endif
    
-
+typedef struct WebdavType {
+    webdav_init_func   init;
+    webdav_create_func create;
+} WebdavType;
     
 typedef struct DefaultWebdavData {
     WebdavVFSProperties vfsproperties;
 } DefaultWebdavData;
     
-    
+WebdavType* webdav_get_type(scstr_t dav_class);
+
+void* webdav_init_backend(ServerConfiguration *cfg, pool_handle_t *pool, WebdavType *dav_class, WSConfigNode *config, int *error);  
+
 int webdav_init(pblock *pb, Session *sn, Request *rq);
     
 int webdav_service(pblock *pb, Session *sn, Request *rq);

mercurial