add config option for pg root node lookup webdav

Thu, 11 Aug 2022 20:51:39 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 11 Aug 2022 20:51:39 +0200
branch
webdav
changeset 372
1d2538a1ba8f
parent 371
ea836c4f7341
child 373
f78a585e1a2f

add config option for pg root node lookup

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/vfs.c file | annotate | diff | comparison | revisions
src/server/plugins/postgresql/webdav.c file | annotate | diff | comparison | revisions
--- a/src/server/plugins/postgresql/config.c	Thu Aug 11 20:21:13 2022 +0200
+++ b/src/server/plugins/postgresql/config.c	Thu Aug 11 20:51:39 2022 +0200
@@ -30,7 +30,52 @@
 
 #include "../../util/util.h"
 
-PgRepository* pg_init_repo(pool_handle_t *pool, WSConfigNode *config) {
+static const char *sql_get_repository_root = "select resource_id from Resource where parent_id is NULL and nodename = $1 ;";
+
+
+// Uses a PGconn to lookup the resource id of the specified root node
+// if the lookup succeeds, the resource id is written to rootid
+// in case of an error, an error message will be logged
+// returns: 0 success, 1 error
+static int pg_lookup_root(ResourceData *res, scstr_t rootnode, int64_t *rootid) {
+    PGconn *connection = res->data;
+    
+    PGresult *result = PQexecParams(
+            connection,
+            sql_get_repository_root,
+            1,     // number of parameters
+            NULL,
+            &rootnode.ptr, // parameter value
+            NULL,
+            NULL,
+            0);    // 0: result in text format
+    
+    if(!result) {
+        log_ereport(LOG_FAILURE, "pg: root lookup failed: %s", PQerrorMessage(connection));
+        return 1;
+    }
+    
+    int ret = 0;
+    
+    int nrows = PQntuples(result);
+    if(nrows == 1) {
+        char *resource_id_str = PQgetvalue(result, 0, 0);
+        if(resource_id_str) {
+            if(!util_strtoint(resource_id_str, rootid)) {
+                log_ereport(LOG_FAILURE, "pg: unexpected result for column resource_id", rootnode.ptr);
+                ret = 1;
+            }
+        }
+    } else {
+        log_ereport(LOG_FAILURE, "pg: cannot find root resource '%s'", rootnode.ptr);
+        ret = 1;
+    }
+    PQclear(result);
+    
+    return ret;
+}
+
+PgRepository* pg_init_repo(ServerConfiguration *cfg, pool_handle_t *pool, WSConfigNode *config) {
     UcxAllocator a = util_pool_allocator(pool);
     
     ConfigNode *pg = serverconfig_get_node(config, CONFIG_NODE_OBJECT, SC("Postgresql"));
@@ -41,6 +86,7 @@
     
     scstr_t cfg_respool = serverconfig_directive_value(pg, SC("ResourcePool"));
     scstr_t cfg_rootid = serverconfig_directive_value(pg, SC("RootId"));
+    scstr_t cfg_rootnode = serverconfig_directive_value(pg, SC("RootNode"));
     scstr_t cfg_dav = serverconfig_directive_value(pg, SC("PGDavConfig"));
     
     // minimum requirement is a resource pool
@@ -57,6 +103,29 @@
         }
     }
     
+    // warn if RootId and RootNode are specified
+    if(cfg_rootid.length > 0 && cfg_rootnode.length > 0) {
+        log_ereport(LOG_WARN, "log_init_repo: RootId and RootNode specified, RootNode ignored");
+    } else if(cfg_rootnode.length > 0) {
+        // check root node
+        
+        // resolve rootnode
+        // therefore we first need to get a connection from the resourcepool
+        ResourceData *res = resourcepool_cfg_lookup(cfg, cfg_respool.ptr, 0);
+        if(!res) {
+            log_ereport(LOG_MISCONFIG, "pg_init_repo: resource lookup failed");
+            return NULL;
+        }
+        // do lookup, if successful, root_id will be set
+        int lookup_err = pg_lookup_root(res, cfg_rootnode, &root_id);
+        // we don't need the connection anymore
+        resourcepool_free(NULL, NULL, res);
+        if(lookup_err) {
+            // no logging required, pg_lookup_root will log the error
+            return NULL;
+        }
+    }
+    
     PgRepository *repo = pool_malloc(pool, sizeof(PgRepository));
     ZERO(repo, sizeof(PgRepository));
     
--- a/src/server/plugins/postgresql/config.h	Thu Aug 11 20:21:13 2022 +0200
+++ b/src/server/plugins/postgresql/config.h	Thu Aug 11 20:51:39 2022 +0200
@@ -51,7 +51,7 @@
     sstr_t resourcepool;
 } PgRepository;
 
-PgRepository* pg_init_repo(pool_handle_t *pool, WSConfigNode *config);
+PgRepository* pg_init_repo(ServerConfiguration *cfg, pool_handle_t *pool, WSConfigNode *config);
 
 #ifdef __cplusplus
 }
--- a/src/server/plugins/postgresql/vfs.c	Thu Aug 11 20:21:13 2022 +0200
+++ b/src/server/plugins/postgresql/vfs.c	Thu Aug 11 20:51:39 2022 +0200
@@ -143,7 +143,7 @@
 
 
 void* pg_vfs_init(ServerConfiguration *cfg, pool_handle_t *pool, WSConfigNode *config) {
-    return pg_init_repo(pool, config);
+    return pg_init_repo(cfg, pool, config);
 }
 
 VFS* pg_vfs_create(Session *sn, Request *rq, pblock *pb, void *initData) {
--- a/src/server/plugins/postgresql/webdav.c	Thu Aug 11 20:21:13 2022 +0200
+++ b/src/server/plugins/postgresql/webdav.c	Thu Aug 11 20:51:39 2022 +0200
@@ -271,7 +271,7 @@
 
 
 void* pg_webdav_init(ServerConfiguration *cfg, pool_handle_t *pool, WSConfigNode *config) {
-    return pg_init_repo(pool, config);
+    return pg_init_repo(cfg, pool, config);
 }
 
 WebdavBackend* pg_webdav_create(Session *sn, Request *rq, pblock *pb, void *initData) {

mercurial