diff -r 570026d3a685 -r 47bc686fafe4 src/server/daemon/config.c --- 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;