1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include "rewrite.h"
30 #include "config.h"
31
32
33 RewriteRule* rewrite_rule_create(ServerConfiguration *cfg, cxmutstr regex, cxmutstr url) {
34 const CxAllocator *a = cfg->a;
35
36 regex_t reg;
37 if(regex.ptr) {
38 if(regcomp(®, regex.ptr,
REG_EXTENDED)) {
39 log_ereport(
LOG_FAILURE,
"rewrite: cannot compile regex: %s", regex.ptr);
40 return NULL;
41 }
42 }
43
44 RewriteRule *rule = cxMalloc(a,
sizeof(RewriteRule));
45 if(!rule) {
46 return NULL;
47 }
48 rule->has_regex = regex.ptr !=
NULL;
49 rule->regex = reg;
50 rule->url = string_template_compile(a, cx_strcast(url));
51 if(!rule->url) {
52 return NULL;
53 }
54
55 return rule;
56 }
57
58
59 typedef struct RVar {
60 cxstring str;
61 regmatch_t *match;
62 int nmatch;
63 } RVar;
64
65 static cxmutstr get_var(
66 const CxAllocator *a,
67 StringTemplateSegment *seg,
68 RVar *vardata,
69 WSBool *free_str)
70 {
71 if(seg->type !=
STRING_SEGMENT_NUM_PLACEHOLDER || seg->num <
0 || seg->num >= vardata->nmatch) {
72 return (cxmutstr){
NULL,
0};
73 }
74 regmatch_t m = vardata->match[seg->num];
75 if(m.rm_eo ==
-1 || m.rm_so ==
-1) {
76 return (cxmutstr){
NULL,
0};
77 }
78 cxstring ret = cx_strsubsl(vardata->str, m.rm_so, m.rm_eo-m.rm_so);
79 return (cxmutstr){(
char*)ret.ptr, ret.length};
80 }
81
82 int rewrite_url(
83 RewriteRule *rule,
84 regmatch_t *match,
85 int nmatch,
86 const CxAllocator *a,
87 const char *url,
88 char **new_url)
89 {
90 *new_url =
NULL;
91
92 RVar vars;
93 vars.str = cx_str(url);
94 vars.match = match;
95 vars.nmatch = nmatch;
96
97 regmatch_t rewrite_match[
WS_REWRITE_NMATCH];
98 if(rule->has_regex) {
99 if(regexec(&rule->regex, url,
WS_REWRITE_NMATCH, rewrite_match,
0) !=
0) {
100 return 0;
101 }
102 vars.match = rewrite_match;
103 vars.nmatch =
WS_REWRITE_NMATCH;
104 }
105
106
107 cxmutstr newstr = string_template_build_string(rule->url, a, (strtpl_var_func)get_var, &vars);
108 if(newstr.length ==
0) {
109 return 1;
110 }
111 *new_url = newstr.ptr;
112
113 return 0;
114 }
115