add rewrite_url

Mon, 01 Dec 2025 21:16:45 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Mon, 01 Dec 2025 21:16:45 +0100
changeset 646
f64ebb0c5fa9
parent 645
0c85c4cd0dd8
child 647
ffbc5076b4bf

add rewrite_url

src/server/daemon/objs.mk file | annotate | diff | comparison | revisions
src/server/daemon/rewrite.c file | annotate | diff | comparison | revisions
src/server/daemon/rewrite.h file | annotate | diff | comparison | revisions
src/server/test/main.c file | annotate | diff | comparison | revisions
src/server/test/objs.mk file | annotate | diff | comparison | revisions
src/server/test/rewrite.c file | annotate | diff | comparison | revisions
src/server/test/rewrite.h file | annotate | diff | comparison | revisions
--- a/src/server/daemon/objs.mk	Sun Nov 30 18:25:55 2025 +0100
+++ b/src/server/daemon/objs.mk	Mon Dec 01 21:16:45 2025 +0100
@@ -59,6 +59,7 @@
 DAEMONOBJ += vfs.o
 DAEMONOBJ += resourcepool.o
 DAEMONOBJ += location.o
+DAEMONOBJ += rewrite.o
 
 # add additional platform dependend objects
 # defined in generated config.mk
--- a/src/server/daemon/rewrite.c	Sun Nov 30 18:25:55 2025 +0100
+++ b/src/server/daemon/rewrite.c	Mon Dec 01 21:16:45 2025 +0100
@@ -26,4 +26,61 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "rewrite.h"
\ No newline at end of file
+#include "rewrite.h"
+
+typedef struct RVar {
+    cxstring str;
+    regmatch_t *match;
+    int nmatch;
+} RVar;
+
+static cxmutstr get_var(
+        const CxAllocator *a,
+        StringTemplateSegment *seg,
+        RVar *vardata,
+        WSBool *free_str)
+{
+    if(seg->type != STRING_SEGMENT_NUM_PLACEHOLDER || seg->num < 0 || seg->num >= vardata->nmatch) {
+        return (cxmutstr){NULL, 0};
+    }
+    regmatch_t m = vardata->match[seg->num];
+    if(m.rm_eo == -1 || m.rm_so == -1) {
+        return (cxmutstr){NULL, 0};
+    }
+    cxstring ret = cx_strsubsl(vardata->str, m.rm_so, m.rm_eo-m.rm_so);
+    return (cxmutstr){(char*)ret.ptr, ret.length};
+}
+
+int rewrite_url(
+        RewriteRule *rule,
+        regmatch_t *match,
+        int nmatch,
+        const CxAllocator *a,
+        const char *url,
+        char **new_url)
+{
+    *new_url = NULL;
+    
+    RVar vars;
+    vars.str = cx_str(url);
+    vars.match = match;
+    vars.nmatch = nmatch;
+    
+    regmatch_t rewrite_match[WS_REWRITE_NMATCH];
+    if(rule->has_regex) {
+        if(regexec(&rule->regex, url, 0, rewrite_match, WS_REWRITE_NMATCH) != 0) {
+            return 0;
+        }
+        vars.match = rewrite_match;
+        vars.nmatch = WS_REWRITE_NMATCH;
+    }
+    
+    // build new url
+    cxmutstr newstr = string_template_build_string(rule->url, a, (strtpl_var_func)get_var, &vars);
+    if(newstr.length == 0) {
+        return 1;
+    }
+    *new_url = newstr.ptr;
+    
+    return 0;
+}
--- a/src/server/daemon/rewrite.h	Sun Nov 30 18:25:55 2025 +0100
+++ b/src/server/daemon/rewrite.h	Mon Dec 01 21:16:45 2025 +0100
@@ -40,9 +40,11 @@
 extern "C" {
 #endif
 
+#define WS_REWRITE_NMATCH 16
+    
 typedef struct RewriteRule {
     /*
-     * 
+     * uncompiled regex string
      */
     cxmutstr match;
     
@@ -52,11 +54,24 @@
     regex_t regex;
     
     /*
+     * does this RewriteRule has a regex rule?
+     */
+    WSBool has_regex;
+    
+    /*
      * Rewrite to this url
      */
     StringTemplate *url;
 } RewriteRule;
 
+int rewrite_url(
+        RewriteRule *rule,
+        regmatch_t *match,
+        int nmatch,
+        const CxAllocator *a,
+        const char *url,
+        char **new_url);
+
 
 #ifdef __cplusplus
 }
--- a/src/server/test/main.c	Sun Nov 30 18:25:55 2025 +0100
+++ b/src/server/test/main.c	Mon Dec 01 21:16:45 2025 +0100
@@ -51,6 +51,7 @@
 #include "io.h"
 #include "event.h"
 #include "strreplace.h"
+#include "rewrite.h"
 
 void register_pg_tests(int argc, char **argv, CxTestSuite *suite);
 
@@ -147,6 +148,9 @@
     cx_test_register(suite, test_string_template_write_to);
     cx_test_register(suite, test_string_template_build_string);
     
+    // rewrite tests
+    cx_test_register(suite, test_rewrite_url_no_regex);
+    
     // xml tests
     cx_test_register(suite, test_wsxml_iterator);
     cx_test_register(suite, test_wsxml_get_required_namespaces);
--- a/src/server/test/objs.mk	Sun Nov 30 18:25:55 2025 +0100
+++ b/src/server/test/objs.mk	Mon Dec 01 21:16:45 2025 +0100
@@ -42,6 +42,7 @@
 TESTOBJ += io.o
 TESTOBJ += event.o
 TESTOBJ += strreplace.o
+TESTOBJ += rewrite.o
 
 TESTOBJS = $(TESTOBJ:%=$(TEST_OBJPRE)%)
 TESTSOURCE = $(TESTOBJ:%.o=test/%.c)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/test/rewrite.c	Mon Dec 01 21:16:45 2025 +0100
@@ -0,0 +1,54 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2025 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "rewrite.h"
+
+#include "../daemon/rewrite.h"
+#include <cx/mempool.h>
+#include <string.h>
+
+
+CX_TEST(test_rewrite_url_no_regex) {
+    CxMempool *mp = cxMempoolCreate(100, CX_MEMPOOL_TYPE_ADVANCED);
+    const CxAllocator *a = mp->allocator;
+    
+    RewriteRule rule;
+    memset(&rule, 0, sizeof(RewriteRule));
+    rule.url = string_template_compile(a, cx_str("/static/"));
+    
+    CX_TEST_DO {
+        char *new_url = NULL;
+        int r = rewrite_url(&rule, NULL, 0, a, "/previous/url", &new_url);
+        
+        CX_TEST_ASSERT(r == 0);
+        CX_TEST_ASSERT(new_url != NULL);
+        CX_TEST_ASSERT(!strcmp(new_url, "/static/"));
+    }
+    
+    cxMempoolFree(mp);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/test/rewrite.h	Mon Dec 01 21:16:45 2025 +0100
@@ -0,0 +1,46 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2025 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TEST_REWRITE_H
+#define TEST_REWRITE_H
+
+#include <cx/test.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+CX_TEST(test_rewrite_url_no_regex);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TEST_REWRITE_H */
+

mercurial