| 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 26 * POSSIBILITY OF SUCH DAMAGE. |
26 * POSSIBILITY OF SUCH DAMAGE. |
| 27 */ |
27 */ |
| 28 |
28 |
| 29 #include "rewrite.h" |
29 #include "rewrite.h" |
| |
30 |
| |
31 typedef struct RVar { |
| |
32 cxstring str; |
| |
33 regmatch_t *match; |
| |
34 int nmatch; |
| |
35 } RVar; |
| |
36 |
| |
37 static cxmutstr get_var( |
| |
38 const CxAllocator *a, |
| |
39 StringTemplateSegment *seg, |
| |
40 RVar *vardata, |
| |
41 WSBool *free_str) |
| |
42 { |
| |
43 if(seg->type != STRING_SEGMENT_NUM_PLACEHOLDER || seg->num < 0 || seg->num >= vardata->nmatch) { |
| |
44 return (cxmutstr){NULL, 0}; |
| |
45 } |
| |
46 regmatch_t m = vardata->match[seg->num]; |
| |
47 if(m.rm_eo == -1 || m.rm_so == -1) { |
| |
48 return (cxmutstr){NULL, 0}; |
| |
49 } |
| |
50 cxstring ret = cx_strsubsl(vardata->str, m.rm_so, m.rm_eo-m.rm_so); |
| |
51 return (cxmutstr){(char*)ret.ptr, ret.length}; |
| |
52 } |
| |
53 |
| |
54 int rewrite_url( |
| |
55 RewriteRule *rule, |
| |
56 regmatch_t *match, |
| |
57 int nmatch, |
| |
58 const CxAllocator *a, |
| |
59 const char *url, |
| |
60 char **new_url) |
| |
61 { |
| |
62 *new_url = NULL; |
| |
63 |
| |
64 RVar vars; |
| |
65 vars.str = cx_str(url); |
| |
66 vars.match = match; |
| |
67 vars.nmatch = nmatch; |
| |
68 |
| |
69 regmatch_t rewrite_match[WS_REWRITE_NMATCH]; |
| |
70 if(rule->has_regex) { |
| |
71 if(regexec(&rule->regex, url, 0, rewrite_match, WS_REWRITE_NMATCH) != 0) { |
| |
72 return 0; |
| |
73 } |
| |
74 vars.match = rewrite_match; |
| |
75 vars.nmatch = WS_REWRITE_NMATCH; |
| |
76 } |
| |
77 |
| |
78 // build new url |
| |
79 cxmutstr newstr = string_template_build_string(rule->url, a, (strtpl_var_func)get_var, &vars); |
| |
80 if(newstr.length == 0) { |
| |
81 return 1; |
| |
82 } |
| |
83 *new_url = newstr.ptr; |
| |
84 |
| |
85 return 0; |
| |
86 } |