Sun, 23 Nov 2025 13:22:56 +0100
add match_location nametrans SAF
--- 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);