vmod_std¶
Varnish Standard Module¶
- Manual section:
3
SYNOPSIS¶
import std [from "path"] ;
STRING toupper(STRING s)
STRING tolower(STRING s)
VOID set_ip_tos(INT tos)
REAL random(REAL lo, REAL hi)
VOID log(STRING s)
VOID syslog(INT priority, STRING s)
STRING fileread(STRING)
BOOL file_exists(STRING path)
VOID collect(HEADER hdr, STRING sep)
DURATION duration(STRING s, DURATION fallback)
INT integer(STRING s, INT fallback)
IP ip(STRING s, IP fallback, BOOL resolve, STRING p)
REAL real(STRING s, REAL fallback)
INT real2integer(REAL r, INT fallback)
TIME real2time(REAL r, TIME fallback)
INT time2integer(TIME t, INT fallback)
REAL time2real(TIME t, REAL fallback)
BOOL healthy(BACKEND be)
INT port(IP ip)
VOID rollback(HTTP h)
VOID timestamp(STRING s)
STRING querysort(STRING)
BOOL cache_req_body(BYTES size)
STRING strstr(STRING s1, STRING s2)
TIME time(STRING s, TIME fallback)
STRING getenv(STRING name)
VOID late_100_continue(BOOL late)
BOOL syntax(REAL)
BOOL fnmatch(STRING pattern, STRING subject, BOOL pathname, BOOL noescape, BOOL period)
CONTENTS¶
DESCRIPTION¶
vmod_std contains basic functions which are part and parcel of Varnish, but which for reasons of architecture fit better in a VMOD.
One particular class of functions in vmod_std is the conversions functions which all have the form:
TYPE type(STRING, TYPE)
These functions attempt to convert STRING to the TYPE, and if that fails, they return the second argument, which must have the given TYPE.
STRING toupper(STRING s)¶
- Description
Converts the string s to uppercase.
- Example
set beresp.http.scream = std.toupper(“yes!”);
STRING tolower(STRING s)¶
- Description
Converts the string s to lowercase.
- Example
set beresp.http.nice = std.tolower(“VerY”);
VOID set_ip_tos(INT tos)¶
- Description
Sets the IP type-of-service (TOS) field for the current session to tos. Silently ignored if the listen address is a Unix domain socket. Please note that the TOS field is not removed by the end of the request so probably want to set it on every request should you utilize it.
- Example
- if (req.url ~ “^/slow/”) {std.set_ip_tos(0);}
REAL random(REAL lo, REAL hi)¶
- Description
Returns a random real number between lo and hi. This function uses the “testable” random generator in varnishd which enables determinstic tests to be run (See m00002.vtc). This function should not be used for cryptographic applications.
- Example
set beresp.http.random-number = std.random(1, 100);
VOID log(STRING s)¶
- Description
Logs the string s to the shared memory log, using VSL tag SLT_VCL_Log.
- Example
std.log(“Something fishy is going on with the vhost “ + req.http.host);
VOID syslog(INT priority, STRING s)¶
- Description
Logs the string s to syslog tagged with priority. priority is formed by ORing the facility and level values. See your system’s syslog.h file for possible values.
Notice: Unlike VCL and other functions in the std vmod, this function will not fail VCL processing for workspace overflows: For an out of workspace condition, the
syslog()
function has no effect.- Example
std.syslog(9, “Something is wrong”);
This will send a message to syslog using LOG_USER | LOG_ALERT.
STRING fileread(STRING)¶
- Description
Reads a file and returns a string with the content. The result is cached indefinitely per filename.
- Example
synthetic(“Response was served by “ + std.fileread(“/etc/hostname”));
Consider that the entire contents of the file appear in the string
that is returned, including newlines that may result in invalid
headers if std.fileread()
is used to form a header. In that case,
you may need to modify the string, for example with regsub()
:
set beresp.http.served-by = regsub(std.fileread("/etc/hostname"), "\R$", "");
BOOL file_exists(STRING path)¶
- Description
Returns true if path or the file pointed to by path exists, false otherwise.
- Example
- if (std.file_exists(“/etc/return_503”)) {return (synth(503, “Varnish is in maintenance”));}
VOID collect(HEADER hdr, STRING sep=”, “)¶
- Description
Collapses multiple hdr headers into one long header. The default separator sep is the standard comma separator to use when collapsing headers, with an additional whitespace for pretty printing.
Care should be taken when collapsing headers. In particular collapsing Set-Cookie will lead to unexpected results on the browser side.
- Examples
- std.collect(req.http.accept);std.collect(req.http.cookie, “; “);
DURATION duration(STRING s, DURATION fallback)¶
- Description
Converts the string s to seconds. s must be quantified with ms (milliseconds), s (seconds), m (minutes), h (hours), d (days), w (weeks) or y (years) units. If conversion fails, fallback will be returned.
- Example
set beresp.ttl = std.duration(“1w”, 3600s);
INT integer(STRING s, INT fallback)¶
- Description
Converts the string s to an integer. If conversion fails, fallback will be returned.
- Example
- if (std.integer(req.http.foo, 0) > 5) {…}
IP ip(STRING s, IP fallback, BOOL resolve=1, STRING p=”80”)¶
- Description
Converts the string s to the first IP number returned by the system library function getaddrinfo(3). If conversion fails, fallback will be returned or VCL failure will happen.
The IP address includes a port number that can be found with
std.port()
that defaults to 80. The default port can be set to a different value with the p argument. It will be overriden if s contains both an IP address and a port number or service name.When s contains both, the syntax is either
address:port
oraddress port
. If the address is a numerical IPv6 address it must be enclosed between brackets, for example[::1] 80
or[::1]:http
. The fallback may also contain both an address and a port, but its default port is always 80.If resolve is false, getaddrinfo(3) is called using
AI_NUMERICHOST
andAI_NUMERICSERV
to avoid network lookups depending on the system’s getaddrinfo(3) or nsswitch configuration. This makes “numerical” IP strings and services cheaper to convert.- Example
- if (std.ip(req.http.X-forwarded-for, “0.0.0.0”) ~ my_acl) {…}
REAL real(STRING s, REAL fallback)¶
- Description
Converts the string s to a real. If conversion fails, fallback will be returned.
- Example
- if (std.real(req.http.foo, 0.0) > 5.5) {…}
INT real2integer(REAL r, INT fallback)¶
- Description
Rounds the real r to the nearest integer, but round halfway cases away from zero (see round(3)). If conversion fails, fallback will be returned.
- Example
set req.http.integer = std.real2integer(1140618699.00, 0); set req.http.posone = real2integer( 0.5, 0); # = 1.0 set req.http.negone = real2integer(-0.5, 0); # = -1.0
TIME real2time(REAL r, TIME fallback)¶
- Description
Rounds the real r to the nearest integer (see func_real2integer) and returns the corresponding time when interpreted as a unix epoch. If conversion fails, fallback will be returned.
- Example
set req.http.time = std.real2time(1140618699.00, now);
INT time2integer(TIME t, INT fallback)¶
- Description
Converts the time t to a integer. If conversion fails, fallback will be returned.
- Example
set req.http.int = std.time2integer(now, 0);
REAL time2real(TIME t, REAL fallback)¶
- Description
Converts the time t to a real. If conversion fails, fallback will be returned.
- Example
set req.http.real = std.time2real(now, 1.0);
BOOL healthy(BACKEND be)¶
- Description
Returns true if the backend be is healthy.
INT port(IP ip)¶
- Description
Returns the port number of the IP address ip. Always returns 0 for a
*.ip
variable whose value is0.0.0.0
because the listen address is a Unix domain socket.
VOID rollback(HTTP h)¶
- Description
Restores the h HTTP headers to their original state.
- Example
std.rollback(bereq);
VOID timestamp(STRING s)¶
- Description
Introduces a timestamp in the log with the current time, using the string s as the label. This is useful to time the execution of lengthy VCL procedures, and makes the timestamps inserted automatically by Varnish more accurate.
- Example
std.timestamp(“curl-request”);
STRING querysort(STRING)¶
- Description
Sorts the query string for cache normalization purposes.
- Example
set req.url = std.querysort(req.url);
BOOL cache_req_body(BYTES size)¶
- Description
Caches the request body if it is smaller than size. Returns true if the body was cached, false otherwise.
Normally the request body is not available after sending it to the backend. By caching it is possible to retry pass operations, e.g. POST and PUT.
- Example
- if (std.cache_req_body(1KB)) {…}
STRING strstr(STRING s1, STRING s2)¶
- Description
Returns a string beginning at the first occurrence of the string s2 in the string s1, or an empty string if s2 is not found.
Note that the comparison is case sensitive.
- Example
- if (std.strstr(req.url, req.http.restrict)) {…}
This will check if the content of req.http.restrict occurs anywhere in req.url.
TIME time(STRING s, TIME fallback)¶
- Description
Converts the string s to a time. If conversion fails, fallback will be returned.
Supported formats:
“Sun, 06 Nov 1994 08:49:37 GMT”“Sunday, 06-Nov-94 08:49:37 GMT”“Sun Nov 6 08:49:37 1994”“1994-11-06T08:49:37”“784111777.00”“784111777”- Example
- if (std.time(resp.http.last-modified, now) < now - 1w) {…}
STRING getenv(STRING name)¶
- Description
Return environment variable name or the empty string.
See getenv(3)
- Example
- set req.http.My-Env = std.getenv(“MY_ENV”);
VOID late_100_continue(BOOL late)¶
- Description
Controls when varnish reacts to an Expect: 100-continue client request header.
Varnish always generates a 100 Continue response if requested by the client trough the Expect: 100-continue header when waiting for request body data.
But, by default, the 100 Continue response is already generated immediately after vcl_recv returns to reduce latencies under the assumption that the request body will be read eventually.
Calling std.late_100_continue(true) in vcl_recv will cause the 100 Continue response to only be sent when needed. This may cause additional latencies for processing request bodies, but is the correct behavior by strict interpretation of RFC7231.
This function has no effect outside vcl_recv and after calling std.cache_req_body() or any other function consuming the request body.
- Example
- vcl_recv {std.late_100_continue(true);if (req.method == “POST”) {std.late_100_continue(false);return (pass);}…}
BOOL syntax(REAL)¶
- Description
Returns the true if VCL version is at least REAL.
fnmatch(…)¶
BOOL fnmatch(
STRING pattern,
STRING subject,
BOOL pathname=1,
BOOL noescape=0,
BOOL period=0
)
- Description
Shell-style pattern matching; returns true if subject matches pattern, where pattern may contain wildcard characters such as * or ?.
The match is executed by the implementation of fnmatch(3) on your system. The rules for pattern matching on most systems include the following:
* matches any sequence of characters
? matches a single character
a bracket expression such as [abc] or [!0-9] is interpreted as a character class according to the rules of basic regular expressions (not PCRE regexen), except that ! is used for character class negation instead of ^.
If pathname is true, then the forward slash character / is only matched literally, and never matches *, ? or a bracket expression. Otherwise, / may match one of those patterns. By default, pathname is true.
If noescape is true, then the backslash character \ is matched as an ordinary character. Otherwise, \ is an escape character, and matches the character that follows it in the pattern. For example, \\ matches \ when noescape is true, and \\ when false. By default, noescape is false.
If period is true, then a leading period character . only matches literally, and never matches *, ? or a bracket expression. A period is leading if it is the first character in subject; if pathname is also true, then a period that immediately follows a / is also leading (as in “/.”). By default, period is false.
fnmatch() invokes VCL failure and returns false if either of pattern or subject is NULL – for example, if an unset header is specified.
- Examples
- # Matches URLs such as /foo/bar and /foo/bazif (std.fnmatch(“/foo/*”, req.url)) { … }# Matches URLs such as /foo/bar/baz and /foo/baz/quuxif (std.fnmatch(“/foo/*/*”, bereq.url)) { … }# Matches /foo/bar/quux, but not /foo/bar/baz/quuxif (std.fnmatch(“/foo/*/quux”, req.url)) { … }# Matches /foo/bar/quux and /foo/bar/baz/quuxif (std.fnmatch(“/foo/*/quux”, req.url, pathname=false)) { … }# Matches /foo/bar, /foo/car and /foo/farif (std.fnmatch(“/foo/?ar”, req.url)) { … }# Matches /foo/ followed by a non-digitif (std.fnmatch(“/foo/[!0-9]”, req.url)) { … }
SEE ALSO¶
COPYRIGHT¶
Copyright (c) 2010-2017 Varnish Software AS
All rights reserved.
Author: Poul-Henning Kamp <phk@FreeBSD.org>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
vmod_directors¶
Varnish Directors Module¶
- Manual section:
3
SYNOPSIS¶
import directors [from "path"] ;
new xround_robin = directors.round_robin()
VOID xround_robin.add_backend(BACKEND)
VOID xround_robin.remove_backend(BACKEND)
BACKEND xround_robin.backend()
new xfallback = directors.fallback(BOOL sticky)
VOID xfallback.add_backend(BACKEND)
VOID xfallback.remove_backend(BACKEND)
BACKEND xfallback.backend()
new xrandom = directors.random()
VOID xrandom.add_backend(BACKEND, REAL)
VOID xrandom.remove_backend(BACKEND)
BACKEND xrandom.backend()
new xhash = directors.hash()
VOID xhash.add_backend(BACKEND, REAL)
VOID xhash.remove_backend(BACKEND)
BACKEND xhash.backend(STRING)
new xshard = directors.shard()
VOID xshard.set_warmup(REAL probability)
VOID xshard.set_rampup(DURATION duration)
VOID xshard.associate(BLOB param)
BOOL xshard.add_backend(BACKEND backend, [STRING ident], [DURATION rampup], [REAL weight])
BOOL xshard.remove_backend([BACKEND backend], [STRING ident])
BOOL xshard.clear()
BOOL xshard.reconfigure(INT replicas)
INT xshard.key(STRING)
BACKEND xshard.backend([ENUM by], [INT key], [BLOB key_blob], [INT alt], [REAL warmup], [BOOL rampup], [ENUM healthy], [BLOB param], [ENUM resolve])
VOID xshard.debug(INT)
new xshard_param = directors.shard_param()
VOID xshard_param.clear()
VOID xshard_param.set([ENUM by], [INT key], [BLOB key_blob], [INT alt], [REAL warmup], [BOOL rampup], [ENUM healthy])
STRING xshard_param.get_by()
INT xshard_param.get_key()
INT xshard_param.get_alt()
REAL xshard_param.get_warmup()
BOOL xshard_param.get_rampup()
STRING xshard_param.get_healthy()
BLOB xshard_param.use()
CONTENTS¶
DESCRIPTION¶
vmod_directors enables backend load balancing in Varnish.
The module implements load balancing techniques, and also serves as an example on how one could extend the load balancing capabilities of Varnish.
To enable load balancing you must import this vmod (directors).
Then you define your backends. Once you have the backends declared you can add them to a director. This happens in executed VCL code. If you want to emulate the previous behavior of Varnish 3.0 you can just initialize the directors in vcl_init, like this:
sub vcl_init {
new vdir = directors.round_robin();
vdir.add_backend(backend1);
vdir.add_backend(backend2);
}
As you can see there is nothing keeping you from manipulating the directors elsewhere in VCL. So, you could have VCL code that would add more backends to a director when a certain URL is called.
Note that directors can use other directors as backends.
new xround_robin = directors.round_robin()¶
- Description
Create a round robin director.
This director will pick backends in a round robin fashion.
- Example
new vdir = directors.round_robin();
VOID xround_robin.add_backend(BACKEND)¶
- Description
Add a backend to the round-robin director.
- Example
vdir.add_backend(backend1);
VOID xround_robin.remove_backend(BACKEND)¶
- Description
Remove a backend from the round-robin director.
- Example
vdir.remove_backend(backend1);
BACKEND xround_robin.backend()¶
- Description
Pick a backend from the director.
- Example
set req.backend_hint = vdir.backend();
new xfallback = directors.fallback(BOOL sticky=0)¶
- Description
Create a fallback director.
A fallback director will try each of the added backends in turn, and return the first one that is healthy.
If
sticky
is set to true, the director will keep using the healthy backend, even if a higher-priority backend becomes available. Once the whole backend list is exhausted, it’ll start over at the beginning.- Example
new vdir = directors.fallback();
VOID xfallback.add_backend(BACKEND)¶
- Description
Add a backend to the director.
Note that the order in which this is done matters for the fallback director.
- Example
vdir.add_backend(backend1);
VOID xfallback.remove_backend(BACKEND)¶
- Description
Remove a backend from the director.
- Example
vdir.remove_backend(backend1);
BACKEND xfallback.backend()¶
- Description
Pick a backend from the director.
- Example
set req.backend_hint = vdir.backend();
new xrandom = directors.random()¶
- Description
Create a random backend director.
The random director distributes load over the backends using a weighted random probability distribution. The “testable” random generator in varnishd is used, which enables deterministic tests to be run (See: d00004.vtc).
- Example
new vdir = directors.random();
VOID xrandom.add_backend(BACKEND, REAL)¶
- Description
Add a backend to the director with a given weight.
Each backend will receive approximately 100 * (weight / (sum(all_added_weights))) per cent of the traffic sent to this director.
- Example
- # 2/3 to backend1, 1/3 to backend2.vdir.add_backend(backend1, 10.0);vdir.add_backend(backend2, 5.0);
VOID xrandom.remove_backend(BACKEND)¶
- Description
Remove a backend from the director.
- Example
vdir.remove_backend(backend1);
BACKEND xrandom.backend()¶
- Description
Pick a backend from the director.
- Example
set req.backend_hint = vdir.backend();
new xhash = directors.hash()¶
- Description
Create a hashing backend director.
The director chooses the backend server by computing a hash/digest of the string given to .backend().
Commonly used with
client.ip
or a session cookie to get sticky sessions.- Example
new vdir = directors.hash();
VOID xhash.add_backend(BACKEND, REAL)¶
- Description
Add a backend to the director with a certain weight.
Weight is used as in the random director. Recommended value is 1.0 unless you have special needs.
- Example
vdir.add_backend(backend1, 1.0);
VOID xhash.remove_backend(BACKEND)¶
- Description
Remove a backend from the director.
- Example
vdir.remove_backend(backend1);
BACKEND xhash.backend(STRING)¶
- Description
Pick a backend from the backend director.
Use the string or list of strings provided to pick the backend.
- Example
- # pick a backend based on the cookie header from the clientset req.backend_hint = vdir.backend(req.http.cookie);
new xshard = directors.shard()¶
Create a shard director.
Note that the shard director needs to be configured using at least one
shard.add_backend()
call(s) followed by a
shard.reconfigure()
call before it can hand out backends.
_Note_ that due to various restrictions (documented below), it is recommended to use the shard director on the backend side.
Introduction¶
The shard director selects backends by a key, which can be provided directly or derived from strings. For the same key, the shard director will always return the same backend, unless the backend configuration or health state changes. Conversely, for differing keys, the shard director will likely choose different backends. In the default configuration, unhealthy backends are not selected.
The shard director resembles the hash director, but its main advantage is that, when the backend configuration or health states change, the association of keys to backends remains as stable as possible.
In addition, the rampup and warmup features can help to further improve user-perceived response times.
Method¶
When .reconfigure()
is called, a consistent hashing circular data
structure gets built from the last 32 bits of SHA256 hash values of
<ident><n> (default ident being the backend name) for each
backend and for a running number n from 1 to replicas. Hashing
creates the seemingly random order for placement of backends on the
consistent hashing ring. When .add_backend()
is called with a
weight argument, replicas is scaled by that weight to add
proportionally more copies of the that backend on the ring.
When .backend()
is called, a load balancing key gets generated
unless provided. The smallest hash value in the circle is looked up
that is larger than the key (searching clockwise and wrapping around
as necessary). The backend for this hash value is the preferred
backend for the given key.
If a healthy backend is requested, the search is continued linearly on the ring as long as backends found are unhealthy or all backends have been checked. The order of these “alternative backends” on the ring is likely to differ for different keys. Alternative backends can also be selected explicitly.
On consistent hashing see:
svn://svn.audioscrobbler.net/misc/ketama
Error Reporting¶
Failing methods should report errors to VSL with the Error tag, so when configuring the shard director, you are advised to check:
varnishlog -I Error:^shard
VOID xshard.set_warmup(REAL probability=0.0)¶
Set the default warmup probability. See the warmup parameter of
shard.backend()
. If probability is 0.0 (default), warmup is
disabled.
VOID xshard.set_rampup(DURATION duration=0)¶
Set the default rampup duration. See rampup parameter of shard.backend(). If duration is 0 (default), rampup is disabled.
VOID xshard.associate(BLOB param=0)¶
Associate a default obj_shard_param object or clear an association.
The value of the param argument must be a call to the func_shard_param.use method. No argument clears the association.
The association can be changed per backend request using the param argument of func_shard.backend.
BOOL xshard.clear()¶
Remove all backends from the director.
NOTE: Backend changes need to be finalized with shard.reconfigure() and are only supported on one shard director at a time.
BOOL xshard.reconfigure(INT replicas=67)¶
Reconfigure the consistent hashing ring to reflect backend changes.
This method must be called at least once before the director can be used.
INT xshard.key(STRING)¶
Convenience method to generate a sharding key for use with the key
argument to the shard.backend()
method by hashing the given string
with SHA256.
To generate sharding keys using other hashes, use a custom vmod like
vmod blobdigest with the key_blob argument of the
shard.backend()
method.
VOID xshard.debug(INT)¶
intentionally undocumented
new xshard_param = directors.shard_param()¶
Create a shard parameter set.
A parameter set allows for re-use of func_shard.backend arguments across many shard director instances and simplifies advanced use cases (e.g. shard director with custom parameters layered below other directors).
Parameter sets have two scopes:
per-VCL scope defined in
vcl_init{}
per backend request scope
The per-VCL scope defines defaults for the per backend scope. Any
changes to a parameter set in backend context and in vcl_pipe {}
only affect the respective backend request.
Parameter sets can not be used in client context except for
vcl_pipe {}
.
VOID xshard_param.clear()¶
Reset the parameter set to default values as documented for func_shard.backend.
in
vcl_init{}
, resets the parameter set default for this VCL inbackend context and in
vcl_pipe {}
, resets the parameter set for this backend request to the VCL defaults
This method may not be used in client context other than vcl_pipe {}
.
STRING xshard_param.get_by()¶
Get a string representation of the by enum argument which denotes how a shard director using this parameter object would derive the shard key. See func_shard.backend.
INT xshard_param.get_key()¶
Get the key which a shard director using this parameter object would use. See func_shard.backend.
INT xshard_param.get_alt()¶
Get the alt parameter which a shard director using this parameter object would use. See func_shard.backend.
REAL xshard_param.get_warmup()¶
Get the warmup parameter which a shard director using this parameter object would use. See func_shard.backend.
BOOL xshard_param.get_rampup()¶
Get the rampup parameter which a shard director using this parameter object would use. See func_shard.backend.
STRING xshard_param.get_healthy()¶
Get a string representation of the healthy enum argument which a shard director using this parameter object would use. See func_shard.backend.
BLOB xshard_param.use()¶
This method may only be used in backend context and in vcl_pipe {}
.
For use with the param argument of func_shard.backend to associate this shard parameter set with a shard director.
ACKNOWLEDGEMENTS¶
Development of a previous version of the shard director was partly sponsored by Deutsche Telekom AG - Products & Innovation.
Development of a previous version of the shard director was partly sponsored by BILD GmbH & Co KG.
COPYRIGHT¶
This document is licensed under the same licence as Varnish
itself. See LICENCE for details.
Copyright (c) 2013-2015 Varnish Software AS
Copyright 2009-2018 UPLEX - Nils Goroll Systemoptimierung
All rights reserved.
Authors: Poul-Henning Kamp <phk@FreeBSD.org>
Julian Wiesener <jw@uplex.de>
Nils Goroll <slink@uplex.de>
Geoffrey Simmons <geoff@uplex.de>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
vmod_vtc¶
Utility module for varnishtest¶
- Manual section:
3
SYNOPSIS¶
import vtc [from "path"] ;
VOID barrier_sync(STRING addr, DURATION timeout)
BACKEND no_backend()
STEVEDORE no_stevedore()
IP no_ip()
VOID panic(STRING)
VOID sleep(DURATION)
VOID workspace_alloc(ENUM, INT size)
BYTES workspace_reserve(ENUM, INT size)
INT workspace_free(ENUM)
VOID workspace_snapshot(ENUM)
VOID workspace_reset(ENUM)
BOOL workspace_overflowed(ENUM)
VOID workspace_overflow(ENUM)
INT typesize(STRING)
CONTENTS¶
DESCRIPTION¶
The goal for this VMOD is to provide VCL users and VMOD authors means to test corner cases or reach certain conditions with varnishtest.
VOID barrier_sync(STRING addr, DURATION timeout=0)¶
When writing test cases, the most common pattern is to start a mock server
instance, a Varnish instance, and spin up a mock client. Those entities run
asynchronously, and others exist like background processes (process
) or
log readers (logexpect
). While you can synchronize with individual
entities and wait for their completion, you must use a barrier if you need
to synchronize two or more entities, or wait until a certain point instead
of completion.
Not only is it possible to synchronize between test entities, with the
barrier_sync
function you can even synchronize VCL code:
sub vcl_recv {
# wait for some barrier b1 to complete
vtc.barrier_sync("${b1_sock}");
}
If the function fails to synchronize with the barrier for some reason, or if it reaches the optional timeout, it fails the VCL transaction.
MISCELLANEOUS¶
BACKEND no_backend()¶
Fails at backend selection.
STEVEDORE no_stevedore()¶
Fails at storage selection.
IP no_ip()¶
Returns a null IP address, not even a bogo_ip.
VOID panic(STRING)¶
It can be useful to crash the child process in order to test the robustness of a VMOD.
VOID sleep(DURATION)¶
Block the current worker thread.
WORKSPACES¶
It can be useful to put a workspace in a given state when testing corner
cases like resource exhaustion for a transaction, especially for VMOD
development. All functions available allow to pick which workspace you
need to tamper with, available values are client
, backend
, session
and thread
.
VOID workspace_alloc(ENUM, INT size)¶
VOID workspace_alloc(
ENUM {client, backend, session, thread},
INT size
)
Allocate and zero out memory from a workspace. A negative size will allocate as much as needed to leave that many bytes free. The actual allocation size may be higher to comply with memory alignment requirements of the CPU architecture. A failed allocation fails the transaction.
BYTES workspace_reserve(ENUM, INT size)¶
BYTES workspace_reserve(
ENUM {client, backend, session, thread},
INT size
)
Attempt to reserve size bytes and release the reservation right away. Return the size of the reservation.
See vtc.workspace_alloc() for semantics of the size argument.
INT workspace_free(ENUM {client, backend, session, thread})¶
Find how much unallocated space there is left in a workspace.
VOID workspace_snapshot(ENUM)¶
VOID workspace_snapshot(ENUM {client, backend, session, thread})
Snapshot a workspace. Only one snapshot may be active at a time.
VOID workspace_reset(ENUM)¶
VOID workspace_reset(ENUM {client, backend, session, thread})
Reset to the previous snapshot of a workspace, it must be the same workspace too.
BOOL workspace_overflowed(ENUM)¶
BOOL workspace_overflowed(ENUM {client, backend, session, thread})
Find whether the workspace overflow mark is set or not.
VOID workspace_overflow(ENUM)¶
VOID workspace_overflow(ENUM {client, backend, session, thread})
Mark a workspace as overflowed.
INT typesize(STRING)¶
Returns the size in bytes of a collection of C-datatypes:
'p'
: pointer'i'
:int
'd'
:double
'f'
:float
'l'
:long
's'
:short
'z'
:size_t
'o'
:off_t
'j'
:intmax_t
This can be useful for VMOD authors in conjunction with workspace operations.
SEE ALSO¶
COPYRIGHT¶
Copyright (c) 2017 Varnish Software AS
All rights reserved.
Author: Dridi Boukelmoune <dridi.boukelmoune@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
vmod_purge¶
Varnish Purge Module¶
- Manual section:
3
SYNOPSIS¶
import purge [from "path"] ;
INT hard()
INT soft(DURATION ttl, DURATION grace, DURATION keep)
CONTENTS¶
DESCRIPTION¶
vmod_purge contains functions that offer a finer-grained control than the
purge
transition in vcl_recv
. The functions can only be called from
vcl_hit
or vcl_miss
and they should in general be used in both to
ensure that all variants of a same object are taken care of.
EXAMPLE¶
sub vcl_recv {
if (req.method == "PURGE") {
if (client.ip !~ purge_acl) {
return (synth(405));
}
return (hash);
}
}
sub my_purge {
set req.http.purged = purge.hard();
if (req.http.purged == "0") {
return (synth(404));
}
else {
return (synth(200));
}
}
sub vcl_hit {
if (req.method == "PURGE") {
call my_purge;
}
}
sub vcl_miss {
if (req.method == "PURGE") {
call my_purge;
}
}
sub vcl_synth {
if (req.method == "PURGE") {
if (req.http.purged) {
set resp.http.purged = req.http.purged;
}
return (deliver);
}
}
INT hard()¶
- Description
This is equivalent to
return(purge)
but explicitly called fromvcl_hit
andvcl_miss
. It returns the number of purged objects.- Example
set req.http.purged = purge.hard();
INT soft(DURATION ttl, DURATION grace, DURATION keep)¶
INT soft(DURATION ttl=0, DURATION grace=-1, DURATION keep=-1)
- Description
Sets the TTL, grace and keep. By default, TTL is set to 0 with grace and keep periods left untouched. Setting a negative value for grace or keep periods leaves them untouched. Setting all three parameters to 0 is equivalent to a hard purge. It can only be called from
vcl_hit
orvcl_miss
. It returns the number of soft-purged objects.
SEE ALSO¶
COPYRIGHT¶
Copyright (c) 2017 Varnish Software AS
All rights reserved.
Author: Dridi Boukelmoune <dridi.boukelmoune@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
vmod_blob¶
Utilities for the VCL blob type, encoding and decoding¶
- Manual section:
3
SYNOPSIS¶
import blob [from "path"] ;
BLOB decode(ENUM decoding, INT length, STRING encoded)
STRING encode(ENUM encoding, ENUM case, BLOB blob)
STRING transcode(ENUM decoding, ENUM encoding, ENUM case, INT length, STRING encoded)
BOOL same(BLOB, BLOB)
BOOL equal(BLOB, BLOB)
INT length(BLOB)
BLOB sub(BLOB, BYTES length, BYTES offset)
new xblob = blob.blob(ENUM decoding, STRING encoded)
BLOB xblob.get()
STRING xblob.encode(ENUM encoding, ENUM case)
CONTENTS¶
DESCRIPTION¶
This VMOD provides utility functions and an object for the VCL data type BLOB, which may contain arbitrary data of any length.
Examples:
sub vcl_init {
# Create blob objects from encodings such as base64 or hex.
new myblob = blob.blob(BASE64, "Zm9vYmFy");
new yourblob = blob.blob(encoded="666F6F", decoding=HEX);
}
sub vcl_deliver {
# The .get() method retrieves the BLOB from an object.
set resp.http.MyBlob-As-Hex
= blob.encode(blob=myblob.get(), encoding=HEX);
# The .encode() method efficiently retrieves an encoding.
set resp.http.YourBlob-As-Base64 = yourblob.encode(BASE64);
# decode() and encode() functions convert blobs to text and
# vice versa at runtime.
set resp.http.Base64-Encoded
= blob.encode(BASE64,
blob=blob.decode(HEX,
encoded=req.http.Hex-Encoded));
}
sub vcl_recv {
# transcode() converts from one encoding to another.
# case=UPPER specifies upper-case hex digits A-F.
set req.http.Hex-Encoded
= blob.transcode(decoding=BASE64, encoding=HEX,
case=UPPER, encoded="YmF6");
# transcode() from URL to IDENTITY effects a URL decode.
set req.url = blob.transcode(encoded=req.url, decoding=URL);
# transcode() from IDENTITY to URL effects a URL encode.
set req.http.url_urlcoded
= blob.transcode(encoded=req.url, encoding=URL);
}
ENCODING SCHEMES¶
Binary-to-text encoding schemes are specified by ENUMs in the VMOD’s constructor, methods and functions. Decodings convert a (possibly concatenated) string into a blob, while encodings convert a blob into a string.
ENUM values for an encoding scheme can be one of:
IDENTITY
BASE64
BASE64URL
BASE64URLNOPAD
HEX
URL
Empty strings are decoded into a “null blob” (of length 0), and conversely a null blob is encoded as the empty string.
For encodings with HEX
or URL
, you may also specify a case
ENUM with one of the values LOWER
, UPPER
or DEFAULT
to
produce a string with lower- or uppercase hex digits (in [a-f]
or
[A-F]
). The default value for case
is DEFAULT
, which for
HEX
and URL
means the same as LOWER
.
The case
ENUM is not relevant for decodings; HEX
or URL
strings to be decoded as BLOBs may have hex digits in either case, or
in mixed case.
The case
ENUM MUST be set to DEFAULT
for the other encodings
(BASE64* and IDENTITY). You cannot, for example, produce an uppercase
string by using the IDENTITY scheme with case=UPPER
. To change the
case of a string, use the toupper
or tolower
functions from
vmod_std.
IDENTITY¶
The simplest encoding converts between the BLOB and STRING data types, leaving the contents byte-identical.
Note that a BLOB may contain a null byte at any position before its end; if such a BLOB is decoded with IDENTITY, the resulting STRING will have a null byte at that position. Since VCL strings, like C strings, are represented with a terminating null byte, the string will be truncated, appearing to contain less data than the original blob. For example:
# Decode from the hex encoding for "foo\0bar".
# The header will be seen as "foo".
set resp.http.Trunced-Foo1
= blob.encode(IDENTITY, blob=blob.decode(HEX,
encoded="666f6f00626172"));
IDENTITY is the default encoding and decoding. So the above can also be written as:
# Decode from the hex encoding for "foo\0bar".
# The header will be seen as "foo".
set resp.http.Trunced-Foo2
= blob.encode(blob=blob.decode(HEX, encoded="666f6f00626172"));
The case
ENUM MUST be set to DEFAULT
for IDENTITY
encodings.
BASE64*¶
The base64 encoding schemes use 4 characters to encode 3 bytes. There are no newlines or maximal line lengths – whitespace is not permitted.
The BASE64
encoding uses the alphanumeric characters, +
and
/
; and encoded strings are padded with the =
character so that
their length is always a multiple of four.
The BASE64URL
encoding also uses the alphanumeric characters, but
-
and _
instead of +
and /
, so that an encoded string
can be used safely in a URL. This scheme also uses the padding
character =
.
The BASE64URLNOPAD
encoding uses the same alphabet as
BASE6URL
, but leaves out the padding. Thus the length of an
encoding with this scheme is not necessarily a multiple of four.
The case
ENUM MUST be set to DEFAULT
for for all of the
BASE64*
encodings.
HEX¶
The HEX
encoding scheme converts hex strings into blobs and vice
versa. For encodings, you may use the case
ENUM to specify upper-
or lowercase hex digits A
through f
(default DEFAULT
,
which means the same as LOWER
). A prefix such as 0x
is not
used for an encoding and is illegal for a decoding.
If a hex string to be decoded has an odd number of digits, it is
decoded as if a 0
is prepended to it; that is, the first digit is
interpreted as representing the least significant nibble of the first
byte. For example:
# The concatenated string is "abcdef0", and is decoded as "0abcdef0".
set resp.http.First = "abc";
set resp.http.Second = "def0";
set resp.http.Hex-Decoded
= blob.encode(HEX, blob=blob.decode(HEX,
encoded=resp.http.First + resp.http.Second));
URL¶
The URL
decoding replaces any %<2-hex-digits>
substrings with
the binary value of the hexadecimal number after the % sign.
The URL
encoding implements “percent encoding” as per RFC3986. The
case
ENUM determines the case of the hex digits, but does not
affect alphabetic characters that are not percent-encoded.
BLOB decode(ENUM decoding, INT length, STRING encoded)¶
BLOB decode(
ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD, HEX, URL} decoding=IDENTITY,
INT length=0,
STRING encoded
)
Returns the BLOB derived from the string encoded
according to the
scheme specified by decoding
.
If length
> 0, only decode the first length
characters of the
encoded string. If length
<= 0 or greater than the length of the
string, then decode the entire string. The default value of length
is 0.
decoding
defaults to IDENTITY.
Example:
blob.decode(BASE64, encoded="Zm9vYmFyYmF6");
# same with named parameters
blob.decode(encoded="Zm9vYmFyYmF6", decoding=BASE64);
# convert string to blob
blob.decode(encoded="foo");
STRING encode(ENUM encoding, ENUM case, BLOB blob)¶
STRING encode(
ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD, HEX, URL} encoding=IDENTITY,
ENUM {LOWER, UPPER, DEFAULT} case=DEFAULT,
BLOB blob
)
Returns a string representation of the BLOB blob
as specified by
encoding
. case
determines the case of hex digits for the
HEX
and URL
encodings, and is ignored for the other encodings.
encoding
defaults to IDENTITY, and case
defaults to DEFAULT.
DEFAULT is interpreted as LOWER for the HEX and URL encodings, and is
the required value for the other encodings.
Example:
set resp.http.encode1
= blob.encode(HEX,
blob=blob.decode(BASE64, encoded="Zm9vYmFyYmF6"));
# same with named parameters
set resp.http.encode2
= blob.encode(blob=blob.decode(encoded="Zm9vYmFyYmF6",
decoding=BASE64),
encoding=HEX);
# convert blob to string
set resp.http.encode3
= blob.encode(blob=blob.decode(encoded="foo"));
transcode(…)¶
STRING transcode(
ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD, HEX, URL} decoding=IDENTITY,
ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD, HEX, URL} encoding=IDENTITY,
ENUM {LOWER, UPPER, DEFAULT} case=DEFAULT,
INT length=0,
STRING encoded
)
Translates from one encoding to another, by first decoding the string
encoded
according to the scheme decoding
, and then returning
the encoding of the resulting blob according to the scheme
encoding
. case
determines the case of hex digits for the
HEX
and URL
encodings, and is ignored for other encodings.
As with decode()
: If length
> 0, only decode the first
length
characters of the encoded string, otherwise decode the
entire string. The default value of length
is 0.
decoding
and encoding
default to IDENTITY, and case
defaults to DEFAULT. DEFAULT is interpreted as LOWER for the HEX and
URL encodings, and is the required value for the other encodings.
Example:
set resp.http.Hex2Base64-1
= blob.transcode(HEX, BASE64, encoded="666f6f");
# same with named parameters
set resp.http.Hex2Base64-2
= blob.transcode(encoded="666f6f",
encoding=BASE64, decoding=HEX);
# URL decode -- recall that IDENTITY is the default encoding.
set resp.http.urldecoded
= blob.transcode(encoded="foo%20bar", decoding=URL);
# URL encode
set resp.http.urlencoded
= blob.transcode(encoded="foo bar", encoding=URL);
BOOL same(BLOB, BLOB)¶
Returns true if and only if the two BLOB arguments are the same object, i.e. they specify exactly the same region of memory, or both are empty.
If the BLOBs are both empty (length is 0 and/or the internal pointer
is NULL), then same()
returns true
. If any non-empty BLOB
is compared to an empty BLOB, then same()
returns false
.
BOOL equal(BLOB, BLOB)¶
Returns true if and only if the two BLOB arguments have equal contents (possibly in different memory regions).
As with same()
: If the BLOBs are both empty, then equal()
returns true
. If any non-empty BLOB is compared to an empty BLOB,
then equal()
returns false
.
INT length(BLOB)¶
Returns the length of the BLOB.
BLOB sub(BLOB, BYTES length, BYTES offset=0)¶
Returns a new BLOB formed from length
bytes of the BLOB argument
starting at offset
bytes from the start of its memory region. The
default value of offset
is 0B.
sub()
fails and returns NULL if the BLOB argument is empty, or if
offset + length
requires more bytes than are available in the
BLOB.
new xblob = blob.blob(ENUM decoding, STRING encoded)¶
new xblob = blob.blob(
ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD, HEX, URL} decoding=IDENTITY,
STRING encoded
)
Creates an object that contains the BLOB derived from the string
encoded
according to the scheme decoding
.
Example:
new theblob1 = blob.blob(BASE64, encoded="YmxvYg==");
# same with named arguments
new theblob2 = blob.blob(encoded="YmxvYg==", decoding=BASE64);
# string as a blob
new stringblob = blob.blob(encoded="bazz");
BLOB xblob.get()¶
Returns the BLOB created by the constructor.
Example:
set resp.http.The-Blob1 =
blob.encode(blob=theblob1.get());
set resp.http.The-Blob2 =
blob.encode(blob=theblob2.get());
set resp.http.The-Stringblob =
blob.encode(blob=stringblob.get());
STRING xblob.encode(ENUM encoding, ENUM case)¶
STRING xblob.encode(
ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD, HEX, URL} encoding=IDENTITY,
ENUM {LOWER, UPPER, DEFAULT} case=DEFAULT
)
Returns an encoding of BLOB created by the constructor, according to
the scheme encoding
. case
determines the case of hex digits
for the HEX
and URL
encodings, and MUST be set to DEFAULT
for the other encodings.
Example:
# blob as text
set resp.http.The-Blob = theblob1.encode();
# blob as base64
set resp.http.The-Blob-b64 = theblob1.encode(BASE64);
For any blob
object, encoding ENC
and case CASE
, encodings
via the .encode()
method and the encode()
function are equal:
# Always true:
blob.encode(ENC, CASE, blob.get()) == blob.encode(ENC, CASE)
But the object method is more efficient – the encoding is computed
once and cached (with allocation in heap memory), and the cached
encoding is retrieved on every subsequent call. The encode()
function computes the encoding on every call, allocating space for the
string in Varnish workspaces.
So if the data in a BLOB are fixed at VCL initialization time, so that
its encodings will always be the same, it is better to create a
blob
object. The VMOD’s functions should be used for data that are
not known until runtime.
ERRORS¶
The encoders, decoders and sub()
may fail if there is insufficient
space to create the new blob or string. Decoders may also fail if the
encoded string is an illegal format for the decoding scheme. Encoders
will fail for the IDENTITY
and BASE64*
encoding schemes if the
case
ENUM is not set to DEFAULT
.
If any of the VMOD’s methods, functions or constructor fail, then VCL
failure is invoked, just as if return(fail)
had been called in the
VCL source. This means that:
If the
blob
object constructor fails, or if any methods or functions fail duringvcl_init
, then the VCL program will fail to load, and the VCC compiler will emit an error message.If a method or function fails in any other VCL subroutine besides
vcl_synth
, then control is directed tovcl_synth
. The response status is set to 503 with the reason string"VCL failed"
, and an error message will be written to the Varnish log using the tagVCL_Error
.If the failure occurs during
vcl_synth
, thenvcl_synth
is aborted. The response line"503 VCL failed"
is returned, and theVCL_Error
message is written to the log.
LIMITATIONS¶
The VMOD allocates memory in various ways for new blobs and
strings. The blob
object and its methods allocate memory from the
heap, and hence they are only limited by available virtual memory.
The encode()
, decode()
and transcode()
functions allocate
Varnish workspace, as does sub()
for the newly created BLOB. If
these functions are failing, as indicated by “out of space” messages
in the Varnish log (with the VCL_Error
tag), then you will need to
increase the varnishd parameters workspace_client
and/or
workspace_backend
.
The transcode()
function also allocates space on the stack for a
temporary BLOB. If this function causes stack overflow, you may need
to increase the varnishd parameter thread_pool_stack
.
SEE ALSO¶
COPYRIGHT¶
This document is licensed under the same conditions as Varnish itself.
See LICENSE for details.
Authors: Nils Goroll <nils.goroll@uplex.de>
Geoffrey Simmons <geoffrey.simmons@uplex.de>
vmod_unix¶
Utilities for Unix domain sockets¶
- Manual section:
3
SYNOPSIS¶
import unix [from "path"] ;
STRING user()
STRING group()
INT uid()
INT gid()
CONTENTS¶
DESCRIPTION¶
This VMOD provides information about the credentials of the peer process (user and group of the process owner) that is connected to a Varnish listener via a Unix domain socket, if the platform supports it.
Examples:
import unix;
sub vcl_recv {
# Return "403 Forbidden" if the connected peer is
# not running as the user "trusteduser".
if (unix.user() != "trusteduser") {
return( synth(403) );
}
# Require the connected peer to run in the group
# "trustedgroup".
if (unix.group() != "trustedgroup") {
return( synth(403) );
}
# Require the connected peer to run under a specific numeric
# user id.
if (unix.uid() != 4711) {
return( synth(403) );
}
# Require the connected peer to run under a numeric group id.
if (unix.gid() != 815) {
return( synth(403) );
}
}
Obtaining the peer credentials is possible on a platform that supports one of the following:
getpeereid(3)
(such as FreeBSD and other BSD-derived systems)the socket option
SO_PEERCRED
forgetsockopt(2)
(Linux)getpeerucred(3C)
(SunOS and descendants)
On SunOS and friends, the PRIV_PROC_INFO
privilege set is added to
the Varnish child process while the VMOD is loaded, see
setppriv(2)
.
On most platforms, the value returned is the effective user or group that was valid when the peer process initiated the connection.
STRING user()¶
Return the user name of the peer process owner.
STRING group()¶
Return the group name of the peer process owner.
INT uid()¶
Return the numeric user id of the peer process owner.
INT gid()¶
Return the numeric group id of the peer process owner.
ERRORS¶
All functions in this VMOD are subject to the following constraints:
None of them may be called in
vcl_init
orvcl_fini
. If one of them is called invcl_init
, then the VCL program will fail to load, with an error message from the VMOD.If called on a platform that is not supported, then VCL failure is invoked. An error message is written to the log (with the
VCL_Error
tag), and for all VCL subroutines except forvcl_synth
, control is directed immediately tovcl_synth
, with the response status set to 503 and the reason string set to “VCL failed”.If the failure occurs during
vcl_synth
, thenvcl_synth
is aborted, and the the response line “503 VCL failed” is sent.If the current listener is not a Unix domain socket, or if the attempt to read credentials fails, then a
VCL_Error
message is written to the log. The STRING functions (vmod_user
andvmod_group
) return NULL, while the INT functions (vmod_uid
andvmod_gid
) return -1.
SEE ALSO¶
COPYRIGHT¶
This document is licensed under the same conditions as Varnish itself.
See LICENSE for details.
Authors: Geoffrey Simmons <geoffrey.simmons@uplex.de>
vmod_proxy¶
Varnish Module to extract TLV attributes from PROXYv2¶
- Manual section:
3
SYNOPSIS¶
import proxy [from "path"] ;
STRING alpn()
STRING authority()
BOOL is_ssl()
BOOL client_has_cert_sess()
BOOL client_has_cert_conn()
INT ssl_verify_result()
STRING ssl_version()
STRING client_cert_cn()
STRING ssl_cipher()
STRING cert_sign()
STRING cert_key()
CONTENTS¶
DESCRIPTION¶
vmod_proxy contains functions to extract proxy-protocol-v2 TLV attributes as described in https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt.
STRING alpn()¶
- Description
Extract ALPN attribute.
- Example
set req.http.alpn = proxy.alpn();
BOOL is_ssl()¶
- Description
Report if proxy-protocol-v2 has SSL TLV.
- Example
- if (proxy.is_ssl()) {set req.http.ssl-version = proxy.ssl_version();}
BOOL client_has_cert_sess()¶
- Description
Report if the client provided a certificate at least once over the TLS session this connection belongs to.
BOOL client_has_cert_conn()¶
- Description
Report if the client provided a certificate over the current connection.
INT ssl_verify_result()¶
- Description
Report the SSL_get_verify_result from a TLS session. It only matters if client_has_cert_sess() is true. Per default, value is set to 0 (X509_V_OK).
- Example
- if (proxy.client_has_cert_sess() && proxy.ssl_verify_result() == 0) {set req.http.ssl-verify = “ok”;}
STRING ssl_version()¶
- Description
Extract SSL version attribute.
- Example
set req.http.ssl-version = proxy.ssl_version();
STRING client_cert_cn()¶
- Description
Extract the common name attribute of the client certificate’s.
- Example
set req.http.cert-cn = proxy.client_cert_cn();
STRING ssl_cipher()¶
- Description
Extract the SSL cipher attribute.
- Example
set req.http.ssl-cipher = proxy.ssl_cipher();
STRING cert_sign()¶
- Description
Extract the certificate signature algorithm attribute.
- Example
set req.http.cert-sign = proxy.cert_sign();
STRING cert_key()¶
- Description
Extract the certificate key algorithm attribute.
- Example
set req.http.cert-key = proxy.cert_key();
SEE ALSO¶
COPYRIGHT¶
Copyright (c) 2018 GANDI SAS
All rights reserved.
Author: Emmanuel Hocdet <manu@gandi.net>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.