Mon, 01 Dec 2025 21:16:45 +0100
add rewrite_url
--- 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 */ +