Various built-in subroutines are called during processing of client- and backend requests as well as upon vcl.load
and vcl.discard
.
See Varnish Processing States for a detailed graphical overview of the states and how they relate to core code functions and VCL subroutines.
Built-in subroutines always terminate with a return (<action>)
, where <action>
determines how processing continues in the request processing state machine.
The behaviour of actions is identical or at least similar across subroutines, so differences are only documented where relevant.
Common actions are documented in Actions. Actions specific to only one or some subroutines are documented herein.
Called at the beginning of a request, after the complete request has been received and parsed, after a restart
or as the result of an ESI include.
Its purpose is to decide whether or not to serve the request, possibly modify it and decide on how to process it further. A backend hint may be set as a default for the backend processing side.
The vcl_recv
subroutine may terminate with calling return()
on one of the following keywords:
fail
see fail
synth(status code, reason)
restart
see restart
pass
see pass
pipe
see pipe
hash
Continue processing the object as a potential candidate for caching. Passes the control over to vcl_hash.
purge
Purge the object and it’s variants. Control passes through vcl_hash to vcl_purge.
vcl(label)
Switch to vcl labelled label.
This will roll back the request as if std.rollback(req)
was called and continue vcl processing in vcl_recv of the vcl labelled label as if it was the active vcl.
The vcl(label)
return is only valid while the req.restarts
count is zero and if used from the active vcl.
See the vcl.label <label> <configname> command.
Called upon entering pipe mode. In this mode, the request is passed on to the backend, and any further data from both the client and backend is passed on unaltered until either end closes the connection. Basically, Varnish will degrade into a simple TCP proxy, shuffling bytes back and forth. For a connection in pipe mode, no other VCL subroutine will ever get called after vcl_pipe
.
The vcl_pipe
subroutine may terminate with calling return()
with one of the following keywords:
fail
see fail
synth(status code, reason)
pipe
Proceed with pipe mode.
Called upon entering pass mode. In this mode, the request is passed on to the backend, and the backend’s response is passed on to the client, but is not entered into the cache. Subsequent requests submitted over the same client connection are handled normally.
The vcl_pass
subroutine may terminate with calling return()
with one of the following keywords:
fail
see fail
synth(status code, reason)
restart
see restart
fetch
Proceed with pass mode - initiate a backend request.
Called after vcl_recv
to create a hash value for the request. This is used as a key to look up the object in Varnish.
The vcl_hash
subroutine may terminate with calling return()
with one of the following keywords:
fail
see fail
lookup
Look up the object in cache.
Control passes to vcl_purge when coming from a purge
return in vcl_recv
.
Otherwise control passes to the next subroutine depending on the result of the cache lookup:
Called after the purge has been executed and all its variants have been evicted.
The vcl_purge
subroutine may terminate with calling return()
with one of the following keywords:
Called after a cache lookup if the requested document was not found in the cache or if vcl_hit returned fetch
.
Its purpose is to decide whether or not to attempt to retrieve the document from the backend. A backend hint may be set as a default for the backend processing side.
The vcl_miss
subroutine may terminate with calling return()
with one of the following keywords:
fail
see fail
synth(status code, reason)
restart
see restart
pass
see pass
fetch
Retrieve the requested object from the backend. Control will eventually pass to vcl_backend_fetch
.
Called when a cache lookup is successful. The object being hit may be stale: It can have a zero or negative ttl
with only grace
or keep
time left.
The vcl_hit
subroutine may terminate with calling return()
with one of the following keywords:
fail
see fail
synth(status code, reason)
restart
see restart
pass
see pass
deliver
Deliver the object. If it is stale, a background fetch to refresh it is triggered.
Called before any object except a vcl_synth
result is delivered to the client.
The vcl_deliver
subroutine may terminate with calling return()
with one of the following keywords:
fail
see fail
synth(status code, reason)
restart
see restart
deliver
Deliver the object to the client.
Called to deliver a synthetic object. A synthetic object is generated in VCL, not fetched from the backend. Its body may be constructed using the synthetic()
function.
A vcl_synth
defined object never enters the cache, contrary to a vcl_backend_error defined object, which may end up in cache.
The subroutine may terminate with calling return()
with one of the following keywords:
fail
see fail
restart
see restart
deliver
Directly deliver the object defined by vcl_synth
to the client without calling vcl_deliver
.
Called before sending the backend request. In this subroutine you typically alter the request before it gets to the backend.
The vcl_backend_fetch
subroutine may terminate with calling return()
with one of the following keywords:
fail
see fail
abandon
see abandon
fetch
Fetch the object from the backend.
error(status code, reason)
Transition to vcl_backend_error with beresp.status
and beresp.reason
being preset to the arguments of error()
if arguments are provided.
Before calling vcl_backend_fetch
, Varnish core prepares the bereq
backend request as follows:
Unless the request is a pass
,
bereq.method
to GET
and bereq.proto
to HTTP/1.1
andbereq.http.Accept_Encoding
to gzip
if http_gzip_support is enabled.bereq.http.If-Modified-Since
from its Last-Modified
header and/or set bereq.http.If-None-Match
from its Etag
headerbereq.http.X-Varnish
to the current transaction id (vxid
)These changes can be undone or modified in vcl_backend_fetch
before the backend request is issued.
In particular, to cache non-GET requests, req.method
needs to be saved to a header or variable in vcl_recv and restored to bereq.method
. Notice that caching non-GET requests typically also requires changing the cache key in vcl_hash e.g. by also hashing the request method and/or request body.
HEAD request can be satisfied from cached GET responses.
Called after the response headers have been successfully retrieved from the backend.
The vcl_backend_response
subroutine may terminate with calling return()
with one of the following keywords:
fail
see fail
abandon
see abandon
deliver
For a 304 response, create an updated cache object. Otherwise, fetch the object body from the backend and initiate delivery to any waiting client requests, possibly in parallel (streaming).
retry
Retry the backend transaction. Increases the retries
counter. If the number of retries is higher than max_retries, control will be passed to vcl_backend_error.
pass(duration)
Mark the object as a hit-for-pass for the given duration. Subsequent lookups hitting this object will be turned into passed transactions, as if vcl_recv
had returned pass
.
error(status code, reason)
Transition to vcl_backend_error with beresp.status
and beresp.reason
being preset to the arguments of error()
if arguments are provided.
For a 304 response, Varnish core code amends beresp
before calling vcl_backend_response
:
Content-Encoding
is unset and any Etag
is weakenedContent-Length
is copied if present in the existing cache object and discarded otherwise.beresp.was_304
marks that this conditional response processing has happened.
Note: Backend conditional requests are independent of client conditional requests, so clients may receive 304 responses no matter if a backend request was conditional.
Before calling vcl_backend_response
, core code sets beresp.ttl
based on the response status and the response headers Age
, Cache-Control
or Expires
and Date
as follows:
Age
header is effectively deduced from all ttl calculations.For status codes 200, 203, 204, 300, 301, 304, 404, 410 and 414:
Cache-Control
contains an s-maxage
or max-age
field (in that order of preference), the ttl is set to the respective non-negative value or 0 if negative.Expires
header exists, the default ttl is used.Expires
contains a time stamp before Date
, the ttl is set to 0.Otherwise, if no Date
header is present or the Date
header timestamp differs from the local clock by no more than the clock_skew
parameter, the ttl is set to
Expires
denotes a past timestamp orExpires
header otherwise.Expires
and Date
Cache-Control
nor Expires
exists.beresp.grace
defaults to the default_grace
parameter.
For a non-negative ttl, if Cache-Control
contains a stale-while-revalidate
field value, beresp.grace
is set to that value if non-negative or 0 otherwise.
beresp.keep
defaults to the default_keep
parameter.
This subroutine is called if we fail the backend fetch or if max_retries has been exceeded.
Returning with abandon does not leave a cache object.
If returning with deliver
and a beresp.ttl > 0s
, a synthetic cache object is generated in VCL, whose body may be constructed using the synthetic()
function.
When there is a waiting list on the object, the default ttl
will be positive (currently one second), set before entering vcl_backend_error
. This is to avoid request serialization and hammering on a potentially failing backend.
Since these synthetic objects are cached in these special circumstances, be cautious with putting private information there. If you really must, then you need to explicitly set beresp.ttl
to zero in vcl_backend_error
.
The vcl_backend_error
subroutine may terminate with calling return()
with one of the following keywords:
fail
see fail
abandon
see abandon
deliver
Deliver and possibly cache the object defined in vcl_backend_error
as if it was fetched from the backend, also referred to as a “backend synth”.
retry
Retry the backend transaction. Increases the retries
counter. If the number of retries is higher than max_retries, vcl_synth on the client side is called with resp.status
preset to 503.
Called when VCL is loaded, before any requests pass through it. Typically used to initialize VMODs.
The vcl_init
subroutine may terminate with calling return()
with one of the following keywords:
ok
Normal return, VCL continues loading.
fail
Abort loading of this VCL.
Called when VCL is discarded only after all requests have exited the VCL. Typically used to clean up VMODs.
The vcl_fini
subroutine may terminate with calling return()
with one of the following keywords:
ok
Normal return, VCL will be discarded.
Copyright © 2006 Verdens Gang AS
Copyright © 2006–2020 Varnish Software AS
Licensed under the BSD-2-Clause License.
https://varnish-cache.org/docs/6.5/users-guide/vcl-built-in-subs.html