Varnish Live

Example VCL

Varnish Live needs access Varnish Custom Statistics to fetch time series data. One way to expose Varnish Custom Statistics securely to the Internet is to have Hitch and Varnish in front of it.

The following is an example VCL that can be used to access a VCS endpoint via Varnish on a custom URL. The example VCL also contains the VCS key (vcs-key) that is used by Varnish Custom Statistics to create the time series.

vcl 4.1;
import std;

backend vcs {
    .host = "192.168.0.1";
    .port = "6555";
}

sub vcl_recv {
    set req.http.X-Forwarded-Host = req.http.host;
    set req.http.X-Forwarded-URL = req.url;

    if (req.url == "^/varnish-live/") {
        if (req.method == "OPTIONS") {
            return (synth(200));
        }
    
        # Optional: Simple implementation of basic authentication in 
        # VCL with base64 encoding. The example below is requires the
        # username user and password changeme.
        #
        # New credentials can be generated on the command line using:
        #
        #     $ echo -n "username:password" | base64 
        #     dXNlcm5hbWU6cGFzc3dvcmQ=
        #
        if (req.http.Authorization != "Basic dXNlcjpjaGFuZ2VtZQ==") {
            return (synth(401));
        }
    
        # Optional: Allow only the request methods that are needed
        # by the app.
        if (req.method != "GET" && req.method != "HEAD") {
            return (synth(405));
        }
    
        # Map the URL to specific VCS keys.
        # Each VCS key is one data source in the Varnish Live app.
        # 
        if (req.url == "/varnish-live/edge.json") {
            set req.url = "/key/EDGE";
        } else {
            return(synth(404));
        }

        ## The following is an example of a more complex URL to VCS key
        ## mapping, with four different VCS keys being used.
        #if (req.url == "/varnish-live/vod-edge.json") {
        #    set req.url = "/key/VOD-EDGE";
        #} else if (req.url == "/varnish-live/vod-storage.json") {
        #    set req.url = "/key/VOD-STORAGE";
        #} else if (req.url == "/varnish-live/live-edge.json") {
        #    set req.url = "/key/LIVE-EDGE";
        #} else if (req.url == "/varnish-live/live-storage.json") {
        #    set req.url = "/key/LIVE-STORAGE";
        #} else {
        #    return(synth(404));
        #}

        # Optional: Remove authorization header, or adjust to match
        # the requirements of the VCS server if any.
        unset req.http.Authorization;

        unset req.http.Cookie;
        set req.backend_hint = vcs;
    }

    # Performance measurements.
    # The transactions that hit the line below will be part of the
    # performance measurements and aggregated with the key EDGE. More keys
    # can be created.
    std.log("vcs-key:EDGE");

    # A string which is unique per user. Assuming the combination of client
    # IP, user-agent and referer header is unique per user in this example:
    std.log("vcs-unique-id:" + client.ip + "/" + req.http.user-agent + "/" + req.http.referer);
}

sub vcl_backend_response {
    if (bereq.http.X-Forwarded-URL ~ "^/varnish-live/") {
        set beresp.grace = 1s;
        set beresp.ttl = 1s;
        set beresp.http.Cache-Control = "max-age=1";
    }
}

# CORS to control requests from Javascript
sub cors {
    if (req.http.X-Forwarded-URL ~ "^/varnish-live/") {
        set resp.http.Access-Control-Allow-Origin = "*";
        set resp.http.Access-Control-Allow-Methods = "OPTIONS, GET";
        set resp.http.Access-Control-Allow-Headers = "Authorization";
    }
}

sub vcl_synth {
    call cors;
}

sub vcl_deliver {
    call cors;
}