#include "rewrite.h"
#include "config.h"
RewriteRule* rewrite_rule_create(ServerConfiguration *cfg, cxmutstr regex, cxmutstr url) {
const CxAllocator *a = cfg->a;
regex_t reg;
if(regex.ptr) {
if(regcomp(®, regex.ptr,
REG_EXTENDED)) {
log_ereport(
LOG_FAILURE,
"rewrite: cannot compile regex: %s", regex.ptr);
return NULL;
}
}
RewriteRule *rule = cxMalloc(a,
sizeof(RewriteRule));
if(!rule) {
return NULL;
}
rule->has_regex = regex.ptr !=
NULL;
rule->regex = reg;
rule->url = string_template_compile(a, cx_strcast(url));
if(!rule->url) {
return NULL;
}
return rule;
}
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,
WS_REWRITE_NMATCH, rewrite_match,
0) !=
0) {
return 0;
}
vars.match = rewrite_match;
vars.nmatch =
WS_REWRITE_NMATCH;
}
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;
}