diff -r b85d45fd3b01 -r 40f069ddda37 src/server/daemon/location.c --- 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 #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); +}