LOG IN SIGN UP
Documentation

Miscellaneous VCL extensions

  Last updated November 08, 2017

Fastly has added several miscellaneous features to Varnish that don't easily fit into specific categories.

Variables

Variable Description
bereq.url The URL sent to the backend. Does not include the host and scheme, meaning in www.example.com/index.html, bereq.url would contain /index.html.
bereq.url.qs The query string portion of bereq.url. This will be from immediately after the ? to the end of the URL.
bereq.url.basename Same as req.url.basename, except for use between Fastly and your origin servers.
bereq.url.dirname Same as req.url.dirname, except for use between Fastly and your origin servers.
beresp.backend.ip The IP of the backend this response was fetched from (backported from Varnish 3).
beresp.backend.name The name of the backend this response was fetched from (backported from Varnish 3).
beresp.backend.port The port of the backend this response was fetched from (backported from Varnish 3).
beresp.grace Defines how long an object can remain overdue and still have Varnish consider it for grace mode. Fastly has implemented stale-if-error as a parallel implementation of beresp.grace.
beresp.pci Specifies that content be cached in a manner that satisfies PCI DSS requirements. See our PCI compliance description for instructions on enabling this feature for your account.
beresp.hipaa Specifies that content not be cached in non-volatile memory to help customers meet HIPAA security requirements. See our guide on HIPAA and caching PHI for instructions on enabling this feature for your account. An alias of beresp.pci.
client.port Returns the remote client port. This could be useful as a seed that returns the same value both in an ESI and a top level request. For example, you could hash client.ip and client.port to get a value used both in ESI and the top level request.
req.grace Defines how long an object can remain overdue and still have Varnish consider it for grace mode.
req.http.host The full host name, without the path or query parameters. For example, in the request www.example.com/index.html?a=1&b=2, req.http.host will return www.example.com.
req.is_ipv6 Indicates whether the request was made using IPv6 or not. This is a boolean, read-only variable available in vcl_recv, vcl_hash, vcl_deliver and vcl_log.
req.restarts Counts the number of times the VCL has been restarted.
req.topurl In an ESI subrequest, returns the URL of the top-level request.
req.url.basename The file name specified in a URL. For example, in the request www.example.com/1/hello.gif?foo=bar, req.url.basename will return hello.gif.
req.url.dirname The directories specified in a URL. For example, in the request www.example.com/1/hello.gif?foo=bar, req.url.dirname will return /1. In the request www.example.com/5/inner/hello.gif?foo=bar, req.url.dirname will return /5/inner.
req.url.ext The file extension specified in a URL. For example, in the request www.example.com/1/hello.gif?foo=bar, req.url.ext will return gif.
req.url.path The full path, without any query parameters. For example, in the request www.example.com/index.html?a=1&b=2, req.url.path will return /index.html.
req.url The full path, including query parameters. For example, in the request www.example.com/index.html?a=1&b=2, req.url will return /index.html?a=1&b=2.
req.url.qs The query string portion of req.url. This will be from immediately after the ? to the end of the URL.
stale.exists Specifies if a given object has stale content in cache. Returns TRUE or FALSE.

Functions

Function Format Description
boltsort.sort STRING boltsort.sort(STRING url) Sorts URL parameters. For example, boltsort.sort("/foo?b=1&a=2&c=3"); returns "/foo?a=2&b=1&c=3".

Example:

set req.url = boltsort.sort(req.url);
cstr_escape STRING cstr_escape(STRING cstr) Escapes characters unsafe for printing from a string. For example, " becomes \".

Example:

log "escaped=" cstr_escape("%22" req.protocol "%22")
http_status_matches BOOL http_status_matches(INT status, STRING fmt) Determines whether or not an HTTP status code matches a pattern. The arguments are an integer (usually beresp.status or resp.status) and a comma-separated list of status codes, optionally prefixed by a ! to negate the match. It returns TRUE or FALSE. For example, if (http_status_matches(beresp.status, "!200,404")) {.

Example:

if (http_status_matches(beresp.status, "!200,301,302")) { set obj.cacheable = 0; }
if() STRING if(BOOL expression, STRING valueiftrue, STRING valueiffalse) Implements a ternary operator for strings; if the expression is true, it returns TRUE; if the expression is false, it returns FALSE. For example, you have an if(x, true-expression, false-expression); if this argument is true, the true-expression is returned. Otherwise, the false-expression is returned. See the example for more information.
std.atoi INTEGER std.atoi(STRING s) Takes a string (which represents an integer) as an argument and returns its value.

Example:

if (std.atoi(req.http.X-Decimal) == 42) { set req.http.X-TheAnswer = "Found"; }
std.strstr STRING std.strstr(STRING haystack, STRING needle) Finds the first occurrence of a byte string and returns its value.

Example:

set req.http.X-qs = std.strstr(req.url, "?");
std.strtol INTEGER std.strtol(STRING s, UINT base) Converts a string to an integer, using the second argument as base. Base can be 2 to 36, or 0. A 0 base means that base 10 (decimal) is used, unless the string has a 0x or 0 prefix, in which case base 16 (hexadecimal) and base 8 (octal) are used respectively. For example, std.strtol("0xa0", 0) will return 160.

Example:

if (std.strtol(req.http.X-HexValue, 16) == 42) { set req.http.X-TheAnswer = "Found"; }
std.tolower STRING std.tolower(STRING_LIST s) Changes the case of a string to lower case. For example, std.tolower("HELLO"); will return "hello".

Example:

set beresp.http.x-nice = std.tolower("VerY");
std.toupper STRING std.toupper(STRING_LIST s) Changes the case of a string to upper case. For example, std.toupper("hello"); will return "HELLO".

Example:

set beresp.http.x-scream = std.toupper("yes!");
std.str2ip IP std.str2ip(STRING addr, STRING fallback) Converts the string address to an IP address (v4 or v6). For example, if (std.str2ip("192.0.2.1", "192.0.2.2") ~ my_acl) { where 192.0.2.2 is the fallback. If conversion fails, the fallback will be returned. Note that only the first result from DNS resolution is returned.
std.ip IP std.ip(STRING addr, STRING fallback) An alias of std.str2ip.
std.ip2str STRING std.ip2str(IP ip) Converts the IP address (v4 or v6) to a string.

Example:

if (std.ip2str(std.str2ip("192.0.2.1", "192.0.2.2")) == "192.0.2.1")) {
std.strlen INTEGER std.strlen(STRING s) Returns the length of the string. For example, std.strlen("Hello world!"); will return 12 (because the string includes whitespaces and punctuation).

Example:

if (std.strlen(req.http.Cookie > 1024)) { unset req.http.Cookie; }
urlencode STRING urlencode(STRING input) Encodes a string for use in a URL. This is also known as percent-encoding. For example, urlencode("hello world"); will return "hello%20world".

Example:

set req.url = req.url "?cookie=" urlencode(req.http.Cookie);
urldecode STRING urldecode(STRING input) Decodes a percent-encoded string. For example, urldecode({"hello%20world+!"}); and urldecode("hello%2025world+!"); will both return "hello world !"

Example:

set req.http.X-Cookie = regsub(req.url, ".*\?cookie=", ""); set req.http.Cookie = urldecode(req.http.X-Cookie);

Miscellaneous Features

Feature Description
goto Performs a one-way transfer of control to another line of code. See the example for more information.
return Returns (with no return value) from a custom subroutine to exit early. See the example for more information.

Examples

Use the following examples to learn how to implement the features.

Goto

Similar to some programming languages, goto statements in VCL allow you perform a one-way transfer of control to another line of code. When using goto, jumps must always be forward, rather than to an earlier part of code.

This act of "jumping" allows you to do things like perform logical operations or set headers before returning lookup, error, or pass actions. These statements also make it easier to do things like jump to common error handling blocks before returning from a function. The goto statement works in custom subroutines.

sub vcl_recv {
  if (!req.http.Foo) {
    goto foo;
  }

foo:
  set req.http.Foo = "1";
}

Return

You can use return to exit early from a custom subroutine.

sub custom_subroutine {
  if (req.http.Cookie:user_id) {
    return;
  }

  # do a bunch of other stuff
}

If

You can use if() as a construct to make simple conditional expressions more concise.

set req.http.foo-status = if(req.http.foo, "present", "absent");

Back to Top