add match_location nametrans SAF

Sun, 23 Nov 2025 13:22:56 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 23 Nov 2025 13:22:56 +0100
changeset 636
40f069ddda37
parent 635
b85d45fd3b01
child 637
85721a583f39

add match_location nametrans SAF

src/server/daemon/config.c file | annotate | diff | comparison | revisions
src/server/daemon/httprequest.c file | annotate | diff | comparison | revisions
src/server/daemon/location.c file | annotate | diff | comparison | revisions
src/server/daemon/location.h file | annotate | diff | comparison | revisions
src/server/daemon/request.h file | annotate | diff | comparison | revisions
src/server/daemon/ws-fn.c file | annotate | diff | comparison | revisions
src/server/safs/nametrans.c file | annotate | diff | comparison | revisions
src/server/safs/nametrans.h file | annotate | diff | comparison | revisions
--- a/src/server/daemon/config.c	Sun Nov 23 12:44:59 2025 +0100
+++ b/src/server/daemon/config.c	Sun Nov 23 13:22:56 2025 +0100
@@ -750,7 +750,7 @@
     CxList *locations = serverconfig_get_node_list(obj, CONFIG_NODE_OBJECT, CX_STR("Location"));
     CxIterator i = cxListIterator(locations);
     cx_foreach(ConfigNode *, node, i) {
-        WSLocation *location = cfg_location_get(cfg->a, node);
+        WSLocation *location = cfg_location_get(cfg, node);
         if(location) {
             vs_add_location(vs, location);
         } else {
--- a/src/server/daemon/httprequest.c	Sun Nov 23 12:44:59 2025 +0100
+++ b/src/server/daemon/httprequest.c	Sun Nov 23 13:22:56 2025 +0100
@@ -802,6 +802,9 @@
     // if no function has set the ppath var, translate it to docroot
     if(ret == REQ_NOACTION && ppath == NULL) {
         cxmutstr docroot = rq->vs->document_root;
+        if(rq->location && rq->location->docroot.ptr) {
+            docroot = rq->location->docroot;
+        }
         if(docroot.length < 1) {
             log_ereport(
                     LOG_WARN,
--- a/src/server/daemon/location.c	Sun Nov 23 12:44:59 2025 +0100
+++ b/src/server/daemon/location.c	Sun Nov 23 13:22:56 2025 +0100
@@ -28,7 +28,10 @@
 
 #include "location.h"
 #include "config.h"
+#include "request.h"
 #include "../util/util.h"
+#include "../util/pblock.h"
+#include "vserver.h"
 #include <cx/linked_list.h>
 
 #define DIR_CHECK_ARGC(n) if(argc != n) { \
@@ -42,7 +45,9 @@
     cx_linked_list_add(begin, end, offsetof(WSLocation, prev), offsetof(WSLocation, next), sub);
 }
 
-static int add_location_config(const CxAllocator *a, WSLocation *location, ConfigNode *dir) {
+static int add_location_config(ServerConfiguration *cfg, WSLocation *location, ConfigNode *dir) {
+    const CxAllocator *a = cfg->a;
+    
     cxmutstr name = dir->name;
     int argc = serverconfig_directive_count_args(dir);
     if(!cx_strcasecmp(name, "DirectoryIndex")) {
@@ -53,7 +58,7 @@
         DIR_CHECK_ARGC(1);
         location->config.docroot = cx_strdup_a(a, dir->args->value);
     } else if(!cx_strcasecmp(name, "Location")) {
-        WSLocation *sub_location = cfg_location_get(a, dir);
+        WSLocation *sub_location = cfg_location_get(cfg, dir);
         if(!sub_location) {
             return 1;
         }
@@ -64,11 +69,13 @@
 }
 
 
-WSLocation* cfg_location_get(const CxAllocator *a, ConfigNode *obj) { 
+WSLocation* cfg_location_get(ServerConfiguration *cfg, ConfigNode *obj) { 
+    const CxAllocator *a = cfg->a;
+    
     WSLocationMatch match = WS_LOCATION_MATCH_EXACT;
     cxmutstr match_str;
     
-    int regex_flags = REG_EXTENDED;
+    int regex_flags = REG_EXTENDED | REG_NOSUB;
     int argc = serverconfig_directive_count_args(obj);
     if(argc == 2) {
         // arg0: match type
@@ -110,7 +117,7 @@
     ConfigNode *dir = obj->children_begin;
     while(dir) {
         if(dir->type == CONFIG_NODE_OBJECT || dir->type == CONFIG_NODE_DIRECTIVE) {
-            if(add_location_config(a, location, dir)) {
+            if(add_location_config(cfg, location, dir)) {
                 log_ereport(LOG_FAILURE, "Location %s: abort", match_str.ptr);
                 return NULL;
             }
@@ -122,3 +129,65 @@
     
     return location;
 }
+
+int location_apply_config(WSLocationConfig *target, WSLocation *loc) {
+    WSLocationConfig *src = &loc->config;
+    if(src->set_dirindex) {
+        target->set_dirindex = TRUE;
+        target->dirindex = src->dirindex;
+    }
+    if(src->set_forcetls) {
+        target->set_forcetls = TRUE;
+        target->forcetls = src->forcetls;
+    }
+    if(src->docroot.ptr) {
+        target->docroot = src->docroot;
+    }
+    if(src->name.ptr) {
+        target->name = src->name;
+    }
+    if(src->dav) {
+        target->dav = src->dav;
+    }
+    // TODO: ...
+    
+    return 0;
+}
+
+int location_match(WSLocation *loc, cxstring uri) {
+    if(loc->match == WS_LOCATION_MATCH_EXACT) {
+        return !cx_strcmp(loc->match_string, uri);
+    } else if(loc->match == WS_LOCATION_MATCH_PREFIX) {
+        return cx_strprefix(uri, loc->match_string);
+    } else {
+        return regexec(&loc->regex, uri.ptr, 0, NULL, 0) == 0;
+    }
+    return 0;
+}
+
+WSLocationConfig* location_match_and_get_config(pool_handle_t *pool, cxstring uri, WSLocation *loc) {
+    WSLocationConfig *config = pool_malloc(pool, sizeof(WSLocationConfig));
+    if(!config) {
+        return NULL;
+    }
+    ZERO(config, sizeof(WSLocationConfig));
+    
+    while(loc) {
+        if(location_match(loc, uri)) {
+            if(location_apply_config(config, loc)) {
+                return NULL;
+            }
+        }
+        loc = loc->next;
+    }
+    
+    
+    return config;
+}
+
+WSLocationConfig* cfg_location_match(Session *sn, Request *rq) {
+    NSAPIRequest *req = (NSAPIRequest*)rq;
+    WSLocation *loc = req->vs->locations_begin;
+    char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
+    return location_match_and_get_config(sn->pool, cx_str(uri), loc);
+}
--- a/src/server/daemon/location.h	Sun Nov 23 12:44:59 2025 +0100
+++ b/src/server/daemon/location.h	Sun Nov 23 13:22:56 2025 +0100
@@ -34,6 +34,7 @@
 #include <regex.h>
 #include "../public/nsapi.h"
 #include "../config/serverconfig.h"
+#include "config.h"
 #include "../util/strreplace.h"
 #include "../webdav/webdav.h"
 
@@ -142,7 +143,12 @@
     WSLocation *next;
 };
 
-WSLocation* cfg_location_get(const CxAllocator *a, ConfigNode *obj);
+WSLocation* cfg_location_get(ServerConfiguration *cfg, ConfigNode *obj);
+
+int location_apply_config(WSLocationConfig *target, WSLocation *loc);
+int location_match(WSLocation *loc, cxstring uri);
+WSLocationConfig* location_match_and_get_config(pool_handle_t *pool, cxstring uri, WSLocation *loc);
+WSLocationConfig* cfg_location_match(Session *sn, Request *rq);
 
 #ifdef __cplusplus
 }
--- a/src/server/daemon/request.h	Sun Nov 23 12:44:59 2025 +0100
+++ b/src/server/daemon/request.h	Sun Nov 23 13:22:56 2025 +0100
@@ -32,6 +32,8 @@
 #include "../public/nsapi.h"
 #include "../util/object.h"
 
+#include "location.h"
+
 #include <cx/map.h>
 
 #ifdef	__cplusplus
@@ -41,15 +43,16 @@
 typedef struct NSAPIRequest NSAPIRequest;
 
 struct NSAPIRequest {
-    Request        rq;
-    RequestStage   phase;
-    VirtualServer  *vs;
-    char           *host;
-    uint16_t       port;
-    NSAPIContext   context;
-    void           *jvm_context;
-    CxMap          *resources;
-    WSBool         finished;
+    Request          rq;
+    RequestStage     phase;
+    VirtualServer    *vs;
+    char             *host;
+    uint16_t         port;
+    NSAPIContext     context;
+    WSLocationConfig *location;
+    void             *jvm_context;
+    CxMap            *resources;
+    WSBool           finished;
 };
 
 /* macros for context access */
--- a/src/server/daemon/ws-fn.c	Sun Nov 23 12:44:59 2025 +0100
+++ b/src/server/daemon/ws-fn.c	Sun Nov 23 13:22:56 2025 +0100
@@ -45,6 +45,7 @@
 
 struct FuncStruct webserver_funcs[] = {
     { "load-modules", load_modules, NULL, NULL, 0},
+    { "match-location", match_location, NULL, NULL, 0},
     { "assign-name", assign_name, NULL, NULL, 0},
     { "document-root", document_root, NULL, NULL, 0},
     { "pfx2dir", pfx2dir, NULL, NULL, 0},
--- a/src/server/safs/nametrans.c	Sun Nov 23 12:44:59 2025 +0100
+++ b/src/server/safs/nametrans.c	Sun Nov 23 13:22:56 2025 +0100
@@ -30,6 +30,7 @@
 
 #include "../daemon/log.h"
 #include "../daemon/request.h"
+#include "../daemon/location.h"
 #include "../util/pblock.h"
 #include "../util/util.h"
 #include "../public/webdav.h"
@@ -279,6 +280,19 @@
     return REQ_NOACTION;
 }
 
+int match_location(pblock *pb, Session *sn, Request *rq) {
+    NSAPIRequest *req = (NSAPIRequest*)rq;
+    
+    WSLocationConfig *config = cfg_location_match(sn, rq);
+    if(!config) {
+        return REQ_ABORTED;
+    }
+    req->location = config;
+    
+    return REQ_NOACTION;
+}
+
+
 /*
  * provisional rewrite saf
  */
--- a/src/server/safs/nametrans.h	Sun Nov 23 12:44:59 2025 +0100
+++ b/src/server/safs/nametrans.h	Sun Nov 23 13:22:56 2025 +0100
@@ -39,6 +39,7 @@
 int document_root(pblock *pb, Session *sn, Request *rq);
 int pfx2dir(pblock *pb, Session *sn, Request *rq);
 int redirect(pblock *pb, Session *sn, Request *rq);
+int match_location(pblock *pb, Session *sn, Request *rq);
 
 int simple_rewrite(pblock *pb, Session *sn, Request *rq);
 

mercurial