Provided by:
varnish_1.0.3-2_i386 
NAME
VCL - Varnish Configuration Language
DESCRIPTION
The VCL language is a small domain-specific language designed to be used
to define request handling and document caching policies for the Varnish
HTTP accelerator.
When a new configuration is loaded, the varnishd management process
translates the VCL code to C and compiles it to a shared object which is
then dynamically linked into the server process.
Syntax
The VCL syntax is very simple, and deliberately similar to C and Perl.
Blocks are delimited by curly braces, statements end with semicolons, and
comments may be written as in C, C++ or Perl according to your own
preferences.
In addition to the C-like assignment (=), comparison (==) and boolean (!,
&& and ||) operators, VCL supports regular expression and ACL matching
using the ~ operator.
Unlike C and Perl, the backslash (\) character has no special meaning in
strings in VCL, so it can be freely used in regular expressions without
doubling.
Assignments are introduced with the set keyword. There are no user-
defined variables; values can only be assigned to variables attached to
backend, request or document objects. Most of these are typed, and the
values assigned to them must have a compatible unit suffix.
VCL has if tests, but no loops.
Backend declarations
A backend declaration creates and initializes a named backend object:
backend www {
set backend.host = "www.example.com";
set backend.port = "http";
}
The backend object can later be used to select a backend at request time:
if (req.http.host ~ "^(www.)?example.com$") {
set req.backend = www;
}
ACLs
An ACL declaration creates and initializes a named access control list
which can later be used to match client addresses:
acl local {
"locahost"; /* myself */
"10.0.0.1"/8; /* and everyone on the local network */
! "10.0.0.23"; /* except for the dialin router */
}
If an ACL entry specifies a host name which Varnish is unable to resolve,
it will match any address it is compared to. Consequently, if it is
preceded by a negation mark, it will reject any address it is compared
to, which may not be what you intended. If the entry is enclosed in
parentheses, however, it will simply be ignored.
To match an IP address against an ACL, simply use the match operator:
if (client.ip ~ local) {
pipe;
}
Subroutines
A subroutine is used to group code for legibility or reusability:
sub pipe_if_local {
if (client.ip ~ local) {
pipe;
}
}
Subroutines in VCL do not take arguments, nor do they return values.
To call a subroutine, use the call keyword followed by the subroutine’s
name:
call pipe_if_local;
There are five special subroutines which hook into the Varnish workflow:
vcl_recv Called at the beginning of a request, after the complete
request has been received and parsed. Its purpose is to
decide whether or not to serve the request, how to do it,
and, if applicanle, which backend to use.
vcl_hit Called after a cache lookup if the requested document was
found in the cache.
vcl_miss Called after a cache lookup if the requested document was
not found in the cache. Its purpose is to decide whether or
not to attempt to retrieve the document from the backend,
and which backend to use.
vcl_fetch Called after a document has been retrieved from the backend,
before it is inserted into the cache.
vcl_timeout Called by the reaper thread when a cached document has
reached its expiry time.
If one of these subroutines is left undefined or terminates without
reaching a handling decision, control will be handed over to the builtin
default. See the EXAMPLES section for a listing of the default code.
Variables
Although subroutines take no arguments, the necessary information is made
available to the handler subroutines through global variables.
The following variables are available in backend declarations:
backend.host
Host name or IP address of a backend.
backend.port
Service name or port number of a backend.
The following variables are available while processing a request:
client.ip
The client’s IP address.
req.request
The request type (e.g. "GET", "HEAD").
req.url
The requested URL.
req.proto
The HTTP protocol version used by the client.
req.backend
The backend to use to service the request.
req.http.header
The corresponding header from the HTTP request.
The following variables are available after the requested object has been
retrieved from cache or from the backend:
obj.valid
True if the object was successfully retrieved.
obj.cacheable
True if the object is cacheable.
obj.ttl
The object’s time to live.
EXAMPLES
The following code is the equivalent of the default configuration with
the backend address set to "backend.example.com" and no backend port
specified.
backend default {
set backend.host = "backend.example.com";
set backend.port = "http";
}
sub vcl_recv {
if (req.request != "GET" && req.request != "HEAD") {
pipe;
}
if (req.http.Expect) {
pipe;
}
if (req.http.Authenticate || req.http.Cookie) {
pass;
}
lookup;
}
sub vcl_hit {
if (!obj.cacheable) {
pass;
}
deliver;
}
sub vcl_miss {
fetch;
}
sub vcl_fetch {
if (!obj.valid) {
error;
}
if (!obj.cacheable) {
insert_pass;
}
if (resp.http.Set-Cookie) {
insert_pass;
}
insert;
}
sub vcl_timeout {
discard;
};
The following example shows how to support multiple sites running on
separate backends in the same Varnish instance, by selecting backends
based on the request URL.
backend www {
set backend.host = "www.example.com";
set backend.port = "80";
}
backend images {
set backend.host = "images.example.com";
set backend.port = "80";
}
sub vcl_recv {
if (req.http.host ~ "^(www.)?example.com$") {
set req.backend = www;
} elsif (req.http.host ~ "^images.example.com") {
set req.backend = images;
} else {
error 404 "Unknown virtual host";
}
}
The following snippet demonstrates how to force a minimum TTL for all
documents. Note that this is not the same as setting the default_ttl
run-time parameter, as that only affects document for which the backend
did not specify a TTL.
sub vcl_fetch {
if (obj.ttl < 120s) {
set obj.ttl = 120s;
}
}
The following snippet demonstrates how to force Varnish to cache
documents even when cookies are present.
sub vcl_recv {
if (req.request == "GET" && req.http.cookie) {
lookup;
}
}
sub vcl_fetch {
if (resp.http.Set-Cookie) {
insert;
}
}
The following code implements the HTTP PURGE method as used by Squid for
object invalidation:
acl purge {
"localhost";
"10.0.0.1"/8;
}
sub vcl_recv {
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
lookup;
}
}
sub vcl_hit {
if (req.request == "PURGE") {
set obj.ttl = 0s;
error 200 "Purged.";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
error 404 "Not in cache.";
}
}
SEE ALSO
varnishd(1)
HISTORY
The VCL language was developed by Poul-Henning Kamp 〈phk@phk.freebsd.dk〉
in cooperation with Verdens Gang AS and Linpro AS. This manual page was
written by Dag-Erling Smørgrav 〈des@linpro.no〉.