VCL-steps
Built-in subroutines
- Manual section: 7
DESCRIPTION
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 VCL Actions in the next section. Actions specific to only one or some subroutines are documented in VCL Steps.
A default behavior is provided for all Varnish Processing States in the Built-in VCL code.
VCL Actions
Actions are used with the return(<action>) keyword, which returns
control from subroutines back to varnish. The action determines how
processing in varnish continues as shown in Varnish Processing States.
Common actions are documented here, while additional actions specific to only one or some subroutines are documented in the next section VCL Steps as well as which action can be used from which built in subroutine.
Common actions for the client and backend side
fail(err)
Transition to vcl_synth on the client side as for
return(synth(503, "VCL Failed")), but with any request state changes undone as ifstd.rollback()was called and forcing a connection close. The optional string argument err is logged to VSL under a VCL_Error tag.
Returning fail from vcl_synth sends a minimal response with a 500 status.
Intended for fatal errors, for which only minimal error handling is possible.
Common actions for the client side
synth(status code, reason)
Transition to vcl_synth with
resp.statusandresp.reasonbeing preset to the arguments ofsynth().
pass
Switch to pass mode, making the current request not use the cache and not putting its response into it. Control will eventually pass to vcl_pass.
pipe
Switch to pipe mode. Control will eventually pass to vcl_pipe.
restart
Restart the transaction. Increases the
req.restartscounter.
If the number of restarts is higher than the max_restarts parameter, control is passed to vcl_synth as for
return(synth(503, "Too many restarts"))
For a restart, all modifications to
reqattributes are preserved except forreq.restartsandreq.xid, which need to change by design.
Common actions for the backend side
abandon
Abandon the backend request. Unless the backend request was a background fetch, control is passed to vcl_synth on the client side with
resp.statuspreset to 503.
VCL Steps
Client side
vcl_recv
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(err)see fail(err) section above
synth(status code, reason)see synth(status code, reason) section above
restartsee restart section above
passsee pass section above
pipesee pipe section above
hashContinue processing the object as a potential candidate for
caching. Passes the control over to vcl_hash.
purgePurge the object and it’s variants. Control passes through
vcl(label)Switch to vcl labelled label.
This will roll back the request as if
std.rollback(req)wascalled 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 thereq.restartscount is zero and if used from the active vcl.
See the vcl.label command in varnish-cli.
vcl_pipe
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(err)see fail(err) section above
synth(status code, reason)see synth(status code, reason) section above
pipeProceed with pipe mode.
vcl_pass
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(err)see fail(err) section above
synth(status code, reason)see synth(status code, reason) section above
restartsee restart section above
fetchProceed with pass mode - initiate a backend request.
vcl_hash
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(err)see fail(err) section above
lookupLook up the object in cache.
Control passes to vcl_purge when coming from a
purgereturn in vcl_recv.
Otherwise control passes to the next subroutine depending on the
result of the cache lookup:
* a hit: pass to vcl_hit
* a miss or a hit on a hit-for-miss object (an object with
obj.uncacheable == true): pass to vcl_miss* a hit on a hit-for-pass object (for which
pass(DURATION)had beenpreviously returned from
vcl_backend_response): pass to
vcl_purge
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:
fail(err)see fail(err) section above
synth(status code, reason)see synth(status code, reason) section above
restartsee restart section above
vcl_miss
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(err)see fail(err) section above
synth(status code, reason)see synth(status code, reason) section above
restartsee restart section above
passsee pass section above
fetchRetrieve the requested object from the backend. Control will
eventually pass to vcl_backend_fetch.
vcl_hit
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(err)see fail(err) section above
synth(status code, reason)see synth(status code, reason) section above
restartsee restart section above
passsee pass section above
deliverDeliver the object. If it is stale, a background fetch to refresh
it is triggered.
vcl_deliver
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(err)see fail(err) section above
synth(status code, reason)see synth(status code, reason) section above
restartsee restart section above
deliverDeliver the object to the client.
vcl_synth
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(err)see fail(err) section above
restartsee restart section above
deliverDirectly deliver the object defined by vcl_synth to the client
without calling vcl_deliver.
Backend Side
vcl_backend_fetch
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(err)see fail(err) section above
abandonsee abandon section above
fetchFetch the object from the backend.
error(status code, reason)Transition to vcl_backend_error with
beresp.statusand
beresp.reasonbeing preset to the arguments oferror()ifarguments are provided.
Before calling vcl_backend_fetch, Varnish core prepares the bereq backend request as follows:
- Unless the request is a pass,
- set
bereq.methodtoGETandbereq.prototoHTTP/1.1and - set
bereq.http.Accept_Encodingtogzipif http_gzip_support is enabled.
- set
- If there is an existing cache object to be revalidated, set
bereq.http.If-Modified-Sincefrom itsLast-Modifiedheader and/or setbereq.http.If-None-Matchfrom itsEtagheader - Set
bereq.http.X-Varnishto 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.
vcl_backend_refresh
This subroutine is called after a legitimate 304 response is received from the backend so that you can chose how to handle the object revalidation.
The default is to apply the RFC logic which is to merge the new headers with the stale ones.
The returned value only affects response headers, the body that is delivered is always the one from the stale object.
See vcl_refresh_* for additional explanations.
mergeMerge the headers we got from the backend response with
the ones we had in the cached object.
obj_staleReturn the stale object’s headers without performing the RFC merge logic.
berespReturn the beresp headers as they were at the end of this subroutine
without executing the RFC merge logic. Any content-length and
content-encoding headers present in the 304 beresp will be removed and
replaced by the stale object ones if available. Etag and Last-Modified
headers are also copied from the stale object to allow future revalidations.
failsee fail(err) section above
abandonsee abandon section above
retryRetry 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.
error(status code, reason)Transition to vcl_backend_error with
beresp.statusand
beresp.reasonbeing preset to the arguments oferror()ifarguments are provided.
vcl_backend_response
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(err)see fail(err) section above
abandonsee abandon section above
deliverFor 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).
retryRetry 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_recvhad returnedpass.
error(status code, reason)Transition to vcl_backend_error with
beresp.statusand
beresp.reasonbeing preset to the arguments oferror()ifarguments are provided.
vcl_backend_error
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 beresp.uncacheable == false, a
synthetic cache object is generated in VCL, whose body may be constructed
using the synthetic() function.
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.uncacheable to true in
vcl_backend_error.
The vcl_backend_error subroutine may terminate with calling return()
with one of the following keywords:
fail(err)see fail(err) section above
abandonsee abandon section above
deliverDeliver 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”.
retryRetry 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.statuspreset to 503.
During vcl.load / vcl.discard
vcl_init
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:
okNormal return, VCL continues loading.
fail(err)Abort loading of this VCL.
vcl_fini
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:
okNormal return, VCL will be discarded.
SEE ALSO
COPYRIGHT
This document is licensed under the same license as Varnish itself. See LICENSE for details.
- Copyright (c) 2006 Verdens Gang AS
- Copyright (c) 2006-2021 Varnish Software AS