syntaxvarnishvarnish-vclfastly

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


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
}

Solution

  • 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.