src/server/daemon/location.c

changeset 636
40f069ddda37
parent 635
b85d45fd3b01
child 637
85721a583f39
--- 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);
+}

mercurial