src/server/daemon/config.c

branch
webdav
changeset 366
47bc686fafe4
parent 339
f4a34b0869c7
child 367
1592224f6059
--- 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;

mercurial