src/server/daemon/rewrite.c

Mon, 01 Dec 2025 21:16:45 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Mon, 01 Dec 2025 21:16:45 +0100
changeset 646
f64ebb0c5fa9
parent 635
b85d45fd3b01
child 647
ffbc5076b4bf
permissions
-rw-r--r--

add rewrite_url

/*
 * 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"

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, 0, rewrite_match, WS_REWRITE_NMATCH) != 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