src/server/daemon/location.c

changeset 651
ed74879c7041
parent 650
3e4f9cdd70b8
child 652
dd90c858eb74
--- 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);
 }

mercurial