File: //proc/thread-self/root/usr/share/doc/varnish-6.0.3/html/reference/vmod_generated.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>vmod_std — Varnish version 6.0.3 documentation</title>
<link rel="stylesheet" href="../_static/classic.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Writing a Director" href="directors.html" />
<link rel="prev" title="VMOD - Varnish Modules" href="vmod.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="directors.html" title="Writing a Director"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="vmod.html" title="VMOD - Varnish Modules"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Varnish version 6.0.3 documentation</a> »</li>
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">The Varnish Reference Manual</a> »</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="vmod-std">
<span id="vmod-std-3"></span><h1>vmod_std<a class="headerlink" href="#vmod-std" title="Permalink to this headline">¶</a></h1>
<div class="section" id="varnish-standard-module">
<h2>Varnish Standard Module<a class="headerlink" href="#varnish-standard-module" title="Permalink to this headline">¶</a></h2>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Manual section:</th><td class="field-body">3</td>
</tr>
</tbody>
</table>
<div class="section" id="synopsis">
<h3>SYNOPSIS<a class="headerlink" href="#synopsis" title="Permalink to this headline">¶</a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">std</span> <span class="p">[</span><span class="kn">from</span> <span class="s2">"path"</span><span class="p">]</span> <span class="p">;</span>
<span class="n">STRING</span> <span class="n">toupper</span><span class="p">(</span><span class="n">STRING</span> <span class="n">s</span><span class="p">)</span>
<span class="n">STRING</span> <span class="n">tolower</span><span class="p">(</span><span class="n">STRING</span> <span class="n">s</span><span class="p">)</span>
<span class="n">VOID</span> <span class="n">set_ip_tos</span><span class="p">(</span><span class="n">INT</span> <span class="n">tos</span><span class="p">)</span>
<span class="n">REAL</span> <span class="n">random</span><span class="p">(</span><span class="n">REAL</span> <span class="n">lo</span><span class="p">,</span> <span class="n">REAL</span> <span class="n">hi</span><span class="p">)</span>
<span class="n">VOID</span> <span class="n">log</span><span class="p">(</span><span class="n">STRING</span> <span class="n">s</span><span class="p">)</span>
<span class="n">VOID</span> <span class="n">syslog</span><span class="p">(</span><span class="n">INT</span> <span class="n">priority</span><span class="p">,</span> <span class="n">STRING</span> <span class="n">s</span><span class="p">)</span>
<span class="n">STRING</span> <span class="n">fileread</span><span class="p">(</span><span class="n">STRING</span><span class="p">)</span>
<span class="n">BOOL</span> <span class="n">file_exists</span><span class="p">(</span><span class="n">STRING</span> <span class="n">path</span><span class="p">)</span>
<span class="n">VOID</span> <span class="n">collect</span><span class="p">(</span><span class="n">HEADER</span> <span class="n">hdr</span><span class="p">,</span> <span class="n">STRING</span> <span class="n">sep</span><span class="p">)</span>
<span class="n">DURATION</span> <span class="n">duration</span><span class="p">(</span><span class="n">STRING</span> <span class="n">s</span><span class="p">,</span> <span class="n">DURATION</span> <span class="n">fallback</span><span class="p">)</span>
<span class="n">INT</span> <span class="n">integer</span><span class="p">(</span><span class="n">STRING</span> <span class="n">s</span><span class="p">,</span> <span class="n">INT</span> <span class="n">fallback</span><span class="p">)</span>
<span class="n">IP</span> <span class="n">ip</span><span class="p">(</span><span class="n">STRING</span> <span class="n">s</span><span class="p">,</span> <span class="n">IP</span> <span class="n">fallback</span><span class="p">,</span> <span class="n">BOOL</span> <span class="n">resolve</span><span class="p">)</span>
<span class="n">REAL</span> <span class="n">real</span><span class="p">(</span><span class="n">STRING</span> <span class="n">s</span><span class="p">,</span> <span class="n">REAL</span> <span class="n">fallback</span><span class="p">)</span>
<span class="n">INT</span> <span class="n">real2integer</span><span class="p">(</span><span class="n">REAL</span> <span class="n">r</span><span class="p">,</span> <span class="n">INT</span> <span class="n">fallback</span><span class="p">)</span>
<span class="n">TIME</span> <span class="n">real2time</span><span class="p">(</span><span class="n">REAL</span> <span class="n">r</span><span class="p">,</span> <span class="n">TIME</span> <span class="n">fallback</span><span class="p">)</span>
<span class="n">INT</span> <span class="n">time2integer</span><span class="p">(</span><span class="n">TIME</span> <span class="n">t</span><span class="p">,</span> <span class="n">INT</span> <span class="n">fallback</span><span class="p">)</span>
<span class="n">REAL</span> <span class="n">time2real</span><span class="p">(</span><span class="n">TIME</span> <span class="n">t</span><span class="p">,</span> <span class="n">REAL</span> <span class="n">fallback</span><span class="p">)</span>
<span class="n">BOOL</span> <span class="n">healthy</span><span class="p">(</span><span class="n">BACKEND</span> <span class="n">be</span><span class="p">)</span>
<span class="n">INT</span> <span class="n">port</span><span class="p">(</span><span class="n">IP</span> <span class="n">ip</span><span class="p">)</span>
<span class="n">VOID</span> <span class="n">rollback</span><span class="p">(</span><span class="n">HTTP</span> <span class="n">h</span><span class="p">)</span>
<span class="n">VOID</span> <span class="n">timestamp</span><span class="p">(</span><span class="n">STRING</span> <span class="n">s</span><span class="p">)</span>
<span class="n">STRING</span> <span class="n">querysort</span><span class="p">(</span><span class="n">STRING</span><span class="p">)</span>
<span class="n">BOOL</span> <span class="n">cache_req_body</span><span class="p">(</span><span class="n">BYTES</span> <span class="n">size</span><span class="p">)</span>
<span class="n">STRING</span> <span class="n">strstr</span><span class="p">(</span><span class="n">STRING</span> <span class="n">s1</span><span class="p">,</span> <span class="n">STRING</span> <span class="n">s2</span><span class="p">)</span>
<span class="n">TIME</span> <span class="n">time</span><span class="p">(</span><span class="n">STRING</span> <span class="n">s</span><span class="p">,</span> <span class="n">TIME</span> <span class="n">fallback</span><span class="p">)</span>
<span class="n">STRING</span> <span class="n">getenv</span><span class="p">(</span><span class="n">STRING</span> <span class="n">name</span><span class="p">)</span>
<span class="n">VOID</span> <span class="n">late_100_continue</span><span class="p">(</span><span class="n">BOOL</span> <span class="n">late</span><span class="p">)</span>
<span class="n">BOOL</span> <span class="n">syntax</span><span class="p">(</span><span class="n">REAL</span><span class="p">)</span>
<span class="n">BOOL</span> <span class="n">fnmatch</span><span class="p">(</span><span class="n">STRING</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">STRING</span> <span class="n">subject</span><span class="p">,</span> <span class="n">BOOL</span> <span class="n">pathname</span><span class="p">,</span> <span class="n">BOOL</span> <span class="n">noescape</span><span class="p">,</span> <span class="n">BOOL</span> <span class="n">period</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="contents">
<h3>CONTENTS<a class="headerlink" href="#contents" title="Permalink to this headline">¶</a></h3>
<ul class="simple">
<li><a class="reference internal" href="#func-cache-req-body"><span class="std std-ref">BOOL cache_req_body(BYTES size)</span></a></li>
<li><a class="reference internal" href="#func-collect"><span class="std std-ref">VOID collect(HEADER hdr, STRING sep=”, “)</span></a></li>
<li><a class="reference internal" href="#func-duration"><span class="std std-ref">DURATION duration(STRING s, DURATION fallback)</span></a></li>
<li><a class="reference internal" href="#func-file-exists"><span class="std std-ref">BOOL file_exists(STRING path)</span></a></li>
<li><a class="reference internal" href="#func-fileread"><span class="std std-ref">STRING fileread(STRING)</span></a></li>
<li><a class="reference internal" href="#func-fnmatch"><span class="std std-ref">fnmatch(…)</span></a></li>
<li><a class="reference internal" href="#func-getenv"><span class="std std-ref">STRING getenv(STRING name)</span></a></li>
<li><a class="reference internal" href="#func-healthy"><span class="std std-ref">BOOL healthy(BACKEND be)</span></a></li>
<li><a class="reference internal" href="#func-integer"><span class="std std-ref">INT integer(STRING s, INT fallback)</span></a></li>
<li><a class="reference internal" href="#func-ip"><span class="std std-ref">IP ip(STRING s, IP fallback, BOOL resolve=1)</span></a></li>
<li><a class="reference internal" href="#func-late-100-continue"><span class="std std-ref">VOID late_100_continue(BOOL late)</span></a></li>
<li><a class="reference internal" href="#func-log"><span class="std std-ref">VOID log(STRING s)</span></a></li>
<li><a class="reference internal" href="#func-port"><span class="std std-ref">INT port(IP ip)</span></a></li>
<li><a class="reference internal" href="#func-querysort"><span class="std std-ref">STRING querysort(STRING)</span></a></li>
<li><a class="reference internal" href="#func-random"><span class="std std-ref">REAL random(REAL lo, REAL hi)</span></a></li>
<li><a class="reference internal" href="#func-real"><span class="std std-ref">REAL real(STRING s, REAL fallback)</span></a></li>
<li><a class="reference internal" href="#func-real2integer"><span class="std std-ref">INT real2integer(REAL r, INT fallback)</span></a></li>
<li><a class="reference internal" href="#func-real2time"><span class="std std-ref">TIME real2time(REAL r, TIME fallback)</span></a></li>
<li><a class="reference internal" href="#func-rollback"><span class="std std-ref">VOID rollback(HTTP h)</span></a></li>
<li><a class="reference internal" href="#func-set-ip-tos"><span class="std std-ref">VOID set_ip_tos(INT tos)</span></a></li>
<li><a class="reference internal" href="#func-strstr"><span class="std std-ref">STRING strstr(STRING s1, STRING s2)</span></a></li>
<li><a class="reference internal" href="#func-syntax"><span class="std std-ref">BOOL syntax(REAL)</span></a></li>
<li><a class="reference internal" href="#func-syslog"><span class="std std-ref">VOID syslog(INT priority, STRING s)</span></a></li>
<li><a class="reference internal" href="#func-time"><span class="std std-ref">TIME time(STRING s, TIME fallback)</span></a></li>
<li><a class="reference internal" href="#func-time2integer"><span class="std std-ref">INT time2integer(TIME t, INT fallback)</span></a></li>
<li><a class="reference internal" href="#func-time2real"><span class="std std-ref">REAL time2real(TIME t, REAL fallback)</span></a></li>
<li><a class="reference internal" href="#func-timestamp"><span class="std std-ref">VOID timestamp(STRING s)</span></a></li>
<li><a class="reference internal" href="#func-tolower"><span class="std std-ref">STRING tolower(STRING s)</span></a></li>
<li><a class="reference internal" href="#func-toupper"><span class="std std-ref">STRING toupper(STRING s)</span></a></li>
</ul>
</div>
<div class="section" id="description">
<h3>DESCRIPTION<a class="headerlink" href="#description" title="Permalink to this headline">¶</a></h3>
<p><cite>vmod_std</cite> contains basic functions which are part and parcel of Varnish,
but which for reasons of architecture fit better in a VMOD.</p>
<p>One particular class of functions in vmod_std is the conversions functions
which all have the form:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">TYPE</span> <span class="nb">type</span><span class="p">(</span><span class="n">STRING</span><span class="p">,</span> <span class="n">TYPE</span><span class="p">)</span>
</pre></div>
</div>
<p>These functions attempt to convert STRING to the TYPE, and if that fails,
they return the second argument, which must have the given TYPE.</p>
<div class="section" id="string-toupper-string-s">
<span id="func-toupper"></span><h4>STRING toupper(STRING s)<a class="headerlink" href="#string-toupper-string-s" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Converts the string <em>s</em> to uppercase.</dd>
<dt>Example</dt>
<dd>set beresp.http.scream = std.toupper(“yes!”);</dd>
</dl>
</div>
<div class="section" id="string-tolower-string-s">
<span id="func-tolower"></span><h4>STRING tolower(STRING s)<a class="headerlink" href="#string-tolower-string-s" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Converts the string <em>s</em> to lowercase.</dd>
<dt>Example</dt>
<dd>set beresp.http.nice = std.tolower(“VerY”);</dd>
</dl>
</div>
<div class="section" id="void-set-ip-tos-int-tos">
<span id="func-set-ip-tos"></span><h4>VOID set_ip_tos(INT tos)<a class="headerlink" href="#void-set-ip-tos-int-tos" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Sets the IP type-of-service (TOS) field for the current session
to <em>tos</em>. 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.</dd>
<dt>Example</dt>
<dd><div class="first last line-block">
<div class="line">if (req.url ~ “^/slow/”) {</div>
<div class="line-block">
<div class="line">std.set_ip_tos(0);</div>
</div>
<div class="line">}</div>
</div>
</dd>
</dl>
</div>
<div class="section" id="real-random-real-lo-real-hi">
<span id="func-random"></span><h4>REAL random(REAL lo, REAL hi)<a class="headerlink" href="#real-random-real-lo-real-hi" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Returns a random real number between <em>lo</em> and <em>hi</em>.
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.</dd>
<dt>Example</dt>
<dd>set beresp.http.random-number = std.random(1, 100);</dd>
</dl>
</div>
<div class="section" id="void-log-string-s">
<span id="func-log"></span><h4>VOID log(STRING s)<a class="headerlink" href="#void-log-string-s" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Logs the string <em>s</em> to the shared memory log, using VSL tag
<em>SLT_VCL_Log</em>.</dd>
<dt>Example</dt>
<dd>std.log(“Something fishy is going on with the vhost ” + req.http.host);</dd>
</dl>
</div>
<div class="section" id="void-syslog-int-priority-string-s">
<span id="func-syslog"></span><h4>VOID syslog(INT priority, STRING s)<a class="headerlink" href="#void-syslog-int-priority-string-s" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd><p class="first">Logs the string <em>s</em> to syslog tagged with <em>priority</em>. <em>priority</em>
is formed by ORing the facility and level values. See your
system’s syslog.h file for possible values.</p>
<p class="last">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 <code class="docutils literal notranslate"><span class="pre">syslog()</span></code> function
has no effect.</p>
</dd>
<dt>Example</dt>
<dd><p class="first">std.syslog(9, “Something is wrong”);</p>
<p class="last">This will send a message to syslog using LOG_USER | LOG_ALERT.</p>
</dd>
</dl>
</div>
<div class="section" id="string-fileread-string">
<span id="func-fileread"></span><h4>STRING fileread(STRING)<a class="headerlink" href="#string-fileread-string" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Reads a file and returns a string with the content. The result
is cached indefinitely per filename.</dd>
<dt>Example</dt>
<dd>synthetic(“Response was served by ” + std.fileread(“/etc/hostname”));</dd>
</dl>
<p>Consider that the entire contents of the file appear in the string
that is returned, including newlines that may result in invalid
headers if <code class="docutils literal notranslate"><span class="pre">std.fileread()</span></code> is used to form a header. In that case,
you may need to modify the string, for example with <code class="docutils literal notranslate"><span class="pre">regsub()</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">set</span> <span class="n">beresp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">served</span><span class="o">-</span><span class="n">by</span> <span class="o">=</span> <span class="n">regsub</span><span class="p">(</span><span class="n">std</span><span class="o">.</span><span class="n">fileread</span><span class="p">(</span><span class="s2">"/etc/hostname"</span><span class="p">),</span> <span class="s2">"\R$"</span><span class="p">,</span> <span class="s2">""</span><span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="bool-file-exists-string-path">
<span id="func-file-exists"></span><h4>BOOL file_exists(STRING path)<a class="headerlink" href="#bool-file-exists-string-path" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Returns <cite>true</cite> if path or the file pointed to by path exists,
<cite>false</cite> otherwise.</dd>
<dt>Example</dt>
<dd><div class="first last line-block">
<div class="line">if (std.file_exists(“/etc/return_503”)) {</div>
<div class="line-block">
<div class="line">return (synth(503, “Varnish is in maintenance”));</div>
</div>
<div class="line">}</div>
</div>
</dd>
</dl>
</div>
<div class="section" id="void-collect-header-hdr-string-sep">
<span id="func-collect"></span><h4>VOID collect(HEADER hdr, STRING sep=”, “)<a class="headerlink" href="#void-collect-header-hdr-string-sep" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd><p class="first">Collapses multiple <em>hdr</em> headers into one long header. The
default separator <em>sep</em> is the standard comma separator to
use when collapsing headers, with an additional whitespace
for pretty printing.</p>
<p class="last">Care should be taken when collapsing headers. In particular
collapsing Set-Cookie will lead to unexpected results on the
browser side.</p>
</dd>
<dt>Examples</dt>
<dd><div class="first last line-block">
<div class="line">std.collect(req.http.accept);</div>
<div class="line">std.collect(req.http.cookie, “; “);</div>
</div>
</dd>
</dl>
</div>
<div class="section" id="duration-duration-string-s-duration-fallback">
<span id="func-duration"></span><h4>DURATION duration(STRING s, DURATION fallback)<a class="headerlink" href="#duration-duration-string-s-duration-fallback" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Converts the string <em>s</em> to seconds. <em>s</em> must be quantified
with ms (milliseconds), s (seconds), m (minutes), h (hours),
d (days), w (weeks) or y (years) units. If conversion fails,
<em>fallback</em> will be returned.</dd>
<dt>Example</dt>
<dd>set beresp.ttl = std.duration(“1w”, 3600s);</dd>
</dl>
</div>
<div class="section" id="int-integer-string-s-int-fallback">
<span id="func-integer"></span><h4>INT integer(STRING s, INT fallback)<a class="headerlink" href="#int-integer-string-s-int-fallback" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Converts the string <em>s</em> to an integer. If conversion fails,
<em>fallback</em> will be returned.</dd>
<dt>Example</dt>
<dd><div class="first last line-block">
<div class="line">if (std.integer(req.http.foo, 0) > 5) {</div>
<div class="line-block">
<div class="line">…</div>
</div>
<div class="line">}</div>
</div>
</dd>
</dl>
</div>
<div class="section" id="ip-ip-string-s-ip-fallback-bool-resolve-1">
<span id="func-ip"></span><h4>IP ip(STRING s, IP fallback, BOOL resolve=1)<a class="headerlink" href="#ip-ip-string-s-ip-fallback-bool-resolve-1" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd><p class="first">Converts the string <em>s</em> to the first IP number returned by
the system library function getaddrinfo(3). If conversion
fails, <em>fallback</em> will be returned.</p>
<p class="last">If <em>resolve</em> is false, getaddrinfo() is called using <em>AI_NUMERICHOST</em>
to avoid network lookups. This makes “pure” IP strings cheaper to
convert.</p>
</dd>
<dt>Example</dt>
<dd><div class="first last line-block">
<div class="line">if (std.ip(req.http.X-forwarded-for, “0.0.0.0”) ~ my_acl) {</div>
<div class="line-block">
<div class="line">…</div>
</div>
<div class="line">}</div>
</div>
</dd>
</dl>
</div>
<div class="section" id="real-real-string-s-real-fallback">
<span id="func-real"></span><h4>REAL real(STRING s, REAL fallback)<a class="headerlink" href="#real-real-string-s-real-fallback" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Converts the string <em>s</em> to a real. If conversion fails,
<em>fallback</em> will be returned.</dd>
<dt>Example</dt>
<dd><div class="first last line-block">
<div class="line">if (std.real(req.http.foo, 0.0) > 5.5) {</div>
<div class="line-block">
<div class="line">…</div>
</div>
<div class="line">}</div>
</div>
</dd>
</dl>
</div>
<div class="section" id="int-real2integer-real-r-int-fallback">
<span id="func-real2integer"></span><h4>INT real2integer(REAL r, INT fallback)<a class="headerlink" href="#int-real2integer-real-r-int-fallback" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Rounds the real <em>r</em> to the nearest integer, but round halfway
cases away from zero (see round(3)). If conversion fails,
<em>fallback</em> will be returned.</dd>
<dt>Example</dt>
<dd>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</dd>
</dl>
</div>
<div class="section" id="time-real2time-real-r-time-fallback">
<span id="func-real2time"></span><h4>TIME real2time(REAL r, TIME fallback)<a class="headerlink" href="#time-real2time-real-r-time-fallback" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Rounds the real <em>r</em> to the nearest integer (see
<a class="reference internal" href="#func-real2integer">func_real2integer</a>) and returns the corresponding time when
interpreted as a unix epoch. If conversion fails, <em>fallback</em>
will be returned.</dd>
<dt>Example</dt>
<dd>set req.http.time = std.real2time(1140618699.00, now);</dd>
</dl>
</div>
<div class="section" id="int-time2integer-time-t-int-fallback">
<span id="func-time2integer"></span><h4>INT time2integer(TIME t, INT fallback)<a class="headerlink" href="#int-time2integer-time-t-int-fallback" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Converts the time <em>t</em> to a integer. If conversion fails,
<em>fallback</em> will be returned.</dd>
<dt>Example</dt>
<dd>set req.http.int = std.time2integer(now, 0);</dd>
</dl>
</div>
<div class="section" id="real-time2real-time-t-real-fallback">
<span id="func-time2real"></span><h4>REAL time2real(TIME t, REAL fallback)<a class="headerlink" href="#real-time2real-time-t-real-fallback" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Converts the time <em>t</em> to a real. If conversion fails,
<em>fallback</em> will be returned.</dd>
<dt>Example</dt>
<dd>set req.http.real = std.time2real(now, 1.0);</dd>
</dl>
</div>
<div class="section" id="bool-healthy-backend-be">
<span id="func-healthy"></span><h4>BOOL healthy(BACKEND be)<a class="headerlink" href="#bool-healthy-backend-be" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Returns <cite>true</cite> if the backend <em>be</em> is healthy.</dd>
</dl>
</div>
<div class="section" id="int-port-ip-ip">
<span id="func-port"></span><h4>INT port(IP ip)<a class="headerlink" href="#int-port-ip-ip" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Returns the port number of the IP address <em>ip</em>. Always returns
0 for a <code class="docutils literal notranslate"><span class="pre">*.ip</span></code> variable whose value is <code class="docutils literal notranslate"><span class="pre">0.0.0.0</span></code> because
the listen address is a Unix domain socket.</dd>
</dl>
</div>
<div class="section" id="void-rollback-http-h">
<span id="func-rollback"></span><h4>VOID rollback(HTTP h)<a class="headerlink" href="#void-rollback-http-h" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Restores the <em>h</em> HTTP headers to their original state.</dd>
<dt>Example</dt>
<dd>std.rollback(bereq);</dd>
</dl>
</div>
<div class="section" id="void-timestamp-string-s">
<span id="func-timestamp"></span><h4>VOID timestamp(STRING s)<a class="headerlink" href="#void-timestamp-string-s" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Introduces a timestamp in the log with the current time, using
the string <em>s</em> as the label. This is useful to time the execution
of lengthy VCL procedures, and makes the timestamps inserted
automatically by Varnish more accurate.</dd>
<dt>Example</dt>
<dd>std.timestamp(“curl-request”);</dd>
</dl>
</div>
<div class="section" id="string-querysort-string">
<span id="func-querysort"></span><h4>STRING querysort(STRING)<a class="headerlink" href="#string-querysort-string" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Sorts the query string for cache normalization purposes.</dd>
<dt>Example</dt>
<dd>set req.url = std.querysort(req.url);</dd>
</dl>
</div>
<div class="section" id="bool-cache-req-body-bytes-size">
<span id="func-cache-req-body"></span><h4>BOOL cache_req_body(BYTES size)<a class="headerlink" href="#bool-cache-req-body-bytes-size" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd><p class="first">Caches the request body if it is smaller than <em>size</em>. Returns
<cite>true</cite> if the body was cached, <cite>false</cite> otherwise.</p>
<p class="last">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.</p>
</dd>
<dt>Example</dt>
<dd><div class="first last line-block">
<div class="line">if (std.cache_req_body(1KB)) {</div>
<div class="line-block">
<div class="line">…</div>
</div>
<div class="line">}</div>
</div>
</dd>
</dl>
</div>
<div class="section" id="string-strstr-string-s1-string-s2">
<span id="func-strstr"></span><h4>STRING strstr(STRING s1, STRING s2)<a class="headerlink" href="#string-strstr-string-s1-string-s2" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd><p class="first">Returns a string beginning at the first occurrence of the string
<em>s2</em> in the string <em>s1</em>, or an empty string if <em>s2</em> is not found.</p>
<p class="last">Note that the comparison is case sensitive.</p>
</dd>
<dt>Example</dt>
<dd><div class="first line-block">
<div class="line">if (std.strstr(req.url, req.http.restrict)) {</div>
<div class="line-block">
<div class="line">…</div>
</div>
<div class="line">}</div>
</div>
<p class="last">This will check if the content of req.http.restrict occurs
anywhere in req.url.</p>
</dd>
</dl>
</div>
<div class="section" id="time-time-string-s-time-fallback">
<span id="func-time"></span><h4>TIME time(STRING s, TIME fallback)<a class="headerlink" href="#time-time-string-s-time-fallback" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd><p class="first">Converts the string <em>s</em> to a time. If conversion fails,
<em>fallback</em> will be returned.</p>
<p>Supported formats:</p>
<div class="last line-block">
<div class="line">“Sun, 06 Nov 1994 08:49:37 GMT”</div>
<div class="line">“Sunday, 06-Nov-94 08:49:37 GMT”</div>
<div class="line">“Sun Nov 6 08:49:37 1994”</div>
<div class="line">“1994-11-06T08:49:37”</div>
<div class="line">“784111777.00”</div>
<div class="line">“784111777”</div>
</div>
</dd>
<dt>Example</dt>
<dd><div class="first last line-block">
<div class="line">if (std.time(resp.http.last-modified, now) < now - 1w) {</div>
<div class="line-block">
<div class="line">…</div>
</div>
<div class="line">}</div>
</div>
</dd>
</dl>
</div>
<div class="section" id="string-getenv-string-name">
<span id="func-getenv"></span><h4>STRING getenv(STRING name)<a class="headerlink" href="#string-getenv-string-name" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd><p class="first">Return environment variable <em>name</em> or the empty string.</p>
<p class="last">See getenv(3)</p>
</dd>
<dt>Example</dt>
<dd><div class="first last line-block">
<div class="line">set req.http.My-Env = std.getenv(“MY_ENV”);</div>
</div>
</dd>
</dl>
</div>
<div class="section" id="void-late-100-continue-bool-late">
<span id="func-late-100-continue"></span><h4>VOID late_100_continue(BOOL late)<a class="headerlink" href="#void-late-100-continue-bool-late" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd><p class="first">Controls when varnish reacts to an <cite>Expect: 100-continue</cite> client
request header.</p>
<p>Varnish always generates a <cite>100 Continue</cite> response if
requested by the client trough the <cite>Expect: 100-continue</cite>
header when waiting for request body data.</p>
<p>But, by default, the <cite>100 Continue</cite> response is already
generated immediately after <cite>vcl_recv</cite> returns to reduce
latencies under the assumption that the request body will be
read eventually.</p>
<p>Calling <cite>std.late_100_continue(true)</cite> in <cite>vcl_recv</cite> will cause
the <cite>100 Continue</cite> 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.</p>
<p class="last">This function has no effect outside <cite>vcl_recv</cite> and after
calling <cite>std.cache_req_body()</cite> or any other function consuming
the request body.</p>
</dd>
<dt>Example</dt>
<dd><div class="first last line-block">
<div class="line">vcl_recv {</div>
<div class="line-block">
<div class="line">std.late_100_continue(true);</div>
<div class="line"><br /></div>
<div class="line">if (req.method == “POST”) {</div>
<div class="line-block">
<div class="line">std.late_100_continue(false);</div>
<div class="line">return (pass);</div>
</div>
<div class="line">}</div>
<div class="line">…</div>
</div>
<div class="line">}</div>
</div>
</dd>
</dl>
</div>
<div class="section" id="bool-syntax-real">
<span id="func-syntax"></span><h4>BOOL syntax(REAL)<a class="headerlink" href="#bool-syntax-real" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Returns the true if VCL version is at least REAL.</dd>
</dl>
</div>
<div class="section" id="fnmatch">
<span id="func-fnmatch"></span><h4>fnmatch(…)<a class="headerlink" href="#fnmatch" title="Permalink to this headline">¶</a></h4>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">BOOL</span> <span class="n">fnmatch</span><span class="p">(</span>
<span class="n">STRING</span> <span class="n">pattern</span><span class="p">,</span>
<span class="n">STRING</span> <span class="n">subject</span><span class="p">,</span>
<span class="n">BOOL</span> <span class="n">pathname</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
<span class="n">BOOL</span> <span class="n">noescape</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
<span class="n">BOOL</span> <span class="n">period</span><span class="o">=</span><span class="mi">0</span>
<span class="p">)</span>
</pre></div>
</div>
<dl class="docutils">
<dt>Description</dt>
<dd><p class="first">Shell-style pattern matching; returns <cite>true</cite> if <em>subject</em>
matches <em>pattern</em>, where <em>pattern</em> may contain wildcard
characters such as * or ?.</p>
<p>The match is executed by the implementation of <cite>fnmatch(3)</cite> on
your system. The rules for pattern matching on most systems
include the following:</p>
<ul class="simple">
<li>* matches any sequence of characters</li>
<li>? matches a single character</li>
<li>a bracket expression such as [abc] or [!0-9] is interpreted
as a character class according to the rules of basic regular
expressions (<em>not</em> PCRE regexen), except that ! is used for
character class negation instead of ^.</li>
</ul>
<p>If <em>pathname</em> is <cite>true</cite>, 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, <em>pathname</em> is <cite>true</cite>.</p>
<p>If <em>noescape</em> is <cite>true</cite>, then the backslash character \ is
matched as an ordinary character. Otherwise, \ is an escape
character, and matches the character that follows it in the
<cite>pattern</cite>. For example, \ matches \ when <em>noescape</em> is
<cite>true</cite>, and \ when <cite>false</cite>. By default, <em>noescape</em> is
<cite>false</cite>.</p>
<p>If <em>period</em> is <cite>true</cite>, 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 <cite>subject</cite>; if <em>pathname</em> is also <cite>true</cite>, then a period that
immediately follows a / is also leading (as in “/.”). By
default, <em>period</em> is <cite>false</cite>.</p>
<p class="last"><cite>fnmatch()</cite> invokes VCL failure and returns <cite>false</cite> if either
of <em>pattern</em> or <em>subject</em> is NULL – for example, if an unset
header is specified.</p>
</dd>
<dt>Examples</dt>
<dd><div class="first last line-block">
<div class="line"># Matches URLs such as /foo/bar and /foo/baz</div>
<div class="line">if (std.fnmatch(“/foo/*”, req.url)) { … }</div>
<div class="line"><br /></div>
<div class="line"># Matches URLs such as /foo/bar/baz and /foo/baz/quux</div>
<div class="line">if (std.fnmatch(“/foo/*/*”, bereq.url)) { … }</div>
<div class="line"><br /></div>
<div class="line"># Matches /foo/bar/quux, but not /foo/bar/baz/quux</div>
<div class="line">if (std.fnmatch(“/foo/*/quux”, req.url)) { … }</div>
<div class="line"><br /></div>
<div class="line"># Matches /foo/bar/quux and /foo/bar/baz/quux</div>
<div class="line">if (std.fnmatch(“/foo/*/quux”, req.url, pathname=false)) { … }</div>
<div class="line"><br /></div>
<div class="line"># Matches /foo/bar, /foo/car and /foo/far</div>
<div class="line">if (std.fnmatch(“/foo/?ar”, req.url)) { … }</div>
<div class="line"><br /></div>
<div class="line"># Matches /foo/ followed by a non-digit</div>
<div class="line">if (std.fnmatch(“/foo/[!0-9]”, req.url)) { … }</div>
</div>
</dd>
</dl>
</div>
</div>
<div class="section" id="see-also">
<h3>SEE ALSO<a class="headerlink" href="#see-also" title="Permalink to this headline">¶</a></h3>
<ul class="simple">
<li><a class="reference internal" href="varnishd.html#varnishd-1"><span class="std std-ref">varnishd</span></a></li>
<li><a class="reference internal" href="vsl.html#vsl-7"><span class="std std-ref">VSL</span></a></li>
<li><cite>fnmatch(3)</cite></li>
</ul>
</div>
<div class="section" id="copyright">
<h3>COPYRIGHT<a class="headerlink" href="#copyright" title="Permalink to this headline">¶</a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>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.
</pre></div>
</div>
</div>
</div>
</div>
<div class="section" id="vmod-directors">
<span id="vmod-directors-3"></span><h1>vmod_directors<a class="headerlink" href="#vmod-directors" title="Permalink to this headline">¶</a></h1>
<div class="section" id="varnish-directors-module">
<h2>Varnish Directors Module<a class="headerlink" href="#varnish-directors-module" title="Permalink to this headline">¶</a></h2>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Manual section:</th><td class="field-body">3</td>
</tr>
</tbody>
</table>
<div class="section" id="id1">
<h3>SYNOPSIS<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">directors</span> <span class="p">[</span><span class="kn">from</span> <span class="s2">"path"</span><span class="p">]</span> <span class="p">;</span>
<span class="n">new</span> <span class="n">xround_robin</span> <span class="o">=</span> <span class="n">directors</span><span class="o">.</span><span class="n">round_robin</span><span class="p">()</span>
<span class="n">VOID</span> <span class="n">xround_robin</span><span class="o">.</span><span class="n">add_backend</span><span class="p">(</span><span class="n">BACKEND</span><span class="p">)</span>
<span class="n">VOID</span> <span class="n">xround_robin</span><span class="o">.</span><span class="n">remove_backend</span><span class="p">(</span><span class="n">BACKEND</span><span class="p">)</span>
<span class="n">BACKEND</span> <span class="n">xround_robin</span><span class="o">.</span><span class="n">backend</span><span class="p">()</span>
<span class="n">new</span> <span class="n">xfallback</span> <span class="o">=</span> <span class="n">directors</span><span class="o">.</span><span class="n">fallback</span><span class="p">(</span><span class="n">BOOL</span> <span class="n">sticky</span><span class="p">)</span>
<span class="n">VOID</span> <span class="n">xfallback</span><span class="o">.</span><span class="n">add_backend</span><span class="p">(</span><span class="n">BACKEND</span><span class="p">)</span>
<span class="n">VOID</span> <span class="n">xfallback</span><span class="o">.</span><span class="n">remove_backend</span><span class="p">(</span><span class="n">BACKEND</span><span class="p">)</span>
<span class="n">BACKEND</span> <span class="n">xfallback</span><span class="o">.</span><span class="n">backend</span><span class="p">()</span>
<span class="n">new</span> <span class="n">xrandom</span> <span class="o">=</span> <span class="n">directors</span><span class="o">.</span><span class="n">random</span><span class="p">()</span>
<span class="n">VOID</span> <span class="n">xrandom</span><span class="o">.</span><span class="n">add_backend</span><span class="p">(</span><span class="n">BACKEND</span><span class="p">,</span> <span class="n">REAL</span><span class="p">)</span>
<span class="n">VOID</span> <span class="n">xrandom</span><span class="o">.</span><span class="n">remove_backend</span><span class="p">(</span><span class="n">BACKEND</span><span class="p">)</span>
<span class="n">BACKEND</span> <span class="n">xrandom</span><span class="o">.</span><span class="n">backend</span><span class="p">()</span>
<span class="n">new</span> <span class="n">xhash</span> <span class="o">=</span> <span class="n">directors</span><span class="o">.</span><span class="n">hash</span><span class="p">()</span>
<span class="n">VOID</span> <span class="n">xhash</span><span class="o">.</span><span class="n">add_backend</span><span class="p">(</span><span class="n">BACKEND</span><span class="p">,</span> <span class="n">REAL</span><span class="p">)</span>
<span class="n">VOID</span> <span class="n">xhash</span><span class="o">.</span><span class="n">remove_backend</span><span class="p">(</span><span class="n">BACKEND</span><span class="p">)</span>
<span class="n">BACKEND</span> <span class="n">xhash</span><span class="o">.</span><span class="n">backend</span><span class="p">(</span><span class="n">STRING</span><span class="p">)</span>
<span class="n">new</span> <span class="n">xshard</span> <span class="o">=</span> <span class="n">directors</span><span class="o">.</span><span class="n">shard</span><span class="p">()</span>
<span class="n">VOID</span> <span class="n">xshard</span><span class="o">.</span><span class="n">set_warmup</span><span class="p">(</span><span class="n">REAL</span> <span class="n">probability</span><span class="p">)</span>
<span class="n">VOID</span> <span class="n">xshard</span><span class="o">.</span><span class="n">set_rampup</span><span class="p">(</span><span class="n">DURATION</span> <span class="n">duration</span><span class="p">)</span>
<span class="n">VOID</span> <span class="n">xshard</span><span class="o">.</span><span class="n">associate</span><span class="p">(</span><span class="n">BLOB</span> <span class="n">param</span><span class="p">)</span>
<span class="n">BOOL</span> <span class="n">xshard</span><span class="o">.</span><span class="n">add_backend</span><span class="p">(</span><span class="n">BACKEND</span> <span class="n">backend</span><span class="p">,</span> <span class="p">[</span><span class="n">STRING</span> <span class="n">ident</span><span class="p">],</span> <span class="p">[</span><span class="n">DURATION</span> <span class="n">rampup</span><span class="p">])</span>
<span class="n">BOOL</span> <span class="n">xshard</span><span class="o">.</span><span class="n">remove_backend</span><span class="p">([</span><span class="n">BACKEND</span> <span class="n">backend</span><span class="p">],</span> <span class="p">[</span><span class="n">STRING</span> <span class="n">ident</span><span class="p">])</span>
<span class="n">BOOL</span> <span class="n">xshard</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span>
<span class="n">BOOL</span> <span class="n">xshard</span><span class="o">.</span><span class="n">reconfigure</span><span class="p">(</span><span class="n">INT</span> <span class="n">replicas</span><span class="p">)</span>
<span class="n">INT</span> <span class="n">xshard</span><span class="o">.</span><span class="n">key</span><span class="p">(</span><span class="n">STRING</span><span class="p">)</span>
<span class="n">BACKEND</span> <span class="n">xshard</span><span class="o">.</span><span class="n">backend</span><span class="p">([</span><span class="n">ENUM</span> <span class="n">by</span><span class="p">],</span> <span class="p">[</span><span class="n">INT</span> <span class="n">key</span><span class="p">],</span> <span class="p">[</span><span class="n">BLOB</span> <span class="n">key_blob</span><span class="p">],</span> <span class="p">[</span><span class="n">INT</span> <span class="n">alt</span><span class="p">],</span> <span class="p">[</span><span class="n">REAL</span> <span class="n">warmup</span><span class="p">],</span> <span class="p">[</span><span class="n">BOOL</span> <span class="n">rampup</span><span class="p">],</span> <span class="p">[</span><span class="n">ENUM</span> <span class="n">healthy</span><span class="p">],</span> <span class="p">[</span><span class="n">BLOB</span> <span class="n">param</span><span class="p">],</span> <span class="p">[</span><span class="n">ENUM</span> <span class="n">resolve</span><span class="p">])</span>
<span class="n">VOID</span> <span class="n">xshard</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">INT</span><span class="p">)</span>
<span class="n">new</span> <span class="n">xshard_param</span> <span class="o">=</span> <span class="n">directors</span><span class="o">.</span><span class="n">shard_param</span><span class="p">()</span>
<span class="n">VOID</span> <span class="n">xshard_param</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span>
<span class="n">VOID</span> <span class="n">xshard_param</span><span class="o">.</span><span class="n">set</span><span class="p">([</span><span class="n">ENUM</span> <span class="n">by</span><span class="p">],</span> <span class="p">[</span><span class="n">INT</span> <span class="n">key</span><span class="p">],</span> <span class="p">[</span><span class="n">BLOB</span> <span class="n">key_blob</span><span class="p">],</span> <span class="p">[</span><span class="n">INT</span> <span class="n">alt</span><span class="p">],</span> <span class="p">[</span><span class="n">REAL</span> <span class="n">warmup</span><span class="p">],</span> <span class="p">[</span><span class="n">BOOL</span> <span class="n">rampup</span><span class="p">],</span> <span class="p">[</span><span class="n">ENUM</span> <span class="n">healthy</span><span class="p">])</span>
<span class="n">STRING</span> <span class="n">xshard_param</span><span class="o">.</span><span class="n">get_by</span><span class="p">()</span>
<span class="n">INT</span> <span class="n">xshard_param</span><span class="o">.</span><span class="n">get_key</span><span class="p">()</span>
<span class="n">INT</span> <span class="n">xshard_param</span><span class="o">.</span><span class="n">get_alt</span><span class="p">()</span>
<span class="n">REAL</span> <span class="n">xshard_param</span><span class="o">.</span><span class="n">get_warmup</span><span class="p">()</span>
<span class="n">BOOL</span> <span class="n">xshard_param</span><span class="o">.</span><span class="n">get_rampup</span><span class="p">()</span>
<span class="n">STRING</span> <span class="n">xshard_param</span><span class="o">.</span><span class="n">get_healthy</span><span class="p">()</span>
<span class="n">BLOB</span> <span class="n">xshard_param</span><span class="o">.</span><span class="n">use</span><span class="p">()</span>
</pre></div>
</div>
</div>
<div class="section" id="id2">
<h3>CONTENTS<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h3>
<ul class="simple">
<li><a class="reference internal" href="#obj-fallback"><span class="std std-ref">new xfallback = directors.fallback(BOOL sticky=0)</span></a></li>
<li><a class="reference internal" href="#func-fallback-add-backend"><span class="std std-ref">VOID xfallback.add_backend(BACKEND)</span></a></li>
<li><a class="reference internal" href="#func-fallback-backend"><span class="std std-ref">BACKEND xfallback.backend()</span></a></li>
<li><a class="reference internal" href="#func-fallback-remove-backend"><span class="std std-ref">VOID xfallback.remove_backend(BACKEND)</span></a></li>
<li><a class="reference internal" href="#obj-hash"><span class="std std-ref">new xhash = directors.hash()</span></a></li>
<li><a class="reference internal" href="#func-hash-add-backend"><span class="std std-ref">VOID xhash.add_backend(BACKEND, REAL)</span></a></li>
<li><a class="reference internal" href="#func-hash-backend"><span class="std std-ref">BACKEND xhash.backend(STRING)</span></a></li>
<li><a class="reference internal" href="#func-hash-remove-backend"><span class="std std-ref">VOID xhash.remove_backend(BACKEND)</span></a></li>
<li><a class="reference internal" href="#obj-random"><span class="std std-ref">new xrandom = directors.random()</span></a></li>
<li><a class="reference internal" href="#func-random-add-backend"><span class="std std-ref">VOID xrandom.add_backend(BACKEND, REAL)</span></a></li>
<li><a class="reference internal" href="#func-random-backend"><span class="std std-ref">BACKEND xrandom.backend()</span></a></li>
<li><a class="reference internal" href="#func-random-remove-backend"><span class="std std-ref">VOID xrandom.remove_backend(BACKEND)</span></a></li>
<li><a class="reference internal" href="#obj-round-robin"><span class="std std-ref">new xround_robin = directors.round_robin()</span></a></li>
<li><a class="reference internal" href="#func-round-robin-add-backend"><span class="std std-ref">VOID xround_robin.add_backend(BACKEND)</span></a></li>
<li><a class="reference internal" href="#func-round-robin-backend"><span class="std std-ref">BACKEND xround_robin.backend()</span></a></li>
<li><a class="reference internal" href="#func-round-robin-remove-backend"><span class="std std-ref">VOID xround_robin.remove_backend(BACKEND)</span></a></li>
<li><a class="reference internal" href="#obj-shard"><span class="std std-ref">new xshard = directors.shard()</span></a></li>
<li><a class="reference internal" href="#func-shard-add-backend"><span class="std std-ref">shard.add_backend(…)</span></a></li>
<li><a class="reference internal" href="#func-shard-associate"><span class="std std-ref">VOID xshard.associate(BLOB param=0)</span></a></li>
<li><a class="reference internal" href="#func-shard-backend"><span class="std std-ref">shard.backend(…)</span></a></li>
<li><a class="reference internal" href="#func-shard-clear"><span class="std std-ref">BOOL xshard.clear()</span></a></li>
<li><a class="reference internal" href="#func-shard-debug"><span class="std std-ref">VOID xshard.debug(INT)</span></a></li>
<li><a class="reference internal" href="#func-shard-key"><span class="std std-ref">INT xshard.key(STRING)</span></a></li>
<li><a class="reference internal" href="#func-shard-reconfigure"><span class="std std-ref">BOOL xshard.reconfigure(INT replicas=67)</span></a></li>
<li><a class="reference internal" href="#func-shard-remove-backend"><span class="std std-ref">shard.remove_backend(…)</span></a></li>
<li><a class="reference internal" href="#func-shard-set-rampup"><span class="std std-ref">VOID xshard.set_rampup(DURATION duration=0)</span></a></li>
<li><a class="reference internal" href="#func-shard-set-warmup"><span class="std std-ref">VOID xshard.set_warmup(REAL probability=0.0)</span></a></li>
<li><a class="reference internal" href="#obj-shard-param"><span class="std std-ref">new xshard_param = directors.shard_param()</span></a></li>
<li><a class="reference internal" href="#func-shard-param-clear"><span class="std std-ref">VOID xshard_param.clear()</span></a></li>
<li><a class="reference internal" href="#func-shard-param-get-alt"><span class="std std-ref">INT xshard_param.get_alt()</span></a></li>
<li><a class="reference internal" href="#func-shard-param-get-by"><span class="std std-ref">STRING xshard_param.get_by()</span></a></li>
<li><a class="reference internal" href="#func-shard-param-get-healthy"><span class="std std-ref">STRING xshard_param.get_healthy()</span></a></li>
<li><a class="reference internal" href="#func-shard-param-get-key"><span class="std std-ref">INT xshard_param.get_key()</span></a></li>
<li><a class="reference internal" href="#func-shard-param-get-rampup"><span class="std std-ref">BOOL xshard_param.get_rampup()</span></a></li>
<li><a class="reference internal" href="#func-shard-param-get-warmup"><span class="std std-ref">REAL xshard_param.get_warmup()</span></a></li>
<li><a class="reference internal" href="#func-shard-param-set"><span class="std std-ref">shard_param.set(…)</span></a></li>
<li><a class="reference internal" href="#func-shard-param-use"><span class="std std-ref">BLOB xshard_param.use()</span></a></li>
</ul>
</div>
<div class="section" id="id3">
<h3>DESCRIPTION<a class="headerlink" href="#id3" title="Permalink to this headline">¶</a></h3>
<p><cite>vmod_directors</cite> enables backend load balancing in Varnish.</p>
<p>The module implements load balancing techniques, and also serves as an
example on how one could extend the load balancing capabilities of
Varnish.</p>
<p>To enable load balancing you must import this vmod (directors).</p>
<p>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:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sub</span> <span class="n">vcl_init</span> <span class="p">{</span>
<span class="n">new</span> <span class="n">vdir</span> <span class="o">=</span> <span class="n">directors</span><span class="o">.</span><span class="n">round_robin</span><span class="p">();</span>
<span class="n">vdir</span><span class="o">.</span><span class="n">add_backend</span><span class="p">(</span><span class="n">backend1</span><span class="p">);</span>
<span class="n">vdir</span><span class="o">.</span><span class="n">add_backend</span><span class="p">(</span><span class="n">backend2</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<p>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.</p>
<p>Note that directors can use other directors as backends.</p>
<div class="section" id="new-xround-robin-directors-round-robin">
<span id="obj-round-robin"></span><h4>new xround_robin = directors.round_robin()<a class="headerlink" href="#new-xround-robin-directors-round-robin" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd><p class="first">Create a round robin director.</p>
<p class="last">This director will pick backends in a round robin fashion.</p>
</dd>
<dt>Example</dt>
<dd>new vdir = directors.round_robin();</dd>
</dl>
</div>
<div class="section" id="void-xround-robin-add-backend-backend">
<span id="func-round-robin-add-backend"></span><h4>VOID xround_robin.add_backend(BACKEND)<a class="headerlink" href="#void-xround-robin-add-backend-backend" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Add a backend to the round-robin director.</dd>
<dt>Example</dt>
<dd>vdir.add_backend(backend1);</dd>
</dl>
</div>
<div class="section" id="void-xround-robin-remove-backend-backend">
<span id="func-round-robin-remove-backend"></span><h4>VOID xround_robin.remove_backend(BACKEND)<a class="headerlink" href="#void-xround-robin-remove-backend-backend" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Remove a backend from the round-robin director.</dd>
<dt>Example</dt>
<dd>vdir.remove_backend(backend1);</dd>
</dl>
</div>
<div class="section" id="backend-xround-robin-backend">
<span id="func-round-robin-backend"></span><h4>BACKEND xround_robin.backend()<a class="headerlink" href="#backend-xround-robin-backend" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Pick a backend from the director.</dd>
<dt>Example</dt>
<dd>set req.backend_hint = vdir.backend();</dd>
</dl>
</div>
<div class="section" id="new-xfallback-directors-fallback-bool-sticky-0">
<span id="obj-fallback"></span><h4>new xfallback = directors.fallback(BOOL sticky=0)<a class="headerlink" href="#new-xfallback-directors-fallback-bool-sticky-0" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd><p class="first">Create a fallback director.</p>
<p>A fallback director will try each of the added backends in turn,
and return the first one that is healthy.</p>
<p class="last">If <code class="docutils literal notranslate"><span class="pre">sticky</span></code> 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.</p>
</dd>
<dt>Example</dt>
<dd>new vdir = directors.fallback();</dd>
</dl>
</div>
<div class="section" id="void-xfallback-add-backend-backend">
<span id="func-fallback-add-backend"></span><h4>VOID xfallback.add_backend(BACKEND)<a class="headerlink" href="#void-xfallback-add-backend-backend" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd><p class="first">Add a backend to the director.</p>
<p class="last">Note that the order in which this is done matters for the fallback
director.</p>
</dd>
<dt>Example</dt>
<dd>vdir.add_backend(backend1);</dd>
</dl>
</div>
<div class="section" id="void-xfallback-remove-backend-backend">
<span id="func-fallback-remove-backend"></span><h4>VOID xfallback.remove_backend(BACKEND)<a class="headerlink" href="#void-xfallback-remove-backend-backend" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Remove a backend from the director.</dd>
<dt>Example</dt>
<dd>vdir.remove_backend(backend1);</dd>
</dl>
</div>
<div class="section" id="backend-xfallback-backend">
<span id="func-fallback-backend"></span><h4>BACKEND xfallback.backend()<a class="headerlink" href="#backend-xfallback-backend" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Pick a backend from the director.</dd>
<dt>Example</dt>
<dd>set req.backend_hint = vdir.backend();</dd>
</dl>
</div>
<div class="section" id="new-xrandom-directors-random">
<span id="obj-random"></span><h4>new xrandom = directors.random()<a class="headerlink" href="#new-xrandom-directors-random" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd><p class="first">Create a random backend director.</p>
<p class="last">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).</p>
</dd>
<dt>Example</dt>
<dd>new vdir = directors.random();</dd>
</dl>
</div>
<div class="section" id="void-xrandom-add-backend-backend-real">
<span id="func-random-add-backend"></span><h4>VOID xrandom.add_backend(BACKEND, REAL)<a class="headerlink" href="#void-xrandom-add-backend-backend-real" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd><p class="first">Add a backend to the director with a given weight.</p>
<p class="last">Each backend will receive approximately 100 * (weight /
(sum(all_added_weights))) per cent of the traffic sent to this
director.</p>
</dd>
<dt>Example</dt>
<dd><div class="first last line-block">
<div class="line"># 2/3 to backend1, 1/3 to backend2.</div>
<div class="line">vdir.add_backend(backend1, 10.0);</div>
<div class="line">vdir.add_backend(backend2, 5.0);</div>
</div>
</dd>
</dl>
</div>
<div class="section" id="void-xrandom-remove-backend-backend">
<span id="func-random-remove-backend"></span><h4>VOID xrandom.remove_backend(BACKEND)<a class="headerlink" href="#void-xrandom-remove-backend-backend" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Remove a backend from the director.</dd>
<dt>Example</dt>
<dd>vdir.remove_backend(backend1);</dd>
</dl>
</div>
<div class="section" id="backend-xrandom-backend">
<span id="func-random-backend"></span><h4>BACKEND xrandom.backend()<a class="headerlink" href="#backend-xrandom-backend" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Pick a backend from the director.</dd>
<dt>Example</dt>
<dd>set req.backend_hint = vdir.backend();</dd>
</dl>
</div>
<div class="section" id="new-xhash-directors-hash">
<span id="obj-hash"></span><h4>new xhash = directors.hash()<a class="headerlink" href="#new-xhash-directors-hash" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd><p class="first">Create a hashing backend director.</p>
<p>The director chooses the backend server by computing a hash/digest
of the string given to .backend().</p>
<p class="last">Commonly used with <code class="docutils literal notranslate"><span class="pre">client.ip</span></code> or a session cookie to get
sticky sessions.</p>
</dd>
<dt>Example</dt>
<dd>new vdir = directors.hash();</dd>
</dl>
</div>
<div class="section" id="void-xhash-add-backend-backend-real">
<span id="func-hash-add-backend"></span><h4>VOID xhash.add_backend(BACKEND, REAL)<a class="headerlink" href="#void-xhash-add-backend-backend-real" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd><p class="first">Add a backend to the director with a certain weight.</p>
<p class="last">Weight is used as in the random director. Recommended value is
1.0 unless you have special needs.</p>
</dd>
<dt>Example</dt>
<dd>vdir.add_backend(backend1, 1.0);</dd>
</dl>
</div>
<div class="section" id="void-xhash-remove-backend-backend">
<span id="func-hash-remove-backend"></span><h4>VOID xhash.remove_backend(BACKEND)<a class="headerlink" href="#void-xhash-remove-backend-backend" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Remove a backend from the director.</dd>
<dt>Example</dt>
<dd>vdir.remove_backend(backend1);</dd>
</dl>
</div>
<div class="section" id="backend-xhash-backend-string">
<span id="func-hash-backend"></span><h4>BACKEND xhash.backend(STRING)<a class="headerlink" href="#backend-xhash-backend-string" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd><p class="first">Pick a backend from the backend director.</p>
<p class="last">Use the string or list of strings provided to pick the backend.</p>
</dd>
<dt>Example</dt>
<dd><div class="first last line-block">
<div class="line"># pick a backend based on the cookie header from the client</div>
<div class="line">set req.backend_hint = vdir.backend(req.http.cookie);</div>
</div>
</dd>
</dl>
</div>
<div class="section" id="new-xshard-directors-shard">
<span id="obj-shard"></span><h4>new xshard = directors.shard()<a class="headerlink" href="#new-xshard-directors-shard" title="Permalink to this headline">¶</a></h4>
<p>Create a shard director.</p>
<p>Note that the shard director needs to be configured using at least one
<code class="docutils literal notranslate"><span class="pre">shard.add_backend()</span></code> call(s) <strong>followed by a</strong>
<code class="docutils literal notranslate"><span class="pre">shard.reconfigure()</span></code> <strong>call</strong> before it can hand out backends.</p>
<p>_Note_ that due to various restrictions (documented below), it is
recommended to use the shard director on the backend side.</p>
<div class="section" id="introduction">
<h5>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h5>
<p>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.</p>
<p>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.</p>
<p>In addition, the rampup and warmup features can help to further
improve user-perceived response times.</p>
</div>
<div class="section" id="sharding">
<h5>Sharding<a class="headerlink" href="#sharding" title="Permalink to this headline">¶</a></h5>
<p>This basic technique allows for numerous applications like optimizing
backend server cache efficiency, Varnish clustering or persisting
sessions to servers without keeping any state, and, in particular,
without the need to synchronize state between nodes of a cluster of
Varnish servers:</p>
<ul>
<li><p class="first">Many applications use caches for data objects, so, in a cluster of
application servers, requesting similar objects from the same server
may help to optimize efficiency of such caches.</p>
<p>For example, sharding by URL or some <cite>id</cite> component of the url has
been shown to drastically improve the efficiency of many content
management systems.</p>
</li>
<li><p class="first">As special case of the previous example, in clusters of Varnish
servers without additional request distribution logic, each cache
will need store all hot objects, so the effective cache size is
approximately the smallest cache size of any server in the cluster.</p>
<p>Sharding allows to segregate objects within the cluster such that
each object is only cached on one of the servers (or on one primary
and one backup, on a primary for long and others for short
etc…). Effectively, this will lead to a cache size in the order of
the sum of all individual caches, with the potential to drastically
increase efficiency (scales by the number of servers).</p>
</li>
<li><p class="first">Another application is to implement persistence of backend requests,
such that all requests sharing a certain criterion (such as an IP
address or session ID) get forwarded to the same backend server.</p>
</li>
</ul>
<p>When used with clusters of varnish servers, the shard director will,
if otherwise configured equally, make the same decision on all
servers. In other words, requests sharing a common criterion used as
the shard key will be balanced onto the same backend server(s) no
matter which Varnish server handles the request.</p>
<p>The drawbacks are:</p>
<ul class="simple">
<li>the distribution of requests depends on the number of requests per
key and the uniformity of the distribution of key values. In short,
while this technique may lead to much better efficiency overall, it
may also lead to less good load balancing for specific cases.</li>
<li>When a backend server becomes unavailable, every persistence
technique has to reselect a new backend server, but this technique
will also switch back to the preferred server once it becomes
healthy again, so when used for persistence, it is generally less
stable compared to stateful techniques (which would continue to use
a selected server for as long as possible (or dictated by a TTL)).</li>
</ul>
</div>
<div class="section" id="method">
<h5>Method<a class="headerlink" href="#method" title="Permalink to this headline">¶</a></h5>
<p>When <code class="docutils literal notranslate"><span class="pre">.reconfigure()</span></code> is called, a consistent hashing circular data
structure gets built from the last 32 bits of SHA256 hash values of
<cite><ident></cite><cite><n></cite> (default <cite>ident</cite> being the backend name) for each
backend and for a running number <cite>n</cite> from 1 to <cite>replicas</cite>. Hashing
creates the seemingly random order for placement of backends on the
consistent hashing ring.</p>
<p>When <code class="docutils literal notranslate"><span class="pre">.backend()</span></code> 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.</p>
<p>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.</p>
<p>On consistent hashing see:</p>
<ul class="simple">
<li><a class="reference external" href="http://www8.org/w8-papers/2a-webserver/caching/paper2.html">http://www8.org/w8-papers/2a-webserver/caching/paper2.html</a></li>
<li><a class="reference external" href="http://www.audioscrobbler.net/development/ketama/">http://www.audioscrobbler.net/development/ketama/</a></li>
<li>svn://svn.audioscrobbler.net/misc/ketama</li>
<li><a class="reference external" href="http://en.wikipedia.org/wiki/Consistent_hashing">http://en.wikipedia.org/wiki/Consistent_hashing</a></li>
</ul>
</div>
<div class="section" id="error-reporting">
<h5>Error Reporting<a class="headerlink" href="#error-reporting" title="Permalink to this headline">¶</a></h5>
<p>Failing methods should report errors to VSL with the Error tag, so
when configuring the shard director, you are advised to check:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">varnishlog</span> <span class="o">-</span><span class="n">I</span> <span class="n">Error</span><span class="p">:</span><span class="o">^</span><span class="n">shard</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="void-xshard-set-warmup-real-probability-0-0">
<span id="func-shard-set-warmup"></span><h4>VOID xshard.set_warmup(REAL probability=0.0)<a class="headerlink" href="#void-xshard-set-warmup-real-probability-0-0" title="Permalink to this headline">¶</a></h4>
<p>Set the default warmup probability. See the <cite>warmup</cite> parameter of
<code class="docutils literal notranslate"><span class="pre">shard.backend()</span></code>. If probability is 0.0 (default), warmup is
disabled.</p>
</div>
<div class="section" id="void-xshard-set-rampup-duration-duration-0">
<span id="func-shard-set-rampup"></span><h4>VOID xshard.set_rampup(DURATION duration=0)<a class="headerlink" href="#void-xshard-set-rampup-duration-duration-0" title="Permalink to this headline">¶</a></h4>
<p>Set the default rampup duration. See <cite>rampup</cite> parameter of
<cite>shard.backend()</cite>. If duration is 0 (default), rampup is disabled.</p>
</div>
<div class="section" id="void-xshard-associate-blob-param-0">
<span id="func-shard-associate"></span><h4>VOID xshard.associate(BLOB param=0)<a class="headerlink" href="#void-xshard-associate-blob-param-0" title="Permalink to this headline">¶</a></h4>
<p>Associate a default <a class="reference internal" href="#obj-shard-param">obj_shard_param</a> object or clear an association.</p>
<p>The value of the <cite>param</cite> argument must be a call to the
<a class="reference internal" href="#func-shard-param-use">func_shard_param.use</a> method. No argument clears the association.</p>
<p>The association can be changed per backend request using the <cite>param</cite>
argument of <a class="reference internal" href="#func-shard-backend">func_shard.backend</a>.</p>
</div>
<div class="section" id="shard-add-backend">
<span id="func-shard-add-backend"></span><h4>shard.add_backend(…)<a class="headerlink" href="#shard-add-backend" title="Permalink to this headline">¶</a></h4>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">BOOL</span> <span class="n">xshard</span><span class="o">.</span><span class="n">add_backend</span><span class="p">(</span>
<span class="n">BACKEND</span> <span class="n">backend</span><span class="p">,</span>
<span class="p">[</span><span class="n">STRING</span> <span class="n">ident</span><span class="p">],</span>
<span class="p">[</span><span class="n">DURATION</span> <span class="n">rampup</span><span class="p">]</span>
<span class="p">)</span>
</pre></div>
</div>
<p>Add a backend <cite>backend</cite> to the director.</p>
<p><cite>ident</cite>: Optionally specify an identification string for this backend,
which will be hashed by <cite>shard.reconfigure()</cite> to construct the
consistent hashing ring. The identification string defaults to the
backend name.</p>
<p><cite>ident</cite> allows to add multiple instances of the same backend.</p>
<p><cite>rampup</cite>: Optionally specify a specific rampup time for this
backend. Otherwise, the per-director rampup time is used (see
<a class="reference internal" href="#func-shard-set-rampup"><span class="std std-ref">VOID xshard.set_rampup(DURATION duration=0)</span></a>).</p>
<p>NOTE: Backend changes need to be finalized with <cite>shard.reconfigure()</cite>
and are only supported on one shard director at a time.</p>
</div>
<div class="section" id="shard-remove-backend">
<span id="func-shard-remove-backend"></span><h4>shard.remove_backend(…)<a class="headerlink" href="#shard-remove-backend" title="Permalink to this headline">¶</a></h4>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">BOOL</span> <span class="n">xshard</span><span class="o">.</span><span class="n">remove_backend</span><span class="p">(</span>
<span class="p">[</span><span class="n">BACKEND</span> <span class="n">backend</span><span class="o">=</span><span class="mi">0</span><span class="p">],</span>
<span class="p">[</span><span class="n">STRING</span> <span class="n">ident</span><span class="o">=</span><span class="mi">0</span><span class="p">]</span>
<span class="p">)</span>
</pre></div>
</div>
<p>Remove backend(s) from the director. Either <cite>backend</cite> or <cite>ident</cite> must
be specified. <cite>ident</cite> removes a specific instance. If <cite>backend</cite> is
given without <cite>ident</cite>, all instances of this backend are removed.</p>
<p>NOTE: Backend changes need to be finalized with <cite>shard.reconfigure()</cite>
and are only supported on one shard director at a time.</p>
</div>
<div class="section" id="bool-xshard-clear">
<span id="func-shard-clear"></span><h4>BOOL xshard.clear()<a class="headerlink" href="#bool-xshard-clear" title="Permalink to this headline">¶</a></h4>
<p>Remove all backends from the director.</p>
<p>NOTE: Backend changes need to be finalized with <cite>shard.reconfigure()</cite>
and are only supported on one shard director at a time.</p>
</div>
<div class="section" id="bool-xshard-reconfigure-int-replicas-67">
<span id="func-shard-reconfigure"></span><h4>BOOL xshard.reconfigure(INT replicas=67)<a class="headerlink" href="#bool-xshard-reconfigure-int-replicas-67" title="Permalink to this headline">¶</a></h4>
<p>Reconfigure the consistent hashing ring to reflect backend changes.</p>
<p>This method must be called at least once before the director can be
used.</p>
</div>
<div class="section" id="int-xshard-key-string">
<span id="func-shard-key"></span><h4>INT xshard.key(STRING)<a class="headerlink" href="#int-xshard-key-string" title="Permalink to this headline">¶</a></h4>
<p>Convenience method to generate a sharding key for use with the <cite>key</cite>
argument to the <code class="docutils literal notranslate"><span class="pre">shard.backend()</span></code> method by hashing the given string
with SHA256.</p>
<p>To generate sharding keys using other hashes, use a custom vmod like
<a class="reference external" href="https://code.uplex.de/uplex-varnish/libvmod-blobdigest/blob/master/README.rst">vmod blobdigest</a> with the <cite>key_blob</cite> argument of the
<code class="docutils literal notranslate"><span class="pre">shard.backend()</span></code> method.</p>
</div>
<div class="section" id="shard-backend">
<span id="func-shard-backend"></span><h4>shard.backend(…)<a class="headerlink" href="#shard-backend" title="Permalink to this headline">¶</a></h4>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">BACKEND</span> <span class="n">xshard</span><span class="o">.</span><span class="n">backend</span><span class="p">(</span>
<span class="p">[</span><span class="n">ENUM</span> <span class="p">{</span><span class="n">HASH</span><span class="p">,</span> <span class="n">URL</span><span class="p">,</span> <span class="n">KEY</span><span class="p">,</span> <span class="n">BLOB</span><span class="p">}</span> <span class="n">by</span><span class="o">=</span><span class="n">HASH</span><span class="p">],</span>
<span class="p">[</span><span class="n">INT</span> <span class="n">key</span><span class="p">],</span>
<span class="p">[</span><span class="n">BLOB</span> <span class="n">key_blob</span><span class="p">],</span>
<span class="p">[</span><span class="n">INT</span> <span class="n">alt</span><span class="o">=</span><span class="mi">0</span><span class="p">],</span>
<span class="p">[</span><span class="n">REAL</span> <span class="n">warmup</span><span class="o">=-</span><span class="mi">1</span><span class="p">],</span>
<span class="p">[</span><span class="n">BOOL</span> <span class="n">rampup</span><span class="o">=</span><span class="mi">1</span><span class="p">],</span>
<span class="p">[</span><span class="n">ENUM</span> <span class="p">{</span><span class="n">CHOSEN</span><span class="p">,</span> <span class="n">IGNORE</span><span class="p">,</span> <span class="n">ALL</span><span class="p">}</span> <span class="n">healthy</span><span class="o">=</span><span class="n">CHOSEN</span><span class="p">],</span>
<span class="p">[</span><span class="n">BLOB</span> <span class="n">param</span><span class="p">],</span>
<span class="p">[</span><span class="n">ENUM</span> <span class="p">{</span><span class="n">NOW</span><span class="p">,</span> <span class="n">LAZY</span><span class="p">}</span> <span class="n">resolve</span><span class="p">]</span>
<span class="p">)</span>
</pre></div>
</div>
<p>Lookup a backend on the consistent hashing ring.</p>
<p>This documentation uses the notion of an order of backends for a
particular shard key. This order is deterministic but seemingly random
as determined by the consistent hashing algorithm and is likely to
differ for different keys, depending on the number of backends and the
number of replicas. In particular, the backend order referred to here
is _not_ the order given when backends are added.</p>
<ul>
<li><p class="first"><cite>by</cite> how to determine the sharding key</p>
<ul class="simple">
<li><cite>HASH</cite>:<ul>
<li>when called in backend context: Use the varnish hash value as
set by <cite>vcl_hash</cite></li>
<li>when called in client context: hash <cite>req.url</cite></li>
</ul>
</li>
<li><cite>URL</cite>: hash req.url / bereq.url</li>
<li><cite>KEY</cite>: use the <cite>key</cite> argument</li>
<li><cite>BLOB</cite>: use the <cite>key_blob</cite> argument</li>
</ul>
</li>
<li><p class="first"><cite>key</cite> lookup key with <cite>by=KEY</cite></p>
<p>the <cite>shard.key()</cite> function may come handy to generate a sharding
key from custom strings.</p>
</li>
<li><p class="first"><cite>key_blob</cite> lookup key with <cite>by=BLOB</cite></p>
<p>Currently, this uses the first 4 bytes from the given blob in
network byte order (big endian), left-padded with zeros for blobs
smaller than 4 bytes.</p>
</li>
<li><p class="first"><cite>alt</cite> alternative backend selection</p>
<p>Select the <cite>alt</cite>-th alternative backend for the given <cite>key</cite>.</p>
<p>This is particularly useful for retries / restarts due to backend
errors: By setting <cite>alt=req.restarts</cite> or <cite>alt=bereq.retries</cite> with
healthy=ALL, another server gets selected.</p>
<p>The rampup and warmup features are only active for <cite>alt==0</cite></p>
</li>
<li><p class="first"><cite>rampup</cite> slow start for servers which just went healthy</p>
<p>If <cite>alt==0</cite> and the chosen backend is in its rampup period, with a
probability proportional to the fraction of time since the backup
became healthy to the rampup period, return the next alternative
backend, unless this is also in its rampup period.</p>
<p>The default rampup interval can be set per shard director using the
<cite>set_rampup()</cite> method or specifically per backend with the
<cite>set_backend()</cite> method.</p>
</li>
<li><p class="first"><cite>warmup</cite> probabilistic alternative server selection</p>
<p>possible values: -1, 0..1</p>
<p><cite>-1</cite>: use the warmup probability from the director definition</p>
<p>Only used for <cite>alt==0</cite>: Sets the ratio of requests (0.0 to 1.0) that
goes to the next alternate backend to warm it up when the preferred
backend is healthy. Not active if any of the preferred or
alternative backend are in rampup.</p>
<p><cite>warmup=0.5</cite> is a convenient way to spread the load for each key
over two backends under normal operating conditions.</p>
</li>
<li><p class="first"><cite>healthy</cite></p>
<ul>
<li><p class="first">CHOSEN: Return a healthy backend if possible.</p>
<p>For <cite>alt==0</cite>, return the first healthy backend or none.</p>
<p>For <cite>alt > 0</cite>, ignore the health state of backends skipped for
alternative backend selection, then return the next healthy
backend. If this does not exist, return the last healthy backend
of those skipped or none.</p>
</li>
<li><p class="first">IGNORE: Completely ignore backend health state</p>
<p>Just return the first or <cite>alt</cite>-th alternative backend, ignoring
health state. Ignore <cite>rampup</cite> and <cite>warmup</cite>.</p>
</li>
<li><p class="first">ALL: Check health state also for alternative backend selection</p>
<p>For <cite>alt > 0</cite>, return the <cite>alt</cite>-th alternative backend of all
those healthy, the last healthy backend found or none.</p>
</li>
</ul>
</li>
<li><p class="first"><cite>resolve</cite></p>
<p>default: <cite>LAZY</cite> in <code class="docutils literal notranslate"><span class="pre">vcl_init{}</span></code>, <cite>NOW</cite> otherwise</p>
<ul>
<li><p class="first"><code class="docutils literal notranslate"><span class="pre">NOW</span></code>: look up a backend and return it.</p>
<p>Can not be used in <code class="docutils literal notranslate"><span class="pre">vcl_init{}</span></code>.</p>
</li>
<li><p class="first"><code class="docutils literal notranslate"><span class="pre">LAZY</span></code>: return an instance of this director for later backend resolution.</p>
<p><code class="docutils literal notranslate"><span class="pre">LAZY</span></code> mode is required for referencing shard director instances,
for example as backends for other directors (director layering).</p>
<p>In <code class="docutils literal notranslate"><span class="pre">vcl_init{}</span></code> and on the client side, <code class="docutils literal notranslate"><span class="pre">LAZY</span></code> mode can not be
used with any other argument.</p>
<p>On the backend side, parameters from arguments or an associated
parameter set affect the shard director instance for the backend
request irrespective of where it is referenced.</p>
</li>
</ul>
</li>
<li><p class="first"><cite>param</cite></p>
<p>Use or associate a parameter set. The value of the <cite>param</cite> argument
must be a call to the <a class="reference internal" href="#func-shard-param-use">func_shard_param.use</a> method.</p>
<p>default: as set by <a class="reference internal" href="#func-shard-associate">func_shard.associate</a> or unset.</p>
<ul>
<li><p class="first">for <code class="docutils literal notranslate"><span class="pre">resolve=NOW</span></code> take parameter defaults from the
<a class="reference internal" href="#obj-shard-param">obj_shard_param</a> parameter set</p>
</li>
<li><p class="first">for <code class="docutils literal notranslate"><span class="pre">resolve=LAZY</span></code> associate the <a class="reference internal" href="#obj-shard-param">obj_shard_param</a> parameter
set for this backend request</p>
<p>Implementation notes for use of parameter sets with
<code class="docutils literal notranslate"><span class="pre">resolve=LAZY</span></code>:</p>
<ul class="simple">
<li>A <cite>param</cite> argument remains associated and any changes to the
associated parameter set affect the sharding decision once the
director resolves to an actual backend.</li>
<li>If other parameter arguments are also given, they have preference
and are kept even if the parameter set given by the <cite>param</cite>
argument is subsequently changed within the same backend request.</li>
<li>Each call to <a class="reference internal" href="#func-shard-backend">func_shard.backend</a> overrides any previous call.</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="void-xshard-debug-int">
<span id="func-shard-debug"></span><h4>VOID xshard.debug(INT)<a class="headerlink" href="#void-xshard-debug-int" title="Permalink to this headline">¶</a></h4>
<p><cite>intentionally undocumented</cite></p>
</div>
<div class="section" id="new-xshard-param-directors-shard-param">
<span id="obj-shard-param"></span><h4>new xshard_param = directors.shard_param()<a class="headerlink" href="#new-xshard-param-directors-shard-param" title="Permalink to this headline">¶</a></h4>
<p>Create a shard parameter set.</p>
<p>A parameter set allows for re-use of <a class="reference internal" href="#func-shard-backend">func_shard.backend</a> arguments
across many shard director instances and simplifies advanced use cases
(e.g. shard director with custom parameters layered below other
directors).</p>
<p>Parameter sets have two scopes:</p>
<ul class="simple">
<li>per-VCL scope defined in <code class="docutils literal notranslate"><span class="pre">vcl_init{}</span></code></li>
<li>per backend request scope</li>
</ul>
<p>The per-VCL scope defines defaults for the per backend scope. Any
changes to a parameter set in backend context only affect the
respective backend request.</p>
<p>Parameter sets can not be used in client context.</p>
</div>
<div class="section" id="void-xshard-param-clear">
<span id="func-shard-param-clear"></span><h4>VOID xshard_param.clear()<a class="headerlink" href="#void-xshard-param-clear" title="Permalink to this headline">¶</a></h4>
<p>Reset the parameter set to default values as documented for
<a class="reference internal" href="#func-shard-backend">func_shard.backend</a>.</p>
<ul class="simple">
<li>in <code class="docutils literal notranslate"><span class="pre">vcl_init{}</span></code>, resets the parameter set default for this VCL</li>
<li>in backend context, resets the parameter set for this backend
request to the VCL defaults</li>
</ul>
<p>This method may not be used in client context</p>
</div>
<div class="section" id="shard-param-set">
<span id="func-shard-param-set"></span><h4>shard_param.set(…)<a class="headerlink" href="#shard-param-set" title="Permalink to this headline">¶</a></h4>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">VOID</span> <span class="n">xshard_param</span><span class="o">.</span><span class="n">set</span><span class="p">(</span>
<span class="p">[</span><span class="n">ENUM</span> <span class="p">{</span><span class="n">HASH</span><span class="p">,</span> <span class="n">URL</span><span class="p">,</span> <span class="n">KEY</span><span class="p">,</span> <span class="n">BLOB</span><span class="p">}</span> <span class="n">by</span><span class="p">],</span>
<span class="p">[</span><span class="n">INT</span> <span class="n">key</span><span class="p">],</span>
<span class="p">[</span><span class="n">BLOB</span> <span class="n">key_blob</span><span class="p">],</span>
<span class="p">[</span><span class="n">INT</span> <span class="n">alt</span><span class="p">],</span>
<span class="p">[</span><span class="n">REAL</span> <span class="n">warmup</span><span class="p">],</span>
<span class="p">[</span><span class="n">BOOL</span> <span class="n">rampup</span><span class="p">],</span>
<span class="p">[</span><span class="n">ENUM</span> <span class="p">{</span><span class="n">CHOSEN</span><span class="p">,</span> <span class="n">IGNORE</span><span class="p">,</span> <span class="n">ALL</span><span class="p">}</span> <span class="n">healthy</span><span class="p">]</span>
<span class="p">)</span>
</pre></div>
</div>
<p>Change the given parameters of a parameter set as documented for
<a class="reference internal" href="#func-shard-backend">func_shard.backend</a>.</p>
<ul class="simple">
<li>in <code class="docutils literal notranslate"><span class="pre">vcl_init{}</span></code>, changes the parameter set default for this VCL</li>
<li>in backend context, changes the parameter set for this backend
request, keeping the defaults set for this VCL for unspecified
arguments.</li>
</ul>
<p>This method may not be used in client context</p>
</div>
<div class="section" id="string-xshard-param-get-by">
<span id="func-shard-param-get-by"></span><h4>STRING xshard_param.get_by()<a class="headerlink" href="#string-xshard-param-get-by" title="Permalink to this headline">¶</a></h4>
<p>Get a string representation of the <cite>by</cite> enum argument which denotes
how a shard director using this parameter object would derive the
shard key. See <a class="reference internal" href="#func-shard-backend">func_shard.backend</a>.</p>
</div>
<div class="section" id="int-xshard-param-get-key">
<span id="func-shard-param-get-key"></span><h4>INT xshard_param.get_key()<a class="headerlink" href="#int-xshard-param-get-key" title="Permalink to this headline">¶</a></h4>
<p>Get the key which a shard director using this parameter object would
use. See <a class="reference internal" href="#func-shard-backend">func_shard.backend</a>.</p>
</div>
<div class="section" id="int-xshard-param-get-alt">
<span id="func-shard-param-get-alt"></span><h4>INT xshard_param.get_alt()<a class="headerlink" href="#int-xshard-param-get-alt" title="Permalink to this headline">¶</a></h4>
<p>Get the <cite>alt</cite> parameter which a shard director using this parameter
object would use. See <a class="reference internal" href="#func-shard-backend">func_shard.backend</a>.</p>
</div>
<div class="section" id="real-xshard-param-get-warmup">
<span id="func-shard-param-get-warmup"></span><h4>REAL xshard_param.get_warmup()<a class="headerlink" href="#real-xshard-param-get-warmup" title="Permalink to this headline">¶</a></h4>
<p>Get the <cite>warmup</cite> parameter which a shard director using this parameter
object would use. See <a class="reference internal" href="#func-shard-backend">func_shard.backend</a>.</p>
</div>
<div class="section" id="bool-xshard-param-get-rampup">
<span id="func-shard-param-get-rampup"></span><h4>BOOL xshard_param.get_rampup()<a class="headerlink" href="#bool-xshard-param-get-rampup" title="Permalink to this headline">¶</a></h4>
<p>Get the <cite>rampup</cite> parameter which a shard director using this parameter
object would use. See <a class="reference internal" href="#func-shard-backend">func_shard.backend</a>.</p>
</div>
<div class="section" id="string-xshard-param-get-healthy">
<span id="func-shard-param-get-healthy"></span><h4>STRING xshard_param.get_healthy()<a class="headerlink" href="#string-xshard-param-get-healthy" title="Permalink to this headline">¶</a></h4>
<p>Get a string representation of the <cite>healthy</cite> enum argument which a
shard director using this parameter object would use. See
<a class="reference internal" href="#func-shard-backend">func_shard.backend</a>.</p>
</div>
<div class="section" id="blob-xshard-param-use">
<span id="func-shard-param-use"></span><h4>BLOB xshard_param.use()<a class="headerlink" href="#blob-xshard-param-use" title="Permalink to this headline">¶</a></h4>
<p>This method may only be used in backend context.</p>
<p>For use with the <cite>param</cite> argument of <a class="reference internal" href="#func-shard-backend">func_shard.backend</a> to associate
this shard parameter set with a shard director.</p>
</div>
</div>
<div class="section" id="acknowledgements">
<h3>ACKNOWLEDGEMENTS<a class="headerlink" href="#acknowledgements" title="Permalink to this headline">¶</a></h3>
<p>Development of a previous version of the shard director was partly
sponsored by Deutsche Telekom AG - Products & Innovation.</p>
<p>Development of a previous version of the shard director was partly
sponsored by BILD GmbH & Co KG.</p>
</div>
<div class="section" id="id4">
<h3>COPYRIGHT<a class="headerlink" href="#id4" title="Permalink to this headline">¶</a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>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.
</pre></div>
</div>
</div>
</div>
</div>
<div class="section" id="vmod-vtc">
<span id="vmod-vtc-3"></span><h1>vmod_vtc<a class="headerlink" href="#vmod-vtc" title="Permalink to this headline">¶</a></h1>
<div class="section" id="utility-module-for-varnishtest">
<h2>Utility module for varnishtest<a class="headerlink" href="#utility-module-for-varnishtest" title="Permalink to this headline">¶</a></h2>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Manual section:</th><td class="field-body">3</td>
</tr>
</tbody>
</table>
<div class="section" id="id5">
<h3>SYNOPSIS<a class="headerlink" href="#id5" title="Permalink to this headline">¶</a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">vtc</span> <span class="p">[</span><span class="kn">from</span> <span class="s2">"path"</span><span class="p">]</span> <span class="p">;</span>
<span class="n">VOID</span> <span class="n">barrier_sync</span><span class="p">(</span><span class="n">STRING</span> <span class="n">addr</span><span class="p">,</span> <span class="n">DURATION</span> <span class="n">timeout</span><span class="p">)</span>
<span class="n">BACKEND</span> <span class="n">no_backend</span><span class="p">()</span>
<span class="n">STEVEDORE</span> <span class="n">no_stevedore</span><span class="p">()</span>
<span class="n">IP</span> <span class="n">no_ip</span><span class="p">()</span>
<span class="n">VOID</span> <span class="n">panic</span><span class="p">(</span><span class="n">STRING</span><span class="p">)</span>
<span class="n">VOID</span> <span class="n">sleep</span><span class="p">(</span><span class="n">DURATION</span><span class="p">)</span>
<span class="n">VOID</span> <span class="n">workspace_alloc</span><span class="p">(</span><span class="n">ENUM</span><span class="p">,</span> <span class="n">INT</span> <span class="n">size</span><span class="p">)</span>
<span class="n">INT</span> <span class="n">workspace_free</span><span class="p">(</span><span class="n">ENUM</span><span class="p">)</span>
<span class="n">VOID</span> <span class="n">workspace_snapshot</span><span class="p">(</span><span class="n">ENUM</span><span class="p">)</span>
<span class="n">VOID</span> <span class="n">workspace_reset</span><span class="p">(</span><span class="n">ENUM</span><span class="p">)</span>
<span class="n">BOOL</span> <span class="n">workspace_overflowed</span><span class="p">(</span><span class="n">ENUM</span><span class="p">)</span>
<span class="n">VOID</span> <span class="n">workspace_overflow</span><span class="p">(</span><span class="n">ENUM</span><span class="p">)</span>
<span class="n">INT</span> <span class="n">typesize</span><span class="p">(</span><span class="n">STRING</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="id6">
<h3>CONTENTS<a class="headerlink" href="#id6" title="Permalink to this headline">¶</a></h3>
<ul class="simple">
<li><a class="reference internal" href="#func-barrier-sync"><span class="std std-ref">VOID barrier_sync(STRING addr, DURATION timeout=0)</span></a></li>
<li><a class="reference internal" href="#func-no-backend"><span class="std std-ref">BACKEND no_backend()</span></a></li>
<li><a class="reference internal" href="#func-no-ip"><span class="std std-ref">IP no_ip()</span></a></li>
<li><a class="reference internal" href="#func-no-stevedore"><span class="std std-ref">STEVEDORE no_stevedore()</span></a></li>
<li><a class="reference internal" href="#func-panic"><span class="std std-ref">VOID panic(STRING)</span></a></li>
<li><a class="reference internal" href="#func-sleep"><span class="std std-ref">VOID sleep(DURATION)</span></a></li>
<li><a class="reference internal" href="#func-typesize"><span class="std std-ref">INT typesize(STRING)</span></a></li>
<li><a class="reference internal" href="#func-workspace-alloc"><span class="std std-ref">VOID workspace_alloc(ENUM, INT size)</span></a></li>
<li><a class="reference internal" href="#func-workspace-free"><span class="std std-ref">INT workspace_free(ENUM {client, backend, session, thread})</span></a></li>
<li><a class="reference internal" href="#func-workspace-overflow"><span class="std std-ref">VOID workspace_overflow(ENUM)</span></a></li>
<li><a class="reference internal" href="#func-workspace-overflowed"><span class="std std-ref">BOOL workspace_overflowed(ENUM)</span></a></li>
<li><a class="reference internal" href="#func-workspace-reset"><span class="std std-ref">VOID workspace_reset(ENUM)</span></a></li>
<li><a class="reference internal" href="#func-workspace-snapshot"><span class="std std-ref">VOID workspace_snapshot(ENUM)</span></a></li>
</ul>
</div>
<div class="section" id="id7">
<h3>DESCRIPTION<a class="headerlink" href="#id7" title="Permalink to this headline">¶</a></h3>
<p>The goal for this VMOD is to provide VCL users and VMOD authors means to
test corner cases or reach certain conditions with varnishtest.</p>
<div class="section" id="void-barrier-sync-string-addr-duration-timeout-0">
<span id="func-barrier-sync"></span><h4>VOID barrier_sync(STRING addr, DURATION timeout=0)<a class="headerlink" href="#void-barrier-sync-string-addr-duration-timeout-0" title="Permalink to this headline">¶</a></h4>
<p>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 (<code class="docutils literal notranslate"><span class="pre">process</span></code>) or
log readers (<code class="docutils literal notranslate"><span class="pre">logexpect</span></code>). 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.</p>
<p>Not only is it possible to synchronize between test entities, with the
<code class="docutils literal notranslate"><span class="pre">barrier_sync</span></code> function you can even synchronize VCL code:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sub</span> <span class="n">vcl_recv</span> <span class="p">{</span>
<span class="c1"># wait for some barrier b1 to complete</span>
<span class="n">vtc</span><span class="o">.</span><span class="n">barrier_sync</span><span class="p">(</span><span class="s2">"$</span><span class="si">{b1_sock}</span><span class="s2">"</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<p>If the function fails to synchronize with the barrier for some reason, or if
it reaches the optional timeout, it fails the VCL transaction.</p>
</div>
</div>
<div class="section" id="miscellaneous">
<h3>MISCELLANEOUS<a class="headerlink" href="#miscellaneous" title="Permalink to this headline">¶</a></h3>
<div class="section" id="backend-no-backend">
<span id="func-no-backend"></span><h4>BACKEND no_backend()<a class="headerlink" href="#backend-no-backend" title="Permalink to this headline">¶</a></h4>
<p>Fails at backend selection.</p>
</div>
<div class="section" id="stevedore-no-stevedore">
<span id="func-no-stevedore"></span><h4>STEVEDORE no_stevedore()<a class="headerlink" href="#stevedore-no-stevedore" title="Permalink to this headline">¶</a></h4>
<p>Fails at storage selection.</p>
</div>
<div class="section" id="ip-no-ip">
<span id="func-no-ip"></span><h4>IP no_ip()<a class="headerlink" href="#ip-no-ip" title="Permalink to this headline">¶</a></h4>
<p>Returns a null IP address, not even a bogo_ip.</p>
</div>
<div class="section" id="void-panic-string">
<span id="func-panic"></span><h4>VOID panic(STRING)<a class="headerlink" href="#void-panic-string" title="Permalink to this headline">¶</a></h4>
<p>It can be useful to crash the child process in order to test the robustness
of a VMOD.</p>
</div>
<div class="section" id="void-sleep-duration">
<span id="func-sleep"></span><h4>VOID sleep(DURATION)<a class="headerlink" href="#void-sleep-duration" title="Permalink to this headline">¶</a></h4>
<p>Block the current worker thread.</p>
</div>
</div>
<div class="section" id="workspaces">
<h3>WORKSPACES<a class="headerlink" href="#workspaces" title="Permalink to this headline">¶</a></h3>
<p>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 <code class="docutils literal notranslate"><span class="pre">client</span></code>, <code class="docutils literal notranslate"><span class="pre">backend</span></code>, <code class="docutils literal notranslate"><span class="pre">session</span></code>
and <code class="docutils literal notranslate"><span class="pre">thread</span></code>.</p>
<div class="section" id="void-workspace-alloc-enum-int-size">
<span id="func-workspace-alloc"></span><h4>VOID workspace_alloc(ENUM, INT size)<a class="headerlink" href="#void-workspace-alloc-enum-int-size" title="Permalink to this headline">¶</a></h4>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">VOID</span> <span class="n">workspace_alloc</span><span class="p">(</span>
<span class="n">ENUM</span> <span class="p">{</span><span class="n">client</span><span class="p">,</span> <span class="n">backend</span><span class="p">,</span> <span class="n">session</span><span class="p">,</span> <span class="n">thread</span><span class="p">},</span>
<span class="n">INT</span> <span class="n">size</span>
<span class="p">)</span>
</pre></div>
</div>
<p>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.</p>
</div>
<div class="section" id="int-workspace-free-enum-client-backend-session-thread">
<span id="func-workspace-free"></span><h4>INT workspace_free(ENUM {client, backend, session, thread})<a class="headerlink" href="#int-workspace-free-enum-client-backend-session-thread" title="Permalink to this headline">¶</a></h4>
<p>Find how much unallocated space there is left in a workspace.</p>
</div>
<div class="section" id="void-workspace-snapshot-enum">
<span id="func-workspace-snapshot"></span><h4>VOID workspace_snapshot(ENUM)<a class="headerlink" href="#void-workspace-snapshot-enum" title="Permalink to this headline">¶</a></h4>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">VOID</span> <span class="n">workspace_snapshot</span><span class="p">(</span><span class="n">ENUM</span> <span class="p">{</span><span class="n">client</span><span class="p">,</span> <span class="n">backend</span><span class="p">,</span> <span class="n">session</span><span class="p">,</span> <span class="n">thread</span><span class="p">})</span>
</pre></div>
</div>
<p>Snapshot a workspace. Only one snapshot may be active at a time.</p>
</div>
<div class="section" id="void-workspace-reset-enum">
<span id="func-workspace-reset"></span><h4>VOID workspace_reset(ENUM)<a class="headerlink" href="#void-workspace-reset-enum" title="Permalink to this headline">¶</a></h4>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">VOID</span> <span class="n">workspace_reset</span><span class="p">(</span><span class="n">ENUM</span> <span class="p">{</span><span class="n">client</span><span class="p">,</span> <span class="n">backend</span><span class="p">,</span> <span class="n">session</span><span class="p">,</span> <span class="n">thread</span><span class="p">})</span>
</pre></div>
</div>
<p>Reset to the previous snapshot of a workspace, it must be the same workspace
too.</p>
</div>
<div class="section" id="bool-workspace-overflowed-enum">
<span id="func-workspace-overflowed"></span><h4>BOOL workspace_overflowed(ENUM)<a class="headerlink" href="#bool-workspace-overflowed-enum" title="Permalink to this headline">¶</a></h4>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">BOOL</span> <span class="n">workspace_overflowed</span><span class="p">(</span><span class="n">ENUM</span> <span class="p">{</span><span class="n">client</span><span class="p">,</span> <span class="n">backend</span><span class="p">,</span> <span class="n">session</span><span class="p">,</span> <span class="n">thread</span><span class="p">})</span>
</pre></div>
</div>
<p>Find whether the workspace overflow mark is set or not.</p>
</div>
<div class="section" id="void-workspace-overflow-enum">
<span id="func-workspace-overflow"></span><h4>VOID workspace_overflow(ENUM)<a class="headerlink" href="#void-workspace-overflow-enum" title="Permalink to this headline">¶</a></h4>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">VOID</span> <span class="n">workspace_overflow</span><span class="p">(</span><span class="n">ENUM</span> <span class="p">{</span><span class="n">client</span><span class="p">,</span> <span class="n">backend</span><span class="p">,</span> <span class="n">session</span><span class="p">,</span> <span class="n">thread</span><span class="p">})</span>
</pre></div>
</div>
<p>Mark a workspace as overflowed.</p>
</div>
<div class="section" id="int-typesize-string">
<span id="func-typesize"></span><h4>INT typesize(STRING)<a class="headerlink" href="#int-typesize-string" title="Permalink to this headline">¶</a></h4>
<p>Returns the size in bytes of a collection of C-datatypes:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">'p'</span></code>: pointer</li>
<li><code class="docutils literal notranslate"><span class="pre">'i'</span></code>: <code class="docutils literal notranslate"><span class="pre">int</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">'d'</span></code>: <code class="docutils literal notranslate"><span class="pre">double</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">'f'</span></code>: <code class="docutils literal notranslate"><span class="pre">float</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">'l'</span></code>: <code class="docutils literal notranslate"><span class="pre">long</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">'s'</span></code>: <code class="docutils literal notranslate"><span class="pre">short</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">'z'</span></code>: <code class="docutils literal notranslate"><span class="pre">size_t</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">'o'</span></code>: <code class="docutils literal notranslate"><span class="pre">off_t</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">'j'</span></code>: <code class="docutils literal notranslate"><span class="pre">intmax_t</span></code></li>
</ul>
<p>This can be useful for VMOD authors in conjunction with workspace operations.</p>
</div>
</div>
<div class="section" id="id8">
<h3>SEE ALSO<a class="headerlink" href="#id8" title="Permalink to this headline">¶</a></h3>
<ul class="simple">
<li><a class="reference internal" href="vtc.html#vtc-7"><span class="std std-ref">VTC</span></a></li>
<li><a class="reference internal" href="vcl.html#vcl-7"><span class="std std-ref">VCL</span></a></li>
</ul>
</div>
<div class="section" id="id9">
<h3>COPYRIGHT<a class="headerlink" href="#id9" title="Permalink to this headline">¶</a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>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.
</pre></div>
</div>
</div>
</div>
</div>
<div class="section" id="vmod-purge">
<span id="vmod-purge-3"></span><h1>vmod_purge<a class="headerlink" href="#vmod-purge" title="Permalink to this headline">¶</a></h1>
<div class="section" id="varnish-purge-module">
<h2>Varnish Purge Module<a class="headerlink" href="#varnish-purge-module" title="Permalink to this headline">¶</a></h2>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Manual section:</th><td class="field-body">3</td>
</tr>
</tbody>
</table>
<div class="section" id="id10">
<h3>SYNOPSIS<a class="headerlink" href="#id10" title="Permalink to this headline">¶</a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">purge</span> <span class="p">[</span><span class="kn">from</span> <span class="s2">"path"</span><span class="p">]</span> <span class="p">;</span>
<span class="n">INT</span> <span class="n">hard</span><span class="p">()</span>
<span class="n">INT</span> <span class="n">soft</span><span class="p">(</span><span class="n">DURATION</span> <span class="n">ttl</span><span class="p">,</span> <span class="n">DURATION</span> <span class="n">grace</span><span class="p">,</span> <span class="n">DURATION</span> <span class="n">keep</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="id11">
<h3>CONTENTS<a class="headerlink" href="#id11" title="Permalink to this headline">¶</a></h3>
<ul class="simple">
<li><a class="reference internal" href="#func-hard"><span class="std std-ref">INT hard()</span></a></li>
<li><a class="reference internal" href="#func-soft"><span class="std std-ref">INT soft(DURATION ttl, DURATION grace, DURATION keep)</span></a></li>
</ul>
</div>
<div class="section" id="id12">
<h3>DESCRIPTION<a class="headerlink" href="#id12" title="Permalink to this headline">¶</a></h3>
<p><cite>vmod_purge</cite> contains functions that offer a finer-grained control than the
<code class="docutils literal notranslate"><span class="pre">purge</span></code> transition in <code class="docutils literal notranslate"><span class="pre">vcl_recv</span></code>. The functions can only be called from
<code class="docutils literal notranslate"><span class="pre">vcl_hit</span></code> or <code class="docutils literal notranslate"><span class="pre">vcl_miss</span></code> and they should in general be used in both to
ensure that all variants of a same object are taken care of.</p>
</div>
<div class="section" id="example">
<h3>EXAMPLE<a class="headerlink" href="#example" title="Permalink to this headline">¶</a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>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);
}
}
</pre></div>
</div>
<div class="section" id="int-hard">
<span id="func-hard"></span><h4>INT hard()<a class="headerlink" href="#int-hard" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>This is equivalent to <code class="docutils literal notranslate"><span class="pre">return(purge)</span></code> but explicitly called from
<code class="docutils literal notranslate"><span class="pre">vcl_hit</span></code> and <code class="docutils literal notranslate"><span class="pre">vcl_miss</span></code>. It returns the number of purged objects.</dd>
<dt>Example</dt>
<dd>set req.http.purged = purge.hard();</dd>
</dl>
</div>
<div class="section" id="int-soft-duration-ttl-duration-grace-duration-keep">
<span id="func-soft"></span><h4>INT soft(DURATION ttl, DURATION grace, DURATION keep)<a class="headerlink" href="#int-soft-duration-ttl-duration-grace-duration-keep" title="Permalink to this headline">¶</a></h4>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">INT</span> <span class="n">soft</span><span class="p">(</span><span class="n">DURATION</span> <span class="n">ttl</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">DURATION</span> <span class="n">grace</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span> <span class="n">DURATION</span> <span class="n">keep</span><span class="o">=-</span><span class="mi">1</span><span class="p">)</span>
</pre></div>
</div>
<dl class="docutils">
<dt>Description</dt>
<dd>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 <code class="docutils literal notranslate"><span class="pre">vcl_hit</span></code>
or <code class="docutils literal notranslate"><span class="pre">vcl_miss</span></code>. It returns the number of soft-purged objects.</dd>
</dl>
</div>
</div>
<div class="section" id="id13">
<h3>SEE ALSO<a class="headerlink" href="#id13" title="Permalink to this headline">¶</a></h3>
<ul class="simple">
<li><a class="reference internal" href="vcl.html#vcl-7"><span class="std std-ref">VCL</span></a></li>
</ul>
</div>
<div class="section" id="id14">
<h3>COPYRIGHT<a class="headerlink" href="#id14" title="Permalink to this headline">¶</a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>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.
</pre></div>
</div>
</div>
</div>
</div>
<div class="section" id="vmod-blob">
<span id="vmod-blob-3"></span><h1>vmod_blob<a class="headerlink" href="#vmod-blob" title="Permalink to this headline">¶</a></h1>
<div class="section" id="utilities-for-the-vcl-blob-type">
<h2>Utilities for the VCL blob type<a class="headerlink" href="#utilities-for-the-vcl-blob-type" title="Permalink to this headline">¶</a></h2>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Manual section:</th><td class="field-body">3</td>
</tr>
</tbody>
</table>
<div class="section" id="id15">
<h3>SYNOPSIS<a class="headerlink" href="#id15" title="Permalink to this headline">¶</a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">blob</span> <span class="p">[</span><span class="kn">from</span> <span class="s2">"path"</span><span class="p">]</span> <span class="p">;</span>
<span class="n">BLOB</span> <span class="n">decode</span><span class="p">(</span><span class="n">ENUM</span> <span class="n">decoding</span><span class="p">,</span> <span class="n">INT</span> <span class="n">length</span><span class="p">,</span> <span class="n">STRING</span> <span class="n">encoded</span><span class="p">)</span>
<span class="n">STRING</span> <span class="n">encode</span><span class="p">(</span><span class="n">ENUM</span> <span class="n">encoding</span><span class="p">,</span> <span class="n">ENUM</span> <span class="n">case</span><span class="p">,</span> <span class="n">BLOB</span> <span class="n">blob</span><span class="p">)</span>
<span class="n">STRING</span> <span class="n">transcode</span><span class="p">(</span><span class="n">ENUM</span> <span class="n">decoding</span><span class="p">,</span> <span class="n">ENUM</span> <span class="n">encoding</span><span class="p">,</span> <span class="n">ENUM</span> <span class="n">case</span><span class="p">,</span> <span class="n">INT</span> <span class="n">length</span><span class="p">,</span> <span class="n">STRING</span> <span class="n">encoded</span><span class="p">)</span>
<span class="n">BOOL</span> <span class="n">same</span><span class="p">(</span><span class="n">BLOB</span><span class="p">,</span> <span class="n">BLOB</span><span class="p">)</span>
<span class="n">BOOL</span> <span class="n">equal</span><span class="p">(</span><span class="n">BLOB</span><span class="p">,</span> <span class="n">BLOB</span><span class="p">)</span>
<span class="n">INT</span> <span class="n">length</span><span class="p">(</span><span class="n">BLOB</span><span class="p">)</span>
<span class="n">BLOB</span> <span class="n">sub</span><span class="p">(</span><span class="n">BLOB</span><span class="p">,</span> <span class="n">BYTES</span> <span class="n">length</span><span class="p">,</span> <span class="n">BYTES</span> <span class="n">offset</span><span class="p">)</span>
<span class="n">new</span> <span class="n">xblob</span> <span class="o">=</span> <span class="n">blob</span><span class="o">.</span><span class="n">blob</span><span class="p">(</span><span class="n">ENUM</span> <span class="n">decoding</span><span class="p">,</span> <span class="n">STRING</span> <span class="n">encoded</span><span class="p">)</span>
<span class="n">BLOB</span> <span class="n">xblob</span><span class="o">.</span><span class="n">get</span><span class="p">()</span>
<span class="n">STRING</span> <span class="n">xblob</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">ENUM</span> <span class="n">encoding</span><span class="p">,</span> <span class="n">ENUM</span> <span class="n">case</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="id16">
<h3>CONTENTS<a class="headerlink" href="#id16" title="Permalink to this headline">¶</a></h3>
<ul class="simple">
<li><a class="reference internal" href="#obj-blob"><span class="std std-ref">new xblob = blob.blob(ENUM decoding, STRING encoded)</span></a></li>
<li><a class="reference internal" href="#func-blob-encode"><span class="std std-ref">STRING xblob.encode(ENUM encoding, ENUM case)</span></a></li>
<li><a class="reference internal" href="#func-blob-get"><span class="std std-ref">BLOB xblob.get()</span></a></li>
<li><a class="reference internal" href="#func-decode"><span class="std std-ref">BLOB decode(ENUM decoding, INT length, STRING encoded)</span></a></li>
<li><a class="reference internal" href="#func-encode"><span class="std std-ref">STRING encode(ENUM encoding, ENUM case, BLOB blob)</span></a></li>
<li><a class="reference internal" href="#func-equal"><span class="std std-ref">BOOL equal(BLOB, BLOB)</span></a></li>
<li><a class="reference internal" href="#func-length"><span class="std std-ref">INT length(BLOB)</span></a></li>
<li><a class="reference internal" href="#func-same"><span class="std std-ref">BOOL same(BLOB, BLOB)</span></a></li>
<li><a class="reference internal" href="#func-sub"><span class="std std-ref">BLOB sub(BLOB, BYTES length, BYTES offset=0)</span></a></li>
<li><a class="reference internal" href="#func-transcode"><span class="std std-ref">transcode(…)</span></a></li>
</ul>
</div>
<div class="section" id="id17">
<h3>DESCRIPTION<a class="headerlink" href="#id17" title="Permalink to this headline">¶</a></h3>
<p>This VMOD provides utility functions and an object for the VCL data
type BLOB, which may contain arbitrary data of any length.</p>
<p>Examples:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sub</span> <span class="n">vcl_init</span> <span class="p">{</span>
<span class="c1"># Create blob objects from encodings such as base64 or hex.</span>
<span class="n">new</span> <span class="n">myblob</span> <span class="o">=</span> <span class="n">blob</span><span class="o">.</span><span class="n">blob</span><span class="p">(</span><span class="n">BASE64</span><span class="p">,</span> <span class="s2">"Zm9vYmFy"</span><span class="p">);</span>
<span class="n">new</span> <span class="n">yourblob</span> <span class="o">=</span> <span class="n">blob</span><span class="o">.</span><span class="n">blob</span><span class="p">(</span><span class="n">encoded</span><span class="o">=</span><span class="s2">"666F6F"</span><span class="p">,</span> <span class="n">decoding</span><span class="o">=</span><span class="n">HEX</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">sub</span> <span class="n">vcl_deliver</span> <span class="p">{</span>
<span class="c1"># The .get() method retrieves the BLOB from an object.</span>
<span class="nb">set</span> <span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">MyBlob</span><span class="o">-</span><span class="n">As</span><span class="o">-</span><span class="n">Hex</span>
<span class="o">=</span> <span class="n">blob</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">blob</span><span class="o">=</span><span class="n">myblob</span><span class="o">.</span><span class="n">get</span><span class="p">(),</span> <span class="n">encoding</span><span class="o">=</span><span class="n">HEX</span><span class="p">);</span>
<span class="c1"># The .encode() method efficiently retrieves an encoding.</span>
<span class="nb">set</span> <span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">YourBlob</span><span class="o">-</span><span class="n">As</span><span class="o">-</span><span class="n">Base64</span> <span class="o">=</span> <span class="n">yourblob</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">BASE64</span><span class="p">);</span>
<span class="c1"># decode() and encode() functions convert blobs to text and</span>
<span class="c1"># vice versa at runtime.</span>
<span class="nb">set</span> <span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">Base64</span><span class="o">-</span><span class="n">Encoded</span>
<span class="o">=</span> <span class="n">blob</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">BASE64</span><span class="p">,</span>
<span class="n">blob</span><span class="o">=</span><span class="n">blob</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="n">HEX</span><span class="p">,</span>
<span class="n">encoded</span><span class="o">=</span><span class="n">req</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">Hex</span><span class="o">-</span><span class="n">Encoded</span><span class="p">));</span>
<span class="p">}</span>
<span class="n">sub</span> <span class="n">vcl_recv</span> <span class="p">{</span>
<span class="c1"># transcode() converts from one encoding to another.</span>
<span class="c1"># case=UPPER specifies upper-case hex digits A-F.</span>
<span class="nb">set</span> <span class="n">req</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">Hex</span><span class="o">-</span><span class="n">Encoded</span>
<span class="o">=</span> <span class="n">blob</span><span class="o">.</span><span class="n">transcode</span><span class="p">(</span><span class="n">decoding</span><span class="o">=</span><span class="n">BASE64</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="n">HEX</span><span class="p">,</span>
<span class="n">case</span><span class="o">=</span><span class="n">UPPER</span><span class="p">,</span> <span class="n">encoded</span><span class="o">=</span><span class="s2">"YmF6"</span><span class="p">);</span>
<span class="c1"># transcode() from URL to IDENTITY effects a URL decode.</span>
<span class="nb">set</span> <span class="n">req</span><span class="o">.</span><span class="n">url</span> <span class="o">=</span> <span class="n">blob</span><span class="o">.</span><span class="n">transcode</span><span class="p">(</span><span class="n">encoded</span><span class="o">=</span><span class="n">req</span><span class="o">.</span><span class="n">url</span><span class="p">,</span> <span class="n">decoding</span><span class="o">=</span><span class="n">URL</span><span class="p">);</span>
<span class="c1"># transcode() from IDENTITY to URL effects a URL encode.</span>
<span class="nb">set</span> <span class="n">req</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">url_urlcoded</span>
<span class="o">=</span> <span class="n">blob</span><span class="o">.</span><span class="n">transcode</span><span class="p">(</span><span class="n">encoded</span><span class="o">=</span><span class="n">req</span><span class="o">.</span><span class="n">url</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="n">URL</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="encoding-schemes">
<h3>ENCODING SCHEMES<a class="headerlink" href="#encoding-schemes" title="Permalink to this headline">¶</a></h3>
<p>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.</p>
<p>ENUM values for an encoding scheme can be one of:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">IDENTITY</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">BASE64</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">BASE64URL</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">BASE64URLNOPAD</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">HEX</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">URL</span></code></li>
</ul>
<p>Empty strings are decoded into a “null blob” (of length 0),
and conversely a null blob is encoded as the empty string.</p>
<p>For encodings with <code class="docutils literal notranslate"><span class="pre">HEX</span></code> or <code class="docutils literal notranslate"><span class="pre">URL</span></code>, you may also specify a <code class="docutils literal notranslate"><span class="pre">case</span></code>
ENUM with one of the values <code class="docutils literal notranslate"><span class="pre">LOWER</span></code>, <code class="docutils literal notranslate"><span class="pre">UPPER</span></code> or <code class="docutils literal notranslate"><span class="pre">DEFAULT</span></code> to
produce a string with lower- or uppercase hex digits (in <code class="docutils literal notranslate"><span class="pre">[a-f]</span></code> or
<code class="docutils literal notranslate"><span class="pre">[A-F]</span></code>). The default value for <code class="docutils literal notranslate"><span class="pre">case</span></code> is <code class="docutils literal notranslate"><span class="pre">DEFAULT</span></code>, which for
<code class="docutils literal notranslate"><span class="pre">HEX</span></code> and <code class="docutils literal notranslate"><span class="pre">URL</span></code> means the same as <code class="docutils literal notranslate"><span class="pre">LOWER</span></code>.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">case</span></code> ENUM is not relevant for decodings; <code class="docutils literal notranslate"><span class="pre">HEX</span></code> or <code class="docutils literal notranslate"><span class="pre">URL</span></code>
strings to be decoded as BLOBs may have hex digits in either case, or
in mixed case.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">case</span></code> ENUM MUST be set to <code class="docutils literal notranslate"><span class="pre">DEFAULT</span></code> for the other encodings
(BASE64* and IDENTITY). You cannot, for example, produce an uppercase
string by using the IDENTITY scheme with <code class="docutils literal notranslate"><span class="pre">case=UPPER</span></code>. To change the
case of a string, use the <code class="docutils literal notranslate"><span class="pre">toupper</span></code> or <code class="docutils literal notranslate"><span class="pre">tolower</span></code> functions from
<a class="reference internal" href="#vmod-std-3"><span class="std std-ref">vmod_std</span></a>.</p>
<div class="section" id="identity">
<h4>IDENTITY<a class="headerlink" href="#identity" title="Permalink to this headline">¶</a></h4>
<p>The simplest encoding converts between the BLOB and STRING data types,
leaving the contents byte-identical.</p>
<p>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:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Decode from the hex encoding for "foo\0bar".</span>
<span class="c1"># The header will be seen as "foo".</span>
<span class="nb">set</span> <span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">Trunced</span><span class="o">-</span><span class="n">Foo1</span>
<span class="o">=</span> <span class="n">blob</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">IDENTITY</span><span class="p">,</span> <span class="n">blob</span><span class="o">=</span><span class="n">blob</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="n">HEX</span><span class="p">,</span>
<span class="n">encoded</span><span class="o">=</span><span class="s2">"666f6f00626172"</span><span class="p">));</span>
</pre></div>
</div>
<p>IDENTITY is the default encoding and decoding. So the above can also
be written as:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Decode from the hex encoding for "foo\0bar".</span>
<span class="c1"># The header will be seen as "foo".</span>
<span class="nb">set</span> <span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">Trunced</span><span class="o">-</span><span class="n">Foo2</span>
<span class="o">=</span> <span class="n">blob</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">blob</span><span class="o">=</span><span class="n">blob</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="n">HEX</span><span class="p">,</span> <span class="n">encoded</span><span class="o">=</span><span class="s2">"666f6f00626172"</span><span class="p">));</span>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">case</span></code> ENUM MUST be set to <code class="docutils literal notranslate"><span class="pre">DEFAULT</span></code> for <code class="docutils literal notranslate"><span class="pre">IDENTITY</span></code> encodings.</p>
</div>
<div class="section" id="base64">
<h4>BASE64*<a class="headerlink" href="#base64" title="Permalink to this headline">¶</a></h4>
<p>The base64 encoding schemes use 4 characters to encode 3 bytes. There
are no newlines or maximal line lengths – whitespace is not
permitted.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">BASE64</span></code> encoding uses the alphanumeric characters, <code class="docutils literal notranslate"><span class="pre">+</span></code> and
<code class="docutils literal notranslate"><span class="pre">/</span></code>; and encoded strings are padded with the <code class="docutils literal notranslate"><span class="pre">=</span></code> character so that
their length is always a multiple of four.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">BASE64URL</span></code> encoding also uses the alphanumeric characters, but
<code class="docutils literal notranslate"><span class="pre">-</span></code> and <code class="docutils literal notranslate"><span class="pre">_</span></code> instead of <code class="docutils literal notranslate"><span class="pre">+</span></code> and <code class="docutils literal notranslate"><span class="pre">/</span></code>, so that an encoded string
can be used safely in a URL. This scheme also uses the padding
character <code class="docutils literal notranslate"><span class="pre">=</span></code>.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">BASE64URLNOPAD</span></code> encoding uses the same alphabet as
<code class="docutils literal notranslate"><span class="pre">BASE6URL</span></code>, but leaves out the padding. Thus the length of an
encoding with this scheme is not necessarily a multiple of four.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">case</span></code> ENUM MUST be set to <code class="docutils literal notranslate"><span class="pre">DEFAULT</span></code> for for all of the
<code class="docutils literal notranslate"><span class="pre">BASE64*</span></code> encodings.</p>
</div>
<div class="section" id="hex">
<h4>HEX<a class="headerlink" href="#hex" title="Permalink to this headline">¶</a></h4>
<p>The <code class="docutils literal notranslate"><span class="pre">HEX</span></code> encoding scheme converts hex strings into blobs and vice
versa. For encodings, you may use the <code class="docutils literal notranslate"><span class="pre">case</span></code> ENUM to specify upper-
or lowercase hex digits <code class="docutils literal notranslate"><span class="pre">A</span></code> through <code class="docutils literal notranslate"><span class="pre">f</span></code> (default <code class="docutils literal notranslate"><span class="pre">DEFAULT</span></code>,
which means the same as <code class="docutils literal notranslate"><span class="pre">LOWER</span></code>). A prefix such as <code class="docutils literal notranslate"><span class="pre">0x</span></code> is not
used for an encoding and is illegal for a decoding.</p>
<p>If a hex string to be decoded has an odd number of digits, it is
decoded as if a <code class="docutils literal notranslate"><span class="pre">0</span></code> is prepended to it; that is, the first digit is
interpreted as representing the least significant nibble of the first
byte. For example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># The concatenated string is "abcdef0", and is decoded as "0abcdef0".</span>
<span class="nb">set</span> <span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">First</span> <span class="o">=</span> <span class="s2">"abc"</span><span class="p">;</span>
<span class="nb">set</span> <span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">Second</span> <span class="o">=</span> <span class="s2">"def0"</span><span class="p">;</span>
<span class="nb">set</span> <span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">Hex</span><span class="o">-</span><span class="n">Decoded</span>
<span class="o">=</span> <span class="n">blob</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">HEX</span><span class="p">,</span> <span class="n">blob</span><span class="o">=</span><span class="n">blob</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="n">HEX</span><span class="p">,</span>
<span class="n">encoded</span><span class="o">=</span><span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">First</span> <span class="o">+</span> <span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">Second</span><span class="p">));</span>
</pre></div>
</div>
</div>
<div class="section" id="url">
<h4>URL<a class="headerlink" href="#url" title="Permalink to this headline">¶</a></h4>
<p>The <code class="docutils literal notranslate"><span class="pre">URL</span></code> decoding replaces any <code class="docutils literal notranslate"><span class="pre">%<2-hex-digits></span></code> substrings with
the binary value of the hexadecimal number after the % sign.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">URL</span></code> encoding implements “percent encoding” as per RFC3986. The
<code class="docutils literal notranslate"><span class="pre">case</span></code> ENUM determines the case of the hex digits, but does not
affect alphabetic characters that are not percent-encoded.</p>
</div>
<div class="section" id="blob-decode-enum-decoding-int-length-string-encoded">
<span id="func-decode"></span><h4>BLOB decode(ENUM decoding, INT length, STRING encoded)<a class="headerlink" href="#blob-decode-enum-decoding-int-length-string-encoded" title="Permalink to this headline">¶</a></h4>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">BLOB</span> <span class="n">decode</span><span class="p">(</span>
<span class="n">ENUM</span> <span class="p">{</span><span class="n">IDENTITY</span><span class="p">,</span> <span class="n">BASE64</span><span class="p">,</span> <span class="n">BASE64URL</span><span class="p">,</span> <span class="n">BASE64URLNOPAD</span><span class="p">,</span> <span class="n">HEX</span><span class="p">,</span> <span class="n">URL</span><span class="p">}</span> <span class="n">decoding</span><span class="o">=</span><span class="n">IDENTITY</span><span class="p">,</span>
<span class="n">INT</span> <span class="n">length</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
<span class="n">STRING</span> <span class="n">encoded</span>
<span class="p">)</span>
</pre></div>
</div>
<p>Returns the BLOB derived from the string <code class="docutils literal notranslate"><span class="pre">encoded</span></code> according to the
scheme specified by <code class="docutils literal notranslate"><span class="pre">decoding</span></code>.</p>
<p>If <code class="docutils literal notranslate"><span class="pre">length</span></code> > 0, only decode the first <code class="docutils literal notranslate"><span class="pre">length</span></code> characters of the
encoded string. If <code class="docutils literal notranslate"><span class="pre">length</span></code> <= 0 or greater than the length of the
string, then decode the entire string. The default value of <code class="docutils literal notranslate"><span class="pre">length</span></code>
is 0.</p>
<p><code class="docutils literal notranslate"><span class="pre">decoding</span></code> defaults to IDENTITY.</p>
<p>Example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">blob</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="n">BASE64</span><span class="p">,</span> <span class="n">encoded</span><span class="o">=</span><span class="s2">"Zm9vYmFyYmF6"</span><span class="p">);</span>
<span class="c1"># same with named parameters</span>
<span class="n">blob</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="n">encoded</span><span class="o">=</span><span class="s2">"Zm9vYmFyYmF6"</span><span class="p">,</span> <span class="n">decoding</span><span class="o">=</span><span class="n">BASE64</span><span class="p">);</span>
<span class="c1"># convert string to blob</span>
<span class="n">blob</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="n">encoded</span><span class="o">=</span><span class="s2">"foo"</span><span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="string-encode-enum-encoding-enum-case-blob-blob">
<span id="func-encode"></span><h4>STRING encode(ENUM encoding, ENUM case, BLOB blob)<a class="headerlink" href="#string-encode-enum-encoding-enum-case-blob-blob" title="Permalink to this headline">¶</a></h4>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">STRING</span> <span class="n">encode</span><span class="p">(</span>
<span class="n">ENUM</span> <span class="p">{</span><span class="n">IDENTITY</span><span class="p">,</span> <span class="n">BASE64</span><span class="p">,</span> <span class="n">BASE64URL</span><span class="p">,</span> <span class="n">BASE64URLNOPAD</span><span class="p">,</span> <span class="n">HEX</span><span class="p">,</span> <span class="n">URL</span><span class="p">}</span> <span class="n">encoding</span><span class="o">=</span><span class="n">IDENTITY</span><span class="p">,</span>
<span class="n">ENUM</span> <span class="p">{</span><span class="n">LOWER</span><span class="p">,</span> <span class="n">UPPER</span><span class="p">,</span> <span class="n">DEFAULT</span><span class="p">}</span> <span class="n">case</span><span class="o">=</span><span class="n">DEFAULT</span><span class="p">,</span>
<span class="n">BLOB</span> <span class="n">blob</span>
<span class="p">)</span>
</pre></div>
</div>
<p>Returns a string representation of the BLOB <code class="docutils literal notranslate"><span class="pre">blob</span></code> as specified by
<code class="docutils literal notranslate"><span class="pre">encoding</span></code>. <code class="docutils literal notranslate"><span class="pre">case</span></code> determines the case of hex digits for the
<code class="docutils literal notranslate"><span class="pre">HEX</span></code> and <code class="docutils literal notranslate"><span class="pre">URL</span></code> encodings, and is ignored for the other encodings.</p>
<p><code class="docutils literal notranslate"><span class="pre">encoding</span></code> defaults to IDENTITY, and <code class="docutils literal notranslate"><span class="pre">case</span></code> defaults to DEFAULT.
DEFAULT is interpreted as LOWER for the HEX and URL encodings, and is
the required value for the other encodings.</p>
<p>Example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">set</span> <span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">encode1</span>
<span class="o">=</span> <span class="n">blob</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">HEX</span><span class="p">,</span>
<span class="n">blob</span><span class="o">=</span><span class="n">blob</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="n">BASE64</span><span class="p">,</span> <span class="n">encoded</span><span class="o">=</span><span class="s2">"Zm9vYmFyYmF6"</span><span class="p">));</span>
<span class="c1"># same with named parameters</span>
<span class="nb">set</span> <span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">encode2</span>
<span class="o">=</span> <span class="n">blob</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">blob</span><span class="o">=</span><span class="n">blob</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="n">encoded</span><span class="o">=</span><span class="s2">"Zm9vYmFyYmF6"</span><span class="p">,</span>
<span class="n">decoding</span><span class="o">=</span><span class="n">BASE64</span><span class="p">),</span>
<span class="n">encoding</span><span class="o">=</span><span class="n">HEX</span><span class="p">);</span>
<span class="c1"># convert blob to string</span>
<span class="nb">set</span> <span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">encode3</span>
<span class="o">=</span> <span class="n">blob</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">blob</span><span class="o">=</span><span class="n">blob</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="n">encoded</span><span class="o">=</span><span class="s2">"foo"</span><span class="p">));</span>
</pre></div>
</div>
</div>
<div class="section" id="transcode">
<span id="func-transcode"></span><h4>transcode(…)<a class="headerlink" href="#transcode" title="Permalink to this headline">¶</a></h4>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">STRING</span> <span class="n">transcode</span><span class="p">(</span>
<span class="n">ENUM</span> <span class="p">{</span><span class="n">IDENTITY</span><span class="p">,</span> <span class="n">BASE64</span><span class="p">,</span> <span class="n">BASE64URL</span><span class="p">,</span> <span class="n">BASE64URLNOPAD</span><span class="p">,</span> <span class="n">HEX</span><span class="p">,</span> <span class="n">URL</span><span class="p">}</span> <span class="n">decoding</span><span class="o">=</span><span class="n">IDENTITY</span><span class="p">,</span>
<span class="n">ENUM</span> <span class="p">{</span><span class="n">IDENTITY</span><span class="p">,</span> <span class="n">BASE64</span><span class="p">,</span> <span class="n">BASE64URL</span><span class="p">,</span> <span class="n">BASE64URLNOPAD</span><span class="p">,</span> <span class="n">HEX</span><span class="p">,</span> <span class="n">URL</span><span class="p">}</span> <span class="n">encoding</span><span class="o">=</span><span class="n">IDENTITY</span><span class="p">,</span>
<span class="n">ENUM</span> <span class="p">{</span><span class="n">LOWER</span><span class="p">,</span> <span class="n">UPPER</span><span class="p">,</span> <span class="n">DEFAULT</span><span class="p">}</span> <span class="n">case</span><span class="o">=</span><span class="n">DEFAULT</span><span class="p">,</span>
<span class="n">INT</span> <span class="n">length</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
<span class="n">STRING</span> <span class="n">encoded</span>
<span class="p">)</span>
</pre></div>
</div>
<p>Translates from one encoding to another, by first decoding the string
<code class="docutils literal notranslate"><span class="pre">encoded</span></code> according to the scheme <code class="docutils literal notranslate"><span class="pre">decoding</span></code>, and then returning
the encoding of the resulting blob according to the scheme
<code class="docutils literal notranslate"><span class="pre">encoding</span></code>. <code class="docutils literal notranslate"><span class="pre">case</span></code> determines the case of hex digits for the
<code class="docutils literal notranslate"><span class="pre">HEX</span></code> and <code class="docutils literal notranslate"><span class="pre">URL</span></code> encodings, and is ignored for other encodings.</p>
<p>As with <code class="docutils literal notranslate"><span class="pre">decode()</span></code>: If <code class="docutils literal notranslate"><span class="pre">length</span></code> > 0, only decode the first
<code class="docutils literal notranslate"><span class="pre">length</span></code> characters of the encoded string, otherwise decode the
entire string. The default value of <code class="docutils literal notranslate"><span class="pre">length</span></code> is 0.</p>
<p><code class="docutils literal notranslate"><span class="pre">decoding</span></code> and <code class="docutils literal notranslate"><span class="pre">encoding</span></code> default to IDENTITY, and <code class="docutils literal notranslate"><span class="pre">case</span></code>
defaults to DEFAULT. DEFAULT is interpreted as LOWER for the HEX and
URL encodings, and is the required value for the other encodings.</p>
<p>Example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">set</span> <span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">Hex2Base64</span><span class="o">-</span><span class="mi">1</span>
<span class="o">=</span> <span class="n">blob</span><span class="o">.</span><span class="n">transcode</span><span class="p">(</span><span class="n">HEX</span><span class="p">,</span> <span class="n">BASE64</span><span class="p">,</span> <span class="n">encoded</span><span class="o">=</span><span class="s2">"666f6f"</span><span class="p">);</span>
<span class="c1"># same with named parameters</span>
<span class="nb">set</span> <span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">Hex2Base64</span><span class="o">-</span><span class="mi">2</span>
<span class="o">=</span> <span class="n">blob</span><span class="o">.</span><span class="n">transcode</span><span class="p">(</span><span class="n">encoded</span><span class="o">=</span><span class="s2">"666f6f"</span><span class="p">,</span>
<span class="n">encoding</span><span class="o">=</span><span class="n">BASE64</span><span class="p">,</span> <span class="n">decoding</span><span class="o">=</span><span class="n">HEX</span><span class="p">);</span>
<span class="c1"># URL decode -- recall that IDENTITY is the default encoding.</span>
<span class="nb">set</span> <span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">urldecoded</span>
<span class="o">=</span> <span class="n">blob</span><span class="o">.</span><span class="n">transcode</span><span class="p">(</span><span class="n">encoded</span><span class="o">=</span><span class="s2">"foo%20bar"</span><span class="p">,</span> <span class="n">decoding</span><span class="o">=</span><span class="n">URL</span><span class="p">);</span>
<span class="c1"># URL encode</span>
<span class="nb">set</span> <span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">urlencoded</span>
<span class="o">=</span> <span class="n">blob</span><span class="o">.</span><span class="n">transcode</span><span class="p">(</span><span class="n">encoded</span><span class="o">=</span><span class="s2">"foo bar"</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="n">URL</span><span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="bool-same-blob-blob">
<span id="func-same"></span><h4>BOOL same(BLOB, BLOB)<a class="headerlink" href="#bool-same-blob-blob" title="Permalink to this headline">¶</a></h4>
<p>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.</p>
<p>If the BLOBs are both empty (length is 0 and/or the internal pointer
is NULL), then <code class="docutils literal notranslate"><span class="pre">same()</span></code> returns <code class="docutils literal notranslate"><span class="pre">true</span></code>. If any non-empty BLOB
is compared to an empty BLOB, then <code class="docutils literal notranslate"><span class="pre">same()</span></code> returns <code class="docutils literal notranslate"><span class="pre">false</span></code>.</p>
</div>
<div class="section" id="bool-equal-blob-blob">
<span id="func-equal"></span><h4>BOOL equal(BLOB, BLOB)<a class="headerlink" href="#bool-equal-blob-blob" title="Permalink to this headline">¶</a></h4>
<p>Returns true if and only if the two BLOB arguments have equal contents
(possibly in different memory regions).</p>
<p>As with <code class="docutils literal notranslate"><span class="pre">same()</span></code>: If the BLOBs are both empty, then <code class="docutils literal notranslate"><span class="pre">equal()</span></code>
returns <code class="docutils literal notranslate"><span class="pre">true</span></code>. If any non-empty BLOB is compared to an empty BLOB,
then <code class="docutils literal notranslate"><span class="pre">equal()</span></code> returns <code class="docutils literal notranslate"><span class="pre">false</span></code>.</p>
</div>
<div class="section" id="int-length-blob">
<span id="func-length"></span><h4>INT length(BLOB)<a class="headerlink" href="#int-length-blob" title="Permalink to this headline">¶</a></h4>
<p>Returns the length of the BLOB.</p>
</div>
<div class="section" id="blob-sub-blob-bytes-length-bytes-offset-0">
<span id="func-sub"></span><h4>BLOB sub(BLOB, BYTES length, BYTES offset=0)<a class="headerlink" href="#blob-sub-blob-bytes-length-bytes-offset-0" title="Permalink to this headline">¶</a></h4>
<p>Returns a new BLOB formed from <code class="docutils literal notranslate"><span class="pre">length</span></code> bytes of the BLOB argument
starting at <code class="docutils literal notranslate"><span class="pre">offset</span></code> bytes from the start of its memory region. The
default value of <code class="docutils literal notranslate"><span class="pre">offset</span></code> is 0B.</p>
<p><code class="docutils literal notranslate"><span class="pre">sub()</span></code> fails and returns NULL if the BLOB argument is empty, or if
<code class="docutils literal notranslate"><span class="pre">offset</span> <span class="pre">+</span> <span class="pre">length</span></code> requires more bytes than are available in the
BLOB.</p>
</div>
<div class="section" id="new-xblob-blob-blob-enum-decoding-string-encoded">
<span id="obj-blob"></span><h4>new xblob = blob.blob(ENUM decoding, STRING encoded)<a class="headerlink" href="#new-xblob-blob-blob-enum-decoding-string-encoded" title="Permalink to this headline">¶</a></h4>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">new</span> <span class="n">xblob</span> <span class="o">=</span> <span class="n">blob</span><span class="o">.</span><span class="n">blob</span><span class="p">(</span>
<span class="n">ENUM</span> <span class="p">{</span><span class="n">IDENTITY</span><span class="p">,</span> <span class="n">BASE64</span><span class="p">,</span> <span class="n">BASE64URL</span><span class="p">,</span> <span class="n">BASE64URLNOPAD</span><span class="p">,</span> <span class="n">HEX</span><span class="p">,</span> <span class="n">URL</span><span class="p">}</span> <span class="n">decoding</span><span class="o">=</span><span class="n">IDENTITY</span><span class="p">,</span>
<span class="n">STRING</span> <span class="n">encoded</span>
<span class="p">)</span>
</pre></div>
</div>
<p>Creates an object that contains the BLOB derived from the string
<code class="docutils literal notranslate"><span class="pre">encoded</span></code> according to the scheme <code class="docutils literal notranslate"><span class="pre">decoding</span></code>.</p>
<p>Example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">new</span> <span class="n">theblob1</span> <span class="o">=</span> <span class="n">blob</span><span class="o">.</span><span class="n">blob</span><span class="p">(</span><span class="n">BASE64</span><span class="p">,</span> <span class="n">encoded</span><span class="o">=</span><span class="s2">"YmxvYg=="</span><span class="p">);</span>
<span class="c1"># same with named arguments</span>
<span class="n">new</span> <span class="n">theblob2</span> <span class="o">=</span> <span class="n">blob</span><span class="o">.</span><span class="n">blob</span><span class="p">(</span><span class="n">encoded</span><span class="o">=</span><span class="s2">"YmxvYg=="</span><span class="p">,</span> <span class="n">decoding</span><span class="o">=</span><span class="n">BASE64</span><span class="p">);</span>
<span class="c1"># string as a blob</span>
<span class="n">new</span> <span class="n">stringblob</span> <span class="o">=</span> <span class="n">blob</span><span class="o">.</span><span class="n">blob</span><span class="p">(</span><span class="n">encoded</span><span class="o">=</span><span class="s2">"bazz"</span><span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="blob-xblob-get">
<span id="func-blob-get"></span><h4>BLOB xblob.get()<a class="headerlink" href="#blob-xblob-get" title="Permalink to this headline">¶</a></h4>
<p>Returns the BLOB created by the constructor.</p>
<p>Example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">set</span> <span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">The</span><span class="o">-</span><span class="n">Blob1</span> <span class="o">=</span>
<span class="n">blob</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">blob</span><span class="o">=</span><span class="n">theblob1</span><span class="o">.</span><span class="n">get</span><span class="p">());</span>
<span class="nb">set</span> <span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">The</span><span class="o">-</span><span class="n">Blob2</span> <span class="o">=</span>
<span class="n">blob</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">blob</span><span class="o">=</span><span class="n">theblob2</span><span class="o">.</span><span class="n">get</span><span class="p">());</span>
<span class="nb">set</span> <span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">The</span><span class="o">-</span><span class="n">Stringblob</span> <span class="o">=</span>
<span class="n">blob</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">blob</span><span class="o">=</span><span class="n">stringblob</span><span class="o">.</span><span class="n">get</span><span class="p">());</span>
</pre></div>
</div>
</div>
<div class="section" id="string-xblob-encode-enum-encoding-enum-case">
<span id="func-blob-encode"></span><h4>STRING xblob.encode(ENUM encoding, ENUM case)<a class="headerlink" href="#string-xblob-encode-enum-encoding-enum-case" title="Permalink to this headline">¶</a></h4>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">STRING</span> <span class="n">xblob</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span>
<span class="n">ENUM</span> <span class="p">{</span><span class="n">IDENTITY</span><span class="p">,</span> <span class="n">BASE64</span><span class="p">,</span> <span class="n">BASE64URL</span><span class="p">,</span> <span class="n">BASE64URLNOPAD</span><span class="p">,</span> <span class="n">HEX</span><span class="p">,</span> <span class="n">URL</span><span class="p">}</span> <span class="n">encoding</span><span class="o">=</span><span class="n">IDENTITY</span><span class="p">,</span>
<span class="n">ENUM</span> <span class="p">{</span><span class="n">LOWER</span><span class="p">,</span> <span class="n">UPPER</span><span class="p">,</span> <span class="n">DEFAULT</span><span class="p">}</span> <span class="n">case</span><span class="o">=</span><span class="n">DEFAULT</span>
<span class="p">)</span>
</pre></div>
</div>
<p>Returns an encoding of BLOB created by the constructor, according to
the scheme <code class="docutils literal notranslate"><span class="pre">encoding</span></code>. <code class="docutils literal notranslate"><span class="pre">case</span></code> determines the case of hex digits
for the <code class="docutils literal notranslate"><span class="pre">HEX</span></code> and <code class="docutils literal notranslate"><span class="pre">URL</span></code> encodings, and MUST be set to <code class="docutils literal notranslate"><span class="pre">DEFAULT</span></code>
for the other encodings.</p>
<p>Example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># blob as text</span>
<span class="nb">set</span> <span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">The</span><span class="o">-</span><span class="n">Blob</span> <span class="o">=</span> <span class="n">theblob1</span><span class="o">.</span><span class="n">encode</span><span class="p">();</span>
<span class="c1"># blob as base64</span>
<span class="nb">set</span> <span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">The</span><span class="o">-</span><span class="n">Blob</span><span class="o">-</span><span class="n">b64</span> <span class="o">=</span> <span class="n">theblob1</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">BASE64</span><span class="p">);</span>
</pre></div>
</div>
<p>For any <code class="docutils literal notranslate"><span class="pre">blob</span></code> object, encoding <code class="docutils literal notranslate"><span class="pre">ENC</span></code> and case <code class="docutils literal notranslate"><span class="pre">CASE</span></code>, encodings
via the <code class="docutils literal notranslate"><span class="pre">.encode()</span></code> method and the <code class="docutils literal notranslate"><span class="pre">encode()</span></code> function are equal:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Always true:</span>
<span class="n">blob</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">ENC</span><span class="p">,</span> <span class="n">CASE</span><span class="p">,</span> <span class="n">blob</span><span class="o">.</span><span class="n">get</span><span class="p">())</span> <span class="o">==</span> <span class="n">blob</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">ENC</span><span class="p">,</span> <span class="n">CASE</span><span class="p">)</span>
</pre></div>
</div>
<p>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 <code class="docutils literal notranslate"><span class="pre">encode()</span></code>
function computes the encoding on every call, allocating space for the
string in Varnish workspaces.</p>
<p>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
<code class="docutils literal notranslate"><span class="pre">blob</span></code> object. The VMOD’s functions should be used for data that are
not known until runtime.</p>
</div>
</div>
<div class="section" id="errors">
<h3>ERRORS<a class="headerlink" href="#errors" title="Permalink to this headline">¶</a></h3>
<p>The encoders, decoders and <code class="docutils literal notranslate"><span class="pre">sub()</span></code> 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 <code class="docutils literal notranslate"><span class="pre">IDENTITY</span></code> and <code class="docutils literal notranslate"><span class="pre">BASE64*</span></code> encoding schemes if the
<code class="docutils literal notranslate"><span class="pre">case</span></code> ENUM is not set to <code class="docutils literal notranslate"><span class="pre">DEFAULT</span></code>.</p>
<p>If any of the VMOD’s methods, functions or constructor fail, then VCL
failure is invoked, just as if <code class="docutils literal notranslate"><span class="pre">return(fail)</span></code> had been called in the
VCL source. This means that:</p>
<ul class="simple">
<li>If the <code class="docutils literal notranslate"><span class="pre">blob</span></code> object constructor fails, or if any methods or
functions fail during <code class="docutils literal notranslate"><span class="pre">vcl_init</span></code>, then the VCL program will fail
to load, and the VCC compiler will emit an error message.</li>
<li>If a method or function fails in any other VCL subroutine besides
<code class="docutils literal notranslate"><span class="pre">vcl_synth</span></code>, then control is directed to <code class="docutils literal notranslate"><span class="pre">vcl_synth</span></code>. The
response status is set to 503 with the reason string <code class="docutils literal notranslate"><span class="pre">"VCL</span>
<span class="pre">failed"</span></code>, and an error message will be written to the Varnish log
using the tag <code class="docutils literal notranslate"><span class="pre">VCL_Error</span></code>.</li>
<li>If the failure occurs during <code class="docutils literal notranslate"><span class="pre">vcl_synth</span></code>, then <code class="docutils literal notranslate"><span class="pre">vcl_synth</span></code> is
aborted. The response line <code class="docutils literal notranslate"><span class="pre">"503</span> <span class="pre">VCL</span> <span class="pre">failed"</span></code> is returned, and
the <code class="docutils literal notranslate"><span class="pre">VCL_Error</span></code> message is written to the log.</li>
</ul>
</div>
<div class="section" id="limitations">
<h3>LIMITATIONS<a class="headerlink" href="#limitations" title="Permalink to this headline">¶</a></h3>
<p>The VMOD allocates memory in various ways for new blobs and
strings. The <code class="docutils literal notranslate"><span class="pre">blob</span></code> object and its methods allocate memory from the
heap, and hence they are only limited by available virtual memory.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">encode()</span></code>, <code class="docutils literal notranslate"><span class="pre">decode()</span></code> and <code class="docutils literal notranslate"><span class="pre">transcode()</span></code> functions allocate
Varnish workspace, as does <code class="docutils literal notranslate"><span class="pre">sub()</span></code> for the newly created BLOB. If
these functions are failing, as indicated by “out of space” messages
in the Varnish log (with the <code class="docutils literal notranslate"><span class="pre">VCL_Error</span></code> tag), then you will need to
increase the varnishd parameters <code class="docutils literal notranslate"><span class="pre">workspace_client</span></code> and/or
<code class="docutils literal notranslate"><span class="pre">workspace_backend</span></code>.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">transcode()</span></code> 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 <code class="docutils literal notranslate"><span class="pre">thread_pool_stack</span></code>.</p>
</div>
<div class="section" id="id18">
<h3>SEE ALSO<a class="headerlink" href="#id18" title="Permalink to this headline">¶</a></h3>
<ul class="simple">
<li><a class="reference internal" href="varnishd.html#varnishd-1"><span class="std std-ref">varnishd</span></a></li>
<li><a class="reference internal" href="vcl.html#vcl-7"><span class="std std-ref">VCL</span></a></li>
<li><a class="reference internal" href="#vmod-std-3"><span class="std std-ref">vmod_std</span></a></li>
</ul>
</div>
<div class="section" id="id19">
<h3>COPYRIGHT<a class="headerlink" href="#id19" title="Permalink to this headline">¶</a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">This</span> <span class="n">document</span> <span class="ow">is</span> <span class="n">licensed</span> <span class="n">under</span> <span class="n">the</span> <span class="n">same</span> <span class="n">conditions</span> <span class="k">as</span> <span class="n">Varnish</span> <span class="n">itself</span><span class="o">.</span>
<span class="n">See</span> <span class="n">LICENSE</span> <span class="k">for</span> <span class="n">details</span><span class="o">.</span>
<span class="n">Authors</span><span class="p">:</span> <span class="n">Nils</span> <span class="n">Goroll</span> <span class="o"><</span><span class="n">nils</span><span class="o">.</span><span class="n">goroll</span><span class="nd">@uplex</span><span class="o">.</span><span class="n">de</span><span class="o">></span>
<span class="n">Geoffrey</span> <span class="n">Simmons</span> <span class="o"><</span><span class="n">geoffrey</span><span class="o">.</span><span class="n">simmons</span><span class="nd">@uplex</span><span class="o">.</span><span class="n">de</span><span class="o">></span>
</pre></div>
</div>
</div>
</div>
</div>
<div class="section" id="vmod-unix">
<span id="vmod-unix-3"></span><h1>vmod_unix<a class="headerlink" href="#vmod-unix" title="Permalink to this headline">¶</a></h1>
<div class="section" id="utilities-for-unix-domain-sockets">
<h2>Utilities for Unix domain sockets<a class="headerlink" href="#utilities-for-unix-domain-sockets" title="Permalink to this headline">¶</a></h2>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Manual section:</th><td class="field-body">3</td>
</tr>
</tbody>
</table>
<div class="section" id="id20">
<h3>SYNOPSIS<a class="headerlink" href="#id20" title="Permalink to this headline">¶</a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">unix</span> <span class="p">[</span><span class="kn">from</span> <span class="s2">"path"</span><span class="p">]</span> <span class="p">;</span>
<span class="n">STRING</span> <span class="n">user</span><span class="p">()</span>
<span class="n">STRING</span> <span class="n">group</span><span class="p">()</span>
<span class="n">INT</span> <span class="n">uid</span><span class="p">()</span>
<span class="n">INT</span> <span class="n">gid</span><span class="p">()</span>
</pre></div>
</div>
</div>
<div class="section" id="id21">
<h3>CONTENTS<a class="headerlink" href="#id21" title="Permalink to this headline">¶</a></h3>
<ul class="simple">
<li><a class="reference internal" href="#func-gid"><span class="std std-ref">INT gid()</span></a></li>
<li><a class="reference internal" href="#func-group"><span class="std std-ref">STRING group()</span></a></li>
<li><a class="reference internal" href="#func-uid"><span class="std std-ref">INT uid()</span></a></li>
<li><a class="reference internal" href="#func-user"><span class="std std-ref">STRING user()</span></a></li>
</ul>
</div>
<div class="section" id="id22">
<h3>DESCRIPTION<a class="headerlink" href="#id22" title="Permalink to this headline">¶</a></h3>
<p>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.</p>
<p>Examples:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">unix</span><span class="p">;</span>
<span class="n">sub</span> <span class="n">vcl_recv</span> <span class="p">{</span>
<span class="c1"># Return "403 Forbidden" if the connected peer is</span>
<span class="c1"># not running as the user "trusteduser".</span>
<span class="k">if</span> <span class="p">(</span><span class="n">unix</span><span class="o">.</span><span class="n">user</span><span class="p">()</span> <span class="o">!=</span> <span class="s2">"trusteduser"</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span><span class="p">(</span> <span class="n">synth</span><span class="p">(</span><span class="mi">403</span><span class="p">)</span> <span class="p">);</span>
<span class="p">}</span>
<span class="c1"># Require the connected peer to run in the group</span>
<span class="c1"># "trustedgroup".</span>
<span class="k">if</span> <span class="p">(</span><span class="n">unix</span><span class="o">.</span><span class="n">group</span><span class="p">()</span> <span class="o">!=</span> <span class="s2">"trustedgroup"</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span><span class="p">(</span> <span class="n">synth</span><span class="p">(</span><span class="mi">403</span><span class="p">)</span> <span class="p">);</span>
<span class="p">}</span>
<span class="c1"># Require the connected peer to run under a specific numeric</span>
<span class="c1"># user id.</span>
<span class="k">if</span> <span class="p">(</span><span class="n">unix</span><span class="o">.</span><span class="n">uid</span><span class="p">()</span> <span class="o">!=</span> <span class="mi">4711</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span><span class="p">(</span> <span class="n">synth</span><span class="p">(</span><span class="mi">403</span><span class="p">)</span> <span class="p">);</span>
<span class="p">}</span>
<span class="c1"># Require the connected peer to run under a numeric group id.</span>
<span class="k">if</span> <span class="p">(</span><span class="n">unix</span><span class="o">.</span><span class="n">gid</span><span class="p">()</span> <span class="o">!=</span> <span class="mi">815</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span><span class="p">(</span> <span class="n">synth</span><span class="p">(</span><span class="mi">403</span><span class="p">)</span> <span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Obtaining the peer credentials is possible on a platform that supports
one of the following:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">getpeereid(3)</span></code> (such as FreeBSD and other BSD-derived systems)</li>
<li>the socket option <code class="docutils literal notranslate"><span class="pre">SO_PEERCRED</span></code> for <code class="docutils literal notranslate"><span class="pre">getsockopt(2)</span></code> (Linux)</li>
<li><code class="docutils literal notranslate"><span class="pre">getpeerucred(3C)</span></code> (SunOS and descendants)</li>
</ul>
<p>On SunOS and friends, the <code class="docutils literal notranslate"><span class="pre">PRIV_PROC_INFO</span></code> privilege set is added to
the Varnish child process while the VMOD is loaded, see
<code class="docutils literal notranslate"><span class="pre">setppriv(2)</span></code>.</p>
<p>On most platforms, the value returned is the effective user or group
that was valid when the peer process initiated the connection.</p>
<div class="section" id="string-user">
<span id="func-user"></span><h4>STRING user()<a class="headerlink" href="#string-user" title="Permalink to this headline">¶</a></h4>
<p>Return the user name of the peer process owner.</p>
</div>
<div class="section" id="string-group">
<span id="func-group"></span><h4>STRING group()<a class="headerlink" href="#string-group" title="Permalink to this headline">¶</a></h4>
<p>Return the group name of the peer process owner.</p>
</div>
<div class="section" id="int-uid">
<span id="func-uid"></span><h4>INT uid()<a class="headerlink" href="#int-uid" title="Permalink to this headline">¶</a></h4>
<p>Return the numeric user id of the peer process owner.</p>
</div>
<div class="section" id="int-gid">
<span id="func-gid"></span><h4>INT gid()<a class="headerlink" href="#int-gid" title="Permalink to this headline">¶</a></h4>
<p>Return the numeric group id of the peer process owner.</p>
</div>
</div>
<div class="section" id="id23">
<h3>ERRORS<a class="headerlink" href="#id23" title="Permalink to this headline">¶</a></h3>
<p>All functions in this VMOD are subject to the following constraints:</p>
<ul>
<li><p class="first">None of them may be called in <code class="docutils literal notranslate"><span class="pre">vcl_init</span></code> or <code class="docutils literal notranslate"><span class="pre">vcl_fini</span></code>. If one
of them is called in <code class="docutils literal notranslate"><span class="pre">vcl_init</span></code>, then the VCL program will fail to
load, with an error message from the VMOD.</p>
</li>
<li><p class="first">If called on a platform that is not supported, then VCL failure is
invoked. An error message is written to the log (with the
<code class="docutils literal notranslate"><span class="pre">VCL_Error</span></code> tag), and for all VCL subroutines except for
<code class="docutils literal notranslate"><span class="pre">vcl_synth</span></code>, control is directed immediately to <code class="docutils literal notranslate"><span class="pre">vcl_synth</span></code>,
with the response status set to 503 and the reason string set to
“VCL failed”.</p>
<p>If the failure occurs during <code class="docutils literal notranslate"><span class="pre">vcl_synth</span></code>, then <code class="docutils literal notranslate"><span class="pre">vcl_synth</span></code> is
aborted, and the the response line “503 VCL failed” is sent.</p>
</li>
<li><p class="first">If the current listener is not a Unix domain socket, or if the
attempt to read credentials fails, then a <code class="docutils literal notranslate"><span class="pre">VCL_Error</span></code> message is
written to the log. The STRING functions (<code class="docutils literal notranslate"><span class="pre">vmod_user</span></code> and
<code class="docutils literal notranslate"><span class="pre">vmod_group</span></code>) return NULL, while the INT functions (<code class="docutils literal notranslate"><span class="pre">vmod_uid</span></code>
and <code class="docutils literal notranslate"><span class="pre">vmod_gid</span></code>) return -1.</p>
</li>
</ul>
</div>
<div class="section" id="id24">
<h3>SEE ALSO<a class="headerlink" href="#id24" title="Permalink to this headline">¶</a></h3>
<ul class="simple">
<li><a class="reference internal" href="varnishd.html#varnishd-1"><span class="std std-ref">varnishd</span></a></li>
<li><a class="reference internal" href="vcl.html#vcl-7"><span class="std std-ref">VCL</span></a></li>
<li><code class="docutils literal notranslate"><span class="pre">getpeereid(3)</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">getsockopt(2)</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">getpeerucred(3C)</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">setppriv(2)</span></code></li>
</ul>
</div>
<div class="section" id="id25">
<h3>COPYRIGHT<a class="headerlink" href="#id25" title="Permalink to this headline">¶</a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">This</span> <span class="n">document</span> <span class="ow">is</span> <span class="n">licensed</span> <span class="n">under</span> <span class="n">the</span> <span class="n">same</span> <span class="n">conditions</span> <span class="k">as</span> <span class="n">Varnish</span> <span class="n">itself</span><span class="o">.</span>
<span class="n">See</span> <span class="n">LICENSE</span> <span class="k">for</span> <span class="n">details</span><span class="o">.</span>
<span class="n">Authors</span><span class="p">:</span> <span class="n">Geoffrey</span> <span class="n">Simmons</span> <span class="o"><</span><span class="n">geoffrey</span><span class="o">.</span><span class="n">simmons</span><span class="nd">@uplex</span><span class="o">.</span><span class="n">de</span><span class="o">></span>
</pre></div>
</div>
</div>
</div>
</div>
<div class="section" id="vmod-proxy">
<span id="vmod-proxy-3"></span><h1>vmod_proxy<a class="headerlink" href="#vmod-proxy" title="Permalink to this headline">¶</a></h1>
<div class="section" id="varnish-module-to-extract-tlv-attributes-from-proxyv2">
<h2>Varnish Module to extract TLV attributes from PROXYv2<a class="headerlink" href="#varnish-module-to-extract-tlv-attributes-from-proxyv2" title="Permalink to this headline">¶</a></h2>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Manual section:</th><td class="field-body">3</td>
</tr>
</tbody>
</table>
<div class="section" id="id26">
<h3>SYNOPSIS<a class="headerlink" href="#id26" title="Permalink to this headline">¶</a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">proxy</span> <span class="p">[</span><span class="kn">from</span> <span class="s2">"path"</span><span class="p">]</span> <span class="p">;</span>
<span class="n">STRING</span> <span class="n">alpn</span><span class="p">()</span>
<span class="n">STRING</span> <span class="n">authority</span><span class="p">()</span>
<span class="n">BOOL</span> <span class="n">is_ssl</span><span class="p">()</span>
<span class="n">BOOL</span> <span class="n">client_has_cert_sess</span><span class="p">()</span>
<span class="n">BOOL</span> <span class="n">client_has_cert_conn</span><span class="p">()</span>
<span class="n">INT</span> <span class="n">ssl_verify_result</span><span class="p">()</span>
<span class="n">STRING</span> <span class="n">ssl_version</span><span class="p">()</span>
<span class="n">STRING</span> <span class="n">client_cert_cn</span><span class="p">()</span>
<span class="n">STRING</span> <span class="n">ssl_cipher</span><span class="p">()</span>
<span class="n">STRING</span> <span class="n">cert_sign</span><span class="p">()</span>
<span class="n">STRING</span> <span class="n">cert_key</span><span class="p">()</span>
</pre></div>
</div>
</div>
<div class="section" id="id27">
<h3>CONTENTS<a class="headerlink" href="#id27" title="Permalink to this headline">¶</a></h3>
<ul class="simple">
<li><a class="reference internal" href="#func-alpn"><span class="std std-ref">STRING alpn()</span></a></li>
<li><a class="reference internal" href="#func-authority"><span class="std std-ref">STRING authority()</span></a></li>
<li><a class="reference internal" href="#func-cert-key"><span class="std std-ref">STRING cert_key()</span></a></li>
<li><a class="reference internal" href="#func-cert-sign"><span class="std std-ref">STRING cert_sign()</span></a></li>
<li><a class="reference internal" href="#func-client-cert-cn"><span class="std std-ref">STRING client_cert_cn()</span></a></li>
<li><a class="reference internal" href="#func-client-has-cert-conn"><span class="std std-ref">BOOL client_has_cert_conn()</span></a></li>
<li><a class="reference internal" href="#func-client-has-cert-sess"><span class="std std-ref">BOOL client_has_cert_sess()</span></a></li>
<li><a class="reference internal" href="#func-is-ssl"><span class="std std-ref">BOOL is_ssl()</span></a></li>
<li><a class="reference internal" href="#func-ssl-cipher"><span class="std std-ref">STRING ssl_cipher()</span></a></li>
<li><a class="reference internal" href="#func-ssl-verify-result"><span class="std std-ref">INT ssl_verify_result()</span></a></li>
<li><a class="reference internal" href="#func-ssl-version"><span class="std std-ref">STRING ssl_version()</span></a></li>
</ul>
</div>
<div class="section" id="id28">
<h3>DESCRIPTION<a class="headerlink" href="#id28" title="Permalink to this headline">¶</a></h3>
<p><cite>vmod_proxy</cite> contains functions to extract proxy-protocol-v2 TLV attributes
as described in <a class="reference external" href="https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt">https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt</a>.</p>
<div class="section" id="string-alpn">
<span id="func-alpn"></span><h4>STRING alpn()<a class="headerlink" href="#string-alpn" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Extract ALPN attribute.</dd>
<dt>Example</dt>
<dd>set req.http.alpn = proxy.alpn();</dd>
</dl>
</div>
<div class="section" id="string-authority">
<span id="func-authority"></span><h4>STRING authority()<a class="headerlink" href="#string-authority" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Extract authority attribute. This corresponds to SNI from a TLS
connection.</dd>
<dt>Example</dt>
<dd>set req.http.authority = proxy.authority();</dd>
</dl>
</div>
<div class="section" id="bool-is-ssl">
<span id="func-is-ssl"></span><h4>BOOL is_ssl()<a class="headerlink" href="#bool-is-ssl" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Report if proxy-protocol-v2 has SSL TLV.</dd>
<dt>Example</dt>
<dd><div class="first last line-block">
<div class="line">if (proxy.is_ssl()) {</div>
<div class="line-block">
<div class="line">set req.http.ssl-version = proxy.ssl_version();</div>
</div>
<div class="line">}</div>
</div>
</dd>
</dl>
</div>
<div class="section" id="bool-client-has-cert-sess">
<span id="func-client-has-cert-sess"></span><h4>BOOL client_has_cert_sess()<a class="headerlink" href="#bool-client-has-cert-sess" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Report if the client provided a certificate at least once over the TLS
session this connection belongs to.</dd>
</dl>
</div>
<div class="section" id="bool-client-has-cert-conn">
<span id="func-client-has-cert-conn"></span><h4>BOOL client_has_cert_conn()<a class="headerlink" href="#bool-client-has-cert-conn" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Report if the client provided a certificate over the current connection.</dd>
</dl>
</div>
<div class="section" id="int-ssl-verify-result">
<span id="func-ssl-verify-result"></span><h4>INT ssl_verify_result()<a class="headerlink" href="#int-ssl-verify-result" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>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).</dd>
<dt>Example</dt>
<dd><div class="first last line-block">
<div class="line">if (proxy.client_has_cert_sess() && proxy.ssl_verify_result() == 0) {</div>
<div class="line-block">
<div class="line">set req.http.ssl-verify = “ok”;</div>
</div>
<div class="line">}</div>
</div>
</dd>
</dl>
</div>
<div class="section" id="string-ssl-version">
<span id="func-ssl-version"></span><h4>STRING ssl_version()<a class="headerlink" href="#string-ssl-version" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Extract SSL version attribute.</dd>
<dt>Example</dt>
<dd>set req.http.ssl-version = proxy.ssl_version();</dd>
</dl>
</div>
<div class="section" id="string-client-cert-cn">
<span id="func-client-cert-cn"></span><h4>STRING client_cert_cn()<a class="headerlink" href="#string-client-cert-cn" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Extract the common name attribute of the client certificate’s.</dd>
<dt>Example</dt>
<dd>set req.http.cert-cn = proxy.client_cert_cn();</dd>
</dl>
</div>
<div class="section" id="string-ssl-cipher">
<span id="func-ssl-cipher"></span><h4>STRING ssl_cipher()<a class="headerlink" href="#string-ssl-cipher" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Extract the SSL cipher attribute.</dd>
<dt>Example</dt>
<dd>set req.http.ssl-cipher = proxy.ssl_cipher();</dd>
</dl>
</div>
<div class="section" id="string-cert-sign">
<span id="func-cert-sign"></span><h4>STRING cert_sign()<a class="headerlink" href="#string-cert-sign" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Extract the certificate signature algorithm attribute.</dd>
<dt>Example</dt>
<dd>set req.http.cert-sign = proxy.cert_sign();</dd>
</dl>
</div>
<div class="section" id="string-cert-key">
<span id="func-cert-key"></span><h4>STRING cert_key()<a class="headerlink" href="#string-cert-key" title="Permalink to this headline">¶</a></h4>
<dl class="docutils">
<dt>Description</dt>
<dd>Extract the certificate key algorithm attribute.</dd>
<dt>Example</dt>
<dd>set req.http.cert-key = proxy.cert_key();</dd>
</dl>
</div>
</div>
<div class="section" id="id29">
<h3>SEE ALSO<a class="headerlink" href="#id29" title="Permalink to this headline">¶</a></h3>
<ul class="simple">
<li><a class="reference internal" href="varnishd.html#varnishd-1"><span class="std std-ref">varnishd</span></a></li>
<li><a class="reference internal" href="vsl.html#vsl-7"><span class="std std-ref">VSL</span></a></li>
</ul>
</div>
<div class="section" id="id30">
<h3>COPYRIGHT<a class="headerlink" href="#id30" title="Permalink to this headline">¶</a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>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.
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">vmod_std</a><ul>
<li><a class="reference internal" href="#varnish-standard-module">Varnish Standard Module</a><ul>
<li><a class="reference internal" href="#synopsis">SYNOPSIS</a></li>
<li><a class="reference internal" href="#contents">CONTENTS</a></li>
<li><a class="reference internal" href="#description">DESCRIPTION</a><ul>
<li><a class="reference internal" href="#string-toupper-string-s">STRING toupper(STRING s)</a></li>
<li><a class="reference internal" href="#string-tolower-string-s">STRING tolower(STRING s)</a></li>
<li><a class="reference internal" href="#void-set-ip-tos-int-tos">VOID set_ip_tos(INT tos)</a></li>
<li><a class="reference internal" href="#real-random-real-lo-real-hi">REAL random(REAL lo, REAL hi)</a></li>
<li><a class="reference internal" href="#void-log-string-s">VOID log(STRING s)</a></li>
<li><a class="reference internal" href="#void-syslog-int-priority-string-s">VOID syslog(INT priority, STRING s)</a></li>
<li><a class="reference internal" href="#string-fileread-string">STRING fileread(STRING)</a></li>
<li><a class="reference internal" href="#bool-file-exists-string-path">BOOL file_exists(STRING path)</a></li>
<li><a class="reference internal" href="#void-collect-header-hdr-string-sep">VOID collect(HEADER hdr, STRING sep=”, “)</a></li>
<li><a class="reference internal" href="#duration-duration-string-s-duration-fallback">DURATION duration(STRING s, DURATION fallback)</a></li>
<li><a class="reference internal" href="#int-integer-string-s-int-fallback">INT integer(STRING s, INT fallback)</a></li>
<li><a class="reference internal" href="#ip-ip-string-s-ip-fallback-bool-resolve-1">IP ip(STRING s, IP fallback, BOOL resolve=1)</a></li>
<li><a class="reference internal" href="#real-real-string-s-real-fallback">REAL real(STRING s, REAL fallback)</a></li>
<li><a class="reference internal" href="#int-real2integer-real-r-int-fallback">INT real2integer(REAL r, INT fallback)</a></li>
<li><a class="reference internal" href="#time-real2time-real-r-time-fallback">TIME real2time(REAL r, TIME fallback)</a></li>
<li><a class="reference internal" href="#int-time2integer-time-t-int-fallback">INT time2integer(TIME t, INT fallback)</a></li>
<li><a class="reference internal" href="#real-time2real-time-t-real-fallback">REAL time2real(TIME t, REAL fallback)</a></li>
<li><a class="reference internal" href="#bool-healthy-backend-be">BOOL healthy(BACKEND be)</a></li>
<li><a class="reference internal" href="#int-port-ip-ip">INT port(IP ip)</a></li>
<li><a class="reference internal" href="#void-rollback-http-h">VOID rollback(HTTP h)</a></li>
<li><a class="reference internal" href="#void-timestamp-string-s">VOID timestamp(STRING s)</a></li>
<li><a class="reference internal" href="#string-querysort-string">STRING querysort(STRING)</a></li>
<li><a class="reference internal" href="#bool-cache-req-body-bytes-size">BOOL cache_req_body(BYTES size)</a></li>
<li><a class="reference internal" href="#string-strstr-string-s1-string-s2">STRING strstr(STRING s1, STRING s2)</a></li>
<li><a class="reference internal" href="#time-time-string-s-time-fallback">TIME time(STRING s, TIME fallback)</a></li>
<li><a class="reference internal" href="#string-getenv-string-name">STRING getenv(STRING name)</a></li>
<li><a class="reference internal" href="#void-late-100-continue-bool-late">VOID late_100_continue(BOOL late)</a></li>
<li><a class="reference internal" href="#bool-syntax-real">BOOL syntax(REAL)</a></li>
<li><a class="reference internal" href="#fnmatch">fnmatch(…)</a></li>
</ul>
</li>
<li><a class="reference internal" href="#see-also">SEE ALSO</a></li>
<li><a class="reference internal" href="#copyright">COPYRIGHT</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#vmod-directors">vmod_directors</a><ul>
<li><a class="reference internal" href="#varnish-directors-module">Varnish Directors Module</a><ul>
<li><a class="reference internal" href="#id1">SYNOPSIS</a></li>
<li><a class="reference internal" href="#id2">CONTENTS</a></li>
<li><a class="reference internal" href="#id3">DESCRIPTION</a><ul>
<li><a class="reference internal" href="#new-xround-robin-directors-round-robin">new xround_robin = directors.round_robin()</a></li>
<li><a class="reference internal" href="#void-xround-robin-add-backend-backend">VOID xround_robin.add_backend(BACKEND)</a></li>
<li><a class="reference internal" href="#void-xround-robin-remove-backend-backend">VOID xround_robin.remove_backend(BACKEND)</a></li>
<li><a class="reference internal" href="#backend-xround-robin-backend">BACKEND xround_robin.backend()</a></li>
<li><a class="reference internal" href="#new-xfallback-directors-fallback-bool-sticky-0">new xfallback = directors.fallback(BOOL sticky=0)</a></li>
<li><a class="reference internal" href="#void-xfallback-add-backend-backend">VOID xfallback.add_backend(BACKEND)</a></li>
<li><a class="reference internal" href="#void-xfallback-remove-backend-backend">VOID xfallback.remove_backend(BACKEND)</a></li>
<li><a class="reference internal" href="#backend-xfallback-backend">BACKEND xfallback.backend()</a></li>
<li><a class="reference internal" href="#new-xrandom-directors-random">new xrandom = directors.random()</a></li>
<li><a class="reference internal" href="#void-xrandom-add-backend-backend-real">VOID xrandom.add_backend(BACKEND, REAL)</a></li>
<li><a class="reference internal" href="#void-xrandom-remove-backend-backend">VOID xrandom.remove_backend(BACKEND)</a></li>
<li><a class="reference internal" href="#backend-xrandom-backend">BACKEND xrandom.backend()</a></li>
<li><a class="reference internal" href="#new-xhash-directors-hash">new xhash = directors.hash()</a></li>
<li><a class="reference internal" href="#void-xhash-add-backend-backend-real">VOID xhash.add_backend(BACKEND, REAL)</a></li>
<li><a class="reference internal" href="#void-xhash-remove-backend-backend">VOID xhash.remove_backend(BACKEND)</a></li>
<li><a class="reference internal" href="#backend-xhash-backend-string">BACKEND xhash.backend(STRING)</a></li>
<li><a class="reference internal" href="#new-xshard-directors-shard">new xshard = directors.shard()</a><ul>
<li><a class="reference internal" href="#introduction">Introduction</a></li>
<li><a class="reference internal" href="#sharding">Sharding</a></li>
<li><a class="reference internal" href="#method">Method</a></li>
<li><a class="reference internal" href="#error-reporting">Error Reporting</a></li>
</ul>
</li>
<li><a class="reference internal" href="#void-xshard-set-warmup-real-probability-0-0">VOID xshard.set_warmup(REAL probability=0.0)</a></li>
<li><a class="reference internal" href="#void-xshard-set-rampup-duration-duration-0">VOID xshard.set_rampup(DURATION duration=0)</a></li>
<li><a class="reference internal" href="#void-xshard-associate-blob-param-0">VOID xshard.associate(BLOB param=0)</a></li>
<li><a class="reference internal" href="#shard-add-backend">shard.add_backend(…)</a></li>
<li><a class="reference internal" href="#shard-remove-backend">shard.remove_backend(…)</a></li>
<li><a class="reference internal" href="#bool-xshard-clear">BOOL xshard.clear()</a></li>
<li><a class="reference internal" href="#bool-xshard-reconfigure-int-replicas-67">BOOL xshard.reconfigure(INT replicas=67)</a></li>
<li><a class="reference internal" href="#int-xshard-key-string">INT xshard.key(STRING)</a></li>
<li><a class="reference internal" href="#shard-backend">shard.backend(…)</a></li>
<li><a class="reference internal" href="#void-xshard-debug-int">VOID xshard.debug(INT)</a></li>
<li><a class="reference internal" href="#new-xshard-param-directors-shard-param">new xshard_param = directors.shard_param()</a></li>
<li><a class="reference internal" href="#void-xshard-param-clear">VOID xshard_param.clear()</a></li>
<li><a class="reference internal" href="#shard-param-set">shard_param.set(…)</a></li>
<li><a class="reference internal" href="#string-xshard-param-get-by">STRING xshard_param.get_by()</a></li>
<li><a class="reference internal" href="#int-xshard-param-get-key">INT xshard_param.get_key()</a></li>
<li><a class="reference internal" href="#int-xshard-param-get-alt">INT xshard_param.get_alt()</a></li>
<li><a class="reference internal" href="#real-xshard-param-get-warmup">REAL xshard_param.get_warmup()</a></li>
<li><a class="reference internal" href="#bool-xshard-param-get-rampup">BOOL xshard_param.get_rampup()</a></li>
<li><a class="reference internal" href="#string-xshard-param-get-healthy">STRING xshard_param.get_healthy()</a></li>
<li><a class="reference internal" href="#blob-xshard-param-use">BLOB xshard_param.use()</a></li>
</ul>
</li>
<li><a class="reference internal" href="#acknowledgements">ACKNOWLEDGEMENTS</a></li>
<li><a class="reference internal" href="#id4">COPYRIGHT</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#vmod-vtc">vmod_vtc</a><ul>
<li><a class="reference internal" href="#utility-module-for-varnishtest">Utility module for varnishtest</a><ul>
<li><a class="reference internal" href="#id5">SYNOPSIS</a></li>
<li><a class="reference internal" href="#id6">CONTENTS</a></li>
<li><a class="reference internal" href="#id7">DESCRIPTION</a><ul>
<li><a class="reference internal" href="#void-barrier-sync-string-addr-duration-timeout-0">VOID barrier_sync(STRING addr, DURATION timeout=0)</a></li>
</ul>
</li>
<li><a class="reference internal" href="#miscellaneous">MISCELLANEOUS</a><ul>
<li><a class="reference internal" href="#backend-no-backend">BACKEND no_backend()</a></li>
<li><a class="reference internal" href="#stevedore-no-stevedore">STEVEDORE no_stevedore()</a></li>
<li><a class="reference internal" href="#ip-no-ip">IP no_ip()</a></li>
<li><a class="reference internal" href="#void-panic-string">VOID panic(STRING)</a></li>
<li><a class="reference internal" href="#void-sleep-duration">VOID sleep(DURATION)</a></li>
</ul>
</li>
<li><a class="reference internal" href="#workspaces">WORKSPACES</a><ul>
<li><a class="reference internal" href="#void-workspace-alloc-enum-int-size">VOID workspace_alloc(ENUM, INT size)</a></li>
<li><a class="reference internal" href="#int-workspace-free-enum-client-backend-session-thread">INT workspace_free(ENUM {client, backend, session, thread})</a></li>
<li><a class="reference internal" href="#void-workspace-snapshot-enum">VOID workspace_snapshot(ENUM)</a></li>
<li><a class="reference internal" href="#void-workspace-reset-enum">VOID workspace_reset(ENUM)</a></li>
<li><a class="reference internal" href="#bool-workspace-overflowed-enum">BOOL workspace_overflowed(ENUM)</a></li>
<li><a class="reference internal" href="#void-workspace-overflow-enum">VOID workspace_overflow(ENUM)</a></li>
<li><a class="reference internal" href="#int-typesize-string">INT typesize(STRING)</a></li>
</ul>
</li>
<li><a class="reference internal" href="#id8">SEE ALSO</a></li>
<li><a class="reference internal" href="#id9">COPYRIGHT</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#vmod-purge">vmod_purge</a><ul>
<li><a class="reference internal" href="#varnish-purge-module">Varnish Purge Module</a><ul>
<li><a class="reference internal" href="#id10">SYNOPSIS</a></li>
<li><a class="reference internal" href="#id11">CONTENTS</a></li>
<li><a class="reference internal" href="#id12">DESCRIPTION</a></li>
<li><a class="reference internal" href="#example">EXAMPLE</a><ul>
<li><a class="reference internal" href="#int-hard">INT hard()</a></li>
<li><a class="reference internal" href="#int-soft-duration-ttl-duration-grace-duration-keep">INT soft(DURATION ttl, DURATION grace, DURATION keep)</a></li>
</ul>
</li>
<li><a class="reference internal" href="#id13">SEE ALSO</a></li>
<li><a class="reference internal" href="#id14">COPYRIGHT</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#vmod-blob">vmod_blob</a><ul>
<li><a class="reference internal" href="#utilities-for-the-vcl-blob-type">Utilities for the VCL blob type</a><ul>
<li><a class="reference internal" href="#id15">SYNOPSIS</a></li>
<li><a class="reference internal" href="#id16">CONTENTS</a></li>
<li><a class="reference internal" href="#id17">DESCRIPTION</a></li>
<li><a class="reference internal" href="#encoding-schemes">ENCODING SCHEMES</a><ul>
<li><a class="reference internal" href="#identity">IDENTITY</a></li>
<li><a class="reference internal" href="#base64">BASE64*</a></li>
<li><a class="reference internal" href="#hex">HEX</a></li>
<li><a class="reference internal" href="#url">URL</a></li>
<li><a class="reference internal" href="#blob-decode-enum-decoding-int-length-string-encoded">BLOB decode(ENUM decoding, INT length, STRING encoded)</a></li>
<li><a class="reference internal" href="#string-encode-enum-encoding-enum-case-blob-blob">STRING encode(ENUM encoding, ENUM case, BLOB blob)</a></li>
<li><a class="reference internal" href="#transcode">transcode(…)</a></li>
<li><a class="reference internal" href="#bool-same-blob-blob">BOOL same(BLOB, BLOB)</a></li>
<li><a class="reference internal" href="#bool-equal-blob-blob">BOOL equal(BLOB, BLOB)</a></li>
<li><a class="reference internal" href="#int-length-blob">INT length(BLOB)</a></li>
<li><a class="reference internal" href="#blob-sub-blob-bytes-length-bytes-offset-0">BLOB sub(BLOB, BYTES length, BYTES offset=0)</a></li>
<li><a class="reference internal" href="#new-xblob-blob-blob-enum-decoding-string-encoded">new xblob = blob.blob(ENUM decoding, STRING encoded)</a></li>
<li><a class="reference internal" href="#blob-xblob-get">BLOB xblob.get()</a></li>
<li><a class="reference internal" href="#string-xblob-encode-enum-encoding-enum-case">STRING xblob.encode(ENUM encoding, ENUM case)</a></li>
</ul>
</li>
<li><a class="reference internal" href="#errors">ERRORS</a></li>
<li><a class="reference internal" href="#limitations">LIMITATIONS</a></li>
<li><a class="reference internal" href="#id18">SEE ALSO</a></li>
<li><a class="reference internal" href="#id19">COPYRIGHT</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#vmod-unix">vmod_unix</a><ul>
<li><a class="reference internal" href="#utilities-for-unix-domain-sockets">Utilities for Unix domain sockets</a><ul>
<li><a class="reference internal" href="#id20">SYNOPSIS</a></li>
<li><a class="reference internal" href="#id21">CONTENTS</a></li>
<li><a class="reference internal" href="#id22">DESCRIPTION</a><ul>
<li><a class="reference internal" href="#string-user">STRING user()</a></li>
<li><a class="reference internal" href="#string-group">STRING group()</a></li>
<li><a class="reference internal" href="#int-uid">INT uid()</a></li>
<li><a class="reference internal" href="#int-gid">INT gid()</a></li>
</ul>
</li>
<li><a class="reference internal" href="#id23">ERRORS</a></li>
<li><a class="reference internal" href="#id24">SEE ALSO</a></li>
<li><a class="reference internal" href="#id25">COPYRIGHT</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#vmod-proxy">vmod_proxy</a><ul>
<li><a class="reference internal" href="#varnish-module-to-extract-tlv-attributes-from-proxyv2">Varnish Module to extract TLV attributes from PROXYv2</a><ul>
<li><a class="reference internal" href="#id26">SYNOPSIS</a></li>
<li><a class="reference internal" href="#id27">CONTENTS</a></li>
<li><a class="reference internal" href="#id28">DESCRIPTION</a><ul>
<li><a class="reference internal" href="#string-alpn">STRING alpn()</a></li>
<li><a class="reference internal" href="#string-authority">STRING authority()</a></li>
<li><a class="reference internal" href="#bool-is-ssl">BOOL is_ssl()</a></li>
<li><a class="reference internal" href="#bool-client-has-cert-sess">BOOL client_has_cert_sess()</a></li>
<li><a class="reference internal" href="#bool-client-has-cert-conn">BOOL client_has_cert_conn()</a></li>
<li><a class="reference internal" href="#int-ssl-verify-result">INT ssl_verify_result()</a></li>
<li><a class="reference internal" href="#string-ssl-version">STRING ssl_version()</a></li>
<li><a class="reference internal" href="#string-client-cert-cn">STRING client_cert_cn()</a></li>
<li><a class="reference internal" href="#string-ssl-cipher">STRING ssl_cipher()</a></li>
<li><a class="reference internal" href="#string-cert-sign">STRING cert_sign()</a></li>
<li><a class="reference internal" href="#string-cert-key">STRING cert_key()</a></li>
</ul>
</li>
<li><a class="reference internal" href="#id29">SEE ALSO</a></li>
<li><a class="reference internal" href="#id30">COPYRIGHT</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="vmod.html"
title="previous chapter">VMOD - Varnish Modules</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="directors.html"
title="next chapter">Writing a Director</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/vmod_generated.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="directors.html" title="Writing a Director"
>next</a> |</li>
<li class="right" >
<a href="vmod.html" title="VMOD - Varnish Modules"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Varnish version 6.0.3 documentation</a> »</li>
<li class="nav-item nav-item-1"><a href="index.html" >The Varnish Reference Manual</a> »</li>
</ul>
</div>
<div class="footer" role="contentinfo">
© Copyright 2010-2014, Varnish Software AS.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.6.
</div>
</body>
</html>