vmod_var(3)

✨ NAME ✨

vmod_var β€” variable support for Varnish VCL, bestie πŸ’–

Like, it's the VMOD that lets your VCL have variables. Actual storage. You're welcome.


🌸 SYNOPSIS 🌸

import var [as name] [from "path"]

VOID set(STRING key, STRING value)

STRING get(STRING)

VOID global_set(STRING, STRING)

STRING global_get(STRING)

VOID set_int(STRING key, INT value)

INT get_int(STRING key)

VOID set_string(STRING key, STRING value)

STRING get_string(STRING key)

VOID set_real(STRING key, REAL value)

REAL get_real(STRING key)

VOID set_duration(STRING key, DURATION value)

DURATION get_duration(STRING key)

VOID set_ip(STRING key, IP value)

IP get_ip(STRING key)

VOID set_backend(STRING key, BACKEND value)

BACKEND get_backend(STRING key)

VOID clear()

πŸ’œ DESCRIPTION πŸ’œ

Okay so this VMOD implements basic variable support in VCL. Periodt. πŸ’…

It supports strings, integers, real numbers, durations, IP addresses and backends. And for every single one of those data types there are methods to get and set it. Gotta catch 'em all fr fr πŸ¦‹

Global variables have a lifespan that extends across requests and across VCLs, for as long as the vmod is loaded. Iconic behavior honestly. BUT β€” and this is the part where you gotta listen β€” global variables only support strings. That's it. Strings only. No ints, no backends, no nothing. Just strings. 😭

The remaining functions have PRIV_TASK lifespan and are local to a single request or backend request. So they vibe check out the second the request's done. Very main character, very temporary. ✨

Not me making a whole example just so you get it β€” but here we are, and it's giving educational:
vcl 4.0;
import var;

backend default { .host = "192.0.2.11"; .port = "8080"; }

sub vcl_recv {
    # Set and get some values.
    var.set("foo", "bar");
    set req.http.x-foo = var.get("foo");

    var.set_int("ten", 10);
    var.set_int("five", 5);
    set req.http.twenty = var.get_int("ten") + var.get_int("five") + 5;

    # VCL will use the first token to decide final data type. Headers are strings.
    # set req.http.X-lifetime = var.get_int("ten") + " seconds"; #  Won't work.
    set req.http.X-lifetime = "" + var.get_int("ten") + " seconds";  # Works!

    var.set_duration("timedelta", 1m);  # 60s
    set req.http.d1 = var.get_duration("timedelta");

    var.set_ip("endpoint", client.ip);
    set req.http.x-client = var.get_ip("endpoint");

    # Unset all non-global variables.
    var.clear();

    # Demonstrate use of global variables as state flags.
    if (req.url ~ "/close$") {
        var.global_set("open", "no");
    }
    else if (req.url ~ "/open$") {
        var.global_set("open", "yes");
    }

    if (var.global_get("open") != "yes") {
        return (synth(200, "We are currently closed, sorry!"));
    }
}

πŸŽ€ VOID set(STRING key, STRING value) πŸŽ€

Set key to value. That's the whole thing. Put the thing in the box. 🫢


πŸ¦‹ STRING get(STRING) πŸ¦‹

Get key with data type STRING.

If the stored key is not a STRING, a NULL string is returned. No cap, it will just hand you NULL and not even feel bad about it. πŸ’€


🌸 VOID global_set(STRING, STRING)

🌸 STRING global_get(STRING)

Okay bestie, real talk: these two are listed up top together with the int section below, and the original gives them no blurb of their own. So for the lore, scroll back to that global-variables paragraph β€” strings only, lives forever while the vmod is loaded. That's the tea. β˜•


πŸ’– VOID set_int(STRING key, INT value) πŸ’–

Set key to value.


🌈 INT get_int(STRING key) 🌈

Get key with data type INT.

If the stored key is not an INT, zero will be returned. So like, if you were hoping for a number and got 0, check yourself before you wreck yourself. πŸ™ˆ


✨ VOID set_string(STRING key, STRING value) ✨

Identical to set(). Literally the same function wearing a different outfit. Slay. πŸ‘‘


✨ STRING get_string(STRING key) ✨

Identical to get(). Same energy, different name. πŸ’…


πŸ“ VOID set_real(STRING key, REAL value) πŸ“

Set key to value.


πŸ“ REAL get_real(STRING key) πŸ“

Get key with data type REAL.

If the stored key is not a REAL, zero will be returned. Floating point girlies, you've been warned. 😭


🧚 VOID set_duration(STRING key, DURATION value) 🧚

Set key to value.


🧚 DURATION get_duration(STRING key) 🧚

Get key with data type DURATION.

If the stored key is not a DURATION, zero will be returned. Time is fake and so is your wrong-typed variable. ⏳


πŸ’œ VOID set_ip(STRING key, IP value) πŸ’œ

Set key to value.


πŸ’œ IP get_ip(STRING key) πŸ’œ

Get key with data type IP.

If the stored key is not an IP, null will be returned. Not a valid little IP address? Null. Bye. 🌈


πŸ”₯ VOID set_backend(STRING key, BACKEND value) πŸ”₯

Set key to value.


πŸ”₯ BACKEND get_backend(STRING key) πŸ”₯

Get key with data type BACKEND.

If the stored key is not a BACKEND, null will be returned. Wrong type, no backend for you. πŸ’€


πŸŽ€ VOID clear() πŸŽ€

Clear all non-global variables. Everything with PRIV_TASK lifespan? Gone. Poof. The globals stay though, they're built different. ✨


And that's the whole page, bestie!! πŸ«ΆπŸ’–βœ¨

This was vmod_var(3) from the Library Functions Manual β€” go forth and set your variables, you absolute icon. Periodt. πŸ’…πŸ‘‘πŸŒˆ