--- a/src/server/daemon/location.c Sun Dec 07 16:31:21 2025 +0100 +++ b/src/server/daemon/location.c Sun Dec 07 17:06:21 2025 +0100 @@ -29,8 +29,10 @@ #include "location.h" #include "config.h" #include "request.h" +#include "rewrite.h" #include "../util/util.h" #include "../util/pblock.h" +#include "../util/pool.h" #include "vserver.h" #include <cx/linked_list.h> #include <cx/array_list.h> @@ -84,6 +86,36 @@ return 1; } location_list_add(location, sub_location); + } else if(!cx_strcasecmp(name, "Rewrite")) { + cxmutstr regex = (cxmutstr){NULL, 0}; + cxmutstr url = (cxmutstr){NULL, 0}; + if(argc == 1) { + // no custom rewrite regex + url = dir->args->value; + } else if(argc == 2) { + // regex, url + regex = dir->args->value; + url = dir->args->next->value; + } else { + log_ereport(LOG_FAILURE, "rewrite [regex] <url>: illegal argc %d", argc); + return 1; + } + + RewriteRule *rule = rewrite_rule_create(cfg, regex, url); + if(!rule) { + return 1; + } + + if(!location->rewrite) { + location->rewrite = cxLinkedListCreate(a, NULL, CX_STORE_POINTERS); + if(!location->rewrite) { + return 1; + } + } + + if(cxListAdd(location->rewrite, rule)) { + return 1; + } } return 0; @@ -197,7 +229,7 @@ return 0; } -WSLocationConfig* location_match_and_get_config(pool_handle_t *pool, cxstring uri, WSLocation *loc) { +WSLocationConfig* location_match_and_get_config(pool_handle_t *pool, Request *rq, cxstring uri, WSLocation *loc) { WSLocationConfig *config = pool_malloc(pool, sizeof(WSLocationConfig)); if(!config) { return NULL; @@ -208,8 +240,22 @@ config->match[i].rm_eo = -1; } + const CxAllocator *a = pool_allocator(pool); + while(loc) { if(location_match(loc, uri, config->match)) { + // apply rewrite rules + CxIterator iter = cxListIterator(loc->rewrite); + cx_foreach(RewriteRule *, rule, iter) { + char *new_url = NULL; + if(!rewrite_url(rule, config->match, WS_LOCATION_NMATCH, a, uri.ptr, &new_url)) { + pblock_removekey(pb_key_uri, rq->reqpb); + if(pblock_kvinsert(pb_key_uri, new_url, strlen(new_url), rq->reqpb) == NULL) { + return NULL; + } + } + } + if(location_apply_config(config, loc)) { return NULL; } @@ -225,5 +271,5 @@ 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); + return location_match_and_get_config(sn->pool, rq, cx_str(uri), loc); }