Is there a way to split a long line of code in VCL?

77 views Asked by At

I can't figure out how to split a long line of code in VCL. I have checked the Varnish docs and Fastly's, and I can't find anything except this regarding VTC files, which I also tested and didn't work with strings, probably due to indentation.

I find it hard to believe that the language doesn't allow splitting long lines or that the docs don't have a single example.

if (req.url.path ~ "^/stuff/otherstuff/(?:[a-z0-9_]+)(?:/(?:2018|2018_2019|2019|2019_2020|2020|2020_2021|2021|2021_2022|2022|2022_2023|2023|2023_2024|2024))?(?:/(?:cool|story|bro)(?:/.*)?)?/?$") {
    # do something
}
1

There are 1 answers

3
Thijs Feryn On BEST ANSWER

You can use long strings in VCL to spread your regex string across multiple lines.

However, the newline character is going to interfere with your regex. The way to tackle this is by adding (?x) to your regex to ignore the newlines in your pattern.

Here's the VCL to do it:

sub vcl_recv {
    if(req.url ~ {"^(?x)/[a-z]+
        [0-9]+"}) {
        return(synth(200));
    }
    return(synth(400));
}

Calling /abc123 would return 200. Calling /foo would return 400.

Here's a varnishtest proof of concept:

varnishtest "multiline regex"

varnish v1 -vcl {
    backend default none;
    sub vcl_recv {
        if(req.url ~ {"^(?x)/[a-z]+
        [0-9]+"}) {
            return(synth(200));
        }
        return(synth(400));
    }
} -start

client c1 {
        txreq -url "/abc123"
        rxresp
        expect resp.status == 200

        txreq -url "/foo"
        rxresp
        expect resp.status == 400
} -run

Your can run this by putting the test case in a VTC file (e.g. multiline-regex.vtc) and then run varnishtest multiline-regex.vtc to run the test and validate the proof of concept.