...
 
Commits (7)
......@@ -28,8 +28,10 @@ SYNOPSIS
new <obj> = file.reader(STRING name [, STRING path] [, DURATION ttl])
STRING <obj>.get()
VOID <obj>.synth()
BLOB <obj>.blob()
BOOL <obj>.error()
STRING <obj>.errmsg()
BOOL <obj>.deleted()
BYTES <obj>.size()
TIME <obj>.mtime()
DURATION <obj>.next_check()
......@@ -177,7 +179,7 @@ new xreader = file.reader(STRING name, STRING path, DURATION ttl, BOOL log_check
new xreader = file.reader(
STRING name,
STRING path="/usr/local/etc/varnish:/usr/local/share/varnish/vcl:/usr/etc/varnish:/usr/share/varnish/vcl",
STRING path="/usr/local/etc/varnish:/usr/local/share/varnish/vcl:/etc/varnish:/usr/share/varnish/vcl",
DURATION ttl=120,
BOOL log_checks=0
)
......@@ -312,10 +314,11 @@ message.
VOID xreader.synth()
--------------------
Generate a synthetic client response body from the file contents. This
method may only be called in ``vcl_synth``. Invokes VCL failure if the
most recent update check encountered an error, or if invoked in any
other VCL subroutine besides ``vcl_synth``.
Generate a synthetic response body from the file contents. This method
may only be called in ``vcl_synth`` or ``vcl_backend_error``. Invokes
VCL failure if the most recent update check encountered an error, or
if invoked in any other VCL subroutine besides the two that are
permitted.
Example::
......@@ -323,6 +326,10 @@ Example::
synth_body.synth();
}
sub vcl_backend_error {
synth_body.synth();
}
.. _xreader.blob():
BLOB xreader.blob()
......@@ -425,13 +432,9 @@ encountered an error.
Example::
import std;
# Log a message if the file has not been updated within the last
# day.
if (now - rdr.mtime() > 1d) {
std.log("file last updated at " + rdr.mtime());
}
# A VCL TIME is converted to a string as an HTTP date, and hence is
# suitable for the Last-Modified header.
set resp.http.Last-Modified = rdr.mtime();
.. _xreader.next_check():
......@@ -442,13 +445,12 @@ Return the time remaining until the next check will be performed.
Example::
import vtc;
import std;
# If an update is pending within the next second, wait for it.
if (synth_body.next_check() < 1s) {
vtc.sleep(1s);
synth_body.synth();
}
# Set the downstream caching TTL to the time remaining until the
# next update check.
set resp.http.Cache-Control = "public, max-age="
+ std.integer(duration=rdr.next_check());
.. _file.version():
......
......@@ -64,7 +64,14 @@ AC_SUBST([VARNISH_LIBRARY_PATH],
[$LIBVARNISHAPI_LIBDIR:$LIBVARNISHAPI_LIBDIR/varnish])
# Checks for C sources
# XXX
AC_CHECK_FUNCS([memset])
AC_CHECK_FUNCS([munmap])
AC_CHECK_FUNCS([strchr])
AC_CHECK_FUNCS([strdup])
AC_CHECK_HEADERS([fcntl.h])
AC_FUNC_MALLOC
AC_FUNC_MMAP
AC_TYPE_SIZE_T
# --enable-stack-protector
AC_ARG_ENABLE(stack-protector,
......
......@@ -2,22 +2,34 @@
varnishtest "reader.synth()"
shell {echo -n "foo bar baz quux" > ${tmpdir}/synth}
shell {
echo -n "foo bar baz quux" > ${tmpdir}/synth
echo -n "ouch" > ${tmpdir}/backend_error
}
varnish v1 -vcl {
import ${vmod_file};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new rdr = file.reader("${tmpdir}/synth", ttl=0.1s);
new synth = file.reader("${tmpdir}/synth", ttl=0.1s);
new backend_err = file.reader("${tmpdir}/backend_error");
}
sub vcl_recv {
if (req.url == "/backend") {
return (pass);
}
return (synth(200));
}
sub vcl_synth {
rdr.synth();
synth.synth();
return (deliver);
}
sub vcl_backend_error {
backend_err.synth();
return (deliver);
}
} -start
......@@ -39,6 +51,13 @@ client c1 {
expect resp.body == "quux baz bar foo"
} -run
client c1 {
txreq -url /backend
rxresp
expect resp.status == 503
expect resp.body == "ouch"
} -run
shell {chmod a-r ${tmpdir}/synth}
delay .1
......@@ -49,7 +68,7 @@ client c1 {
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error {^rdr\.synth\(\): vmod file failure: vcl1\.rdr: cannot open}
expect * = VCL_Error {^synth\.synth\(\): vmod file failure: vcl1\.synth: cannot open}
expect * = End
} -run
......@@ -73,7 +92,7 @@ varnish v1 -vcl {
logexpect l1 -v v1 -d 0 -g vxid -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error {^rdr\.synth\(\) may only be called in vcl_synth$}
expect * = VCL_Error {^rdr\.synth\(\) may only be called in vcl_synth or vcl_backend_error$}
expect * = End
} -start
......
......@@ -445,7 +445,6 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
AZ(rdr->flags & RDR_DELETED);
AN(rdr->addr);
AN(rdr->info->mtime.tv_sec);
AN(rdr->info->mtime.tv_nsec);
*rdrp = rdr;
}
......@@ -531,9 +530,9 @@ vmod_reader_synth(VRT_CTX, struct VPFX(file_reader) *rdr)
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(rdr, FILE_READER_MAGIC);
if ((ctx->method & VCL_MET_SYNTH) == 0) {
VRT_fail(ctx, "%s.synth() may only be called in vcl_synth",
rdr->obj_name);
if ((ctx->method & (VCL_MET_SYNTH | VCL_MET_BACKEND_ERROR)) == 0) {
VRT_fail(ctx, "%s.synth() may only be called in vcl_synth or "
"vcl_backend_error", rdr->obj_name);
return;
}
......
......@@ -24,8 +24,10 @@ SYNOPSIS
new <obj> = file.reader(STRING name [, STRING path] [, DURATION ttl])
STRING <obj>.get()
VOID <obj>.synth()
BLOB <obj>.blob()
BOOL <obj>.error()
STRING <obj>.errmsg()
BOOL <obj>.deleted()
BYTES <obj>.size()
TIME <obj>.mtime()
DURATION <obj>.next_check()
......@@ -165,7 +167,7 @@ is followed.
.. _reader object:
$Object reader(PRIV_VCL, STRING name,
STRING path="/usr/local/etc/varnish:/usr/local/share/varnish/vcl:/usr/etc/varnish:/usr/share/varnish/vcl",
STRING path="/usr/local/etc/varnish:/usr/local/share/varnish/vcl:/etc/varnish:/usr/share/varnish/vcl",
DURATION ttl=120, BOOL log_checks=0)
Create an object to read and cache the contents of the file named
......@@ -292,10 +294,11 @@ message.
$Method VOID .synth()
Generate a synthetic client response body from the file contents. This
method may only be called in ``vcl_synth``. Invokes VCL failure if the
most recent update check encountered an error, or if invoked in any
other VCL subroutine besides ``vcl_synth``.
Generate a synthetic response body from the file contents. This method
may only be called in ``vcl_synth`` or ``vcl_backend_error``. Invokes
VCL failure if the most recent update check encountered an error, or
if invoked in any other VCL subroutine besides the two that are
permitted.
Example::
......@@ -303,6 +306,10 @@ Example::
synth_body.synth();
}
sub vcl_backend_error {
synth_body.synth();
}
$Method BLOB .blob()
Return the file's contents as a BLOB. Invokes VCL failure if the most
......@@ -387,13 +394,9 @@ encountered an error.
Example::
import std;
# Log a message if the file has not been updated within the last
# day.
if (now - rdr.mtime() > 1d) {
std.log("file last updated at " + rdr.mtime());
}
# A VCL TIME is converted to a string as an HTTP date, and hence is
# suitable for the Last-Modified header.
set resp.http.Last-Modified = rdr.mtime();
$Method DURATION .next_check()
......@@ -401,13 +404,12 @@ Return the time remaining until the next check will be performed.
Example::
import vtc;
import std;
# If an update is pending within the next second, wait for it.
if (synth_body.next_check() < 1s) {
vtc.sleep(1s);
synth_body.synth();
}
# Set the downstream caching TTL to the time remaining until the
# next update check.
set resp.http.Cache-Control = "public, max-age="
+ std.integer(duration=rdr.next_check());
$Function STRING version()
......