src/server/daemon/rewrite.c

Sun, 07 Dec 2025 20:16:02 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 07 Dec 2025 20:16:02 +0100
changeset 656
59dd1fb27639
parent 652
dd90c858eb74
permissions
-rw-r--r--

update uwproj

/*
 * 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 "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(&reg, 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;
    }
    
    // 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;
}

mercurial