src/server/daemon/rewrite.c

Sun, 07 Dec 2025 17:37:05 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 07 Dec 2025 17:37:05 +0100
changeset 652
dd90c858eb74
parent 651
ed74879c7041
permissions
-rw-r--r--

add rewrite_url tests

635
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1 /*
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
3 *
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
4 * Copyright 2025 Olaf Wintermann. All rights reserved.
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
5 *
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
6 * Redistribution and use in source and binary forms, with or without
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
7 * modification, are permitted provided that the following conditions are met:
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
8 *
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
9 * 1. Redistributions of source code must retain the above copyright
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
10 * notice, this list of conditions and the following disclaimer.
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
11 *
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
12 * 2. Redistributions in binary form must reproduce the above copyright
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
13 * notice, this list of conditions and the following disclaimer in the
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
14 * documentation and/or other materials provided with the distribution.
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
15 *
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
26 * POSSIBILITY OF SUCH DAMAGE.
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
27 */
b85d45fd3b01 add location config parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
28
646
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
29 #include "rewrite.h"
651
ed74879c7041 add rewrite directive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 647
diff changeset
30 #include "config.h"
646
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
31
647
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
32
651
ed74879c7041 add rewrite directive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 647
diff changeset
33 RewriteRule* rewrite_rule_create(ServerConfiguration *cfg, cxmutstr regex, cxmutstr url) {
ed74879c7041 add rewrite directive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 647
diff changeset
34 const CxAllocator *a = cfg->a;
ed74879c7041 add rewrite directive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 647
diff changeset
35
647
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
36 regex_t reg;
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
37 if(regex.ptr) {
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
38 if(regcomp(&reg, regex.ptr, REG_EXTENDED)) {
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
39 log_ereport(LOG_FAILURE, "rewrite: cannot compile regex: %s", regex.ptr);
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
40 return NULL;
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
41 }
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
42 }
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
43
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
44 RewriteRule *rule = cxMalloc(a, sizeof(RewriteRule));
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
45 if(!rule) {
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
46 return NULL;
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
47 }
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
48 rule->has_regex = regex.ptr != NULL;
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
49 rule->regex = reg;
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
50 rule->url = string_template_compile(a, cx_strcast(url));
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
51 if(!rule->url) {
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
52 return NULL;
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
53 }
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
54
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
55 return rule;
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
56 }
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
57
ffbc5076b4bf add rewrite_rule_create
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 646
diff changeset
58
646
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
59 typedef struct RVar {
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
60 cxstring str;
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
61 regmatch_t *match;
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
62 int nmatch;
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
63 } RVar;
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
64
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
65 static cxmutstr get_var(
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
66 const CxAllocator *a,
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
67 StringTemplateSegment *seg,
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
68 RVar *vardata,
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
69 WSBool *free_str)
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
70 {
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
71 if(seg->type != STRING_SEGMENT_NUM_PLACEHOLDER || seg->num < 0 || seg->num >= vardata->nmatch) {
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
72 return (cxmutstr){NULL, 0};
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
73 }
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
74 regmatch_t m = vardata->match[seg->num];
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
75 if(m.rm_eo == -1 || m.rm_so == -1) {
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
76 return (cxmutstr){NULL, 0};
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
77 }
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
78 cxstring ret = cx_strsubsl(vardata->str, m.rm_so, m.rm_eo-m.rm_so);
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
79 return (cxmutstr){(char*)ret.ptr, ret.length};
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
80 }
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
81
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
82 int rewrite_url(
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
83 RewriteRule *rule,
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
84 regmatch_t *match,
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
85 int nmatch,
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
86 const CxAllocator *a,
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
87 const char *url,
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
88 char **new_url)
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
89 {
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
90 *new_url = NULL;
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
91
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
92 RVar vars;
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
93 vars.str = cx_str(url);
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
94 vars.match = match;
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
95 vars.nmatch = nmatch;
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
96
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
97 regmatch_t rewrite_match[WS_REWRITE_NMATCH];
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
98 if(rule->has_regex) {
652
dd90c858eb74 add rewrite_url tests
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 651
diff changeset
99 if(regexec(&rule->regex, url, WS_REWRITE_NMATCH, rewrite_match, 0) != 0) {
646
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
100 return 0;
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
101 }
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
102 vars.match = rewrite_match;
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
103 vars.nmatch = WS_REWRITE_NMATCH;
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
104 }
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
105
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
106 // build new url
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
107 cxmutstr newstr = string_template_build_string(rule->url, a, (strtpl_var_func)get_var, &vars);
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
108 if(newstr.length == 0) {
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
109 return 1;
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
110 }
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
111 *new_url = newstr.ptr;
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
112
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
113 return 0;
f64ebb0c5fa9 add rewrite_url
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 635
diff changeset
114 }

mercurial