From geoff at varnish-cache.org Fri Jul 8 09:47:32 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:32 +0200 Subject: [experimental-ims] 6e50c1d Reference varnish-cli + -n semantics Message-ID: commit 6e50c1d6ee44b3d2c510c08abdf5577f6240cf8d Author: Per Buer Date: Fri Apr 29 18:44:29 2011 +0200 Reference varnish-cli + -n semantics diff --git a/doc/sphinx/reference/varnishadm.rst b/doc/sphinx/reference/varnishadm.rst index af68355..70758fb 100644 --- a/doc/sphinx/reference/varnishadm.rst +++ b/doc/sphinx/reference/varnishadm.rst @@ -9,7 +9,7 @@ Control a running varnish instance :Author: Cecilie Fritzvold :Author: Per Buer :Date: 2010-05-31 -:Version: 0.2 +:Version: 0.3 :Manual section: 1 SYNOPSIS @@ -21,7 +21,10 @@ DESCRIPTION =========== The varnishadm utility establishes a CLI connection to varnishd either -using -n *name* or using the -T and -S arguments. If -n *name* is the location of the secret file and the address:port is looked up in shared memory. If neither is given varnishadm will look for an instance without a given name. +using -n *name* or using the -T and -S arguments. If -n *name* is +given the location of the secret file and the address:port is looked +up in shared memory. If neither is given varnishadm will look for an +instance without a given name. If a command is given, the command and arguments are sent over the CLI connection and the result returned on stdout. @@ -46,10 +49,13 @@ OPTIONS -n name Connect to the instance of varnishd with this name. -Available commands and parameters are documented in the varnishd(1) -manual page. Additionally, a summary of commands can be obtained by -issuing the *help* command, and a summary of parameters can be -obtained by issuing the *param.show* command. +The syntax and operation of the actual CLI interface is described in +the varnish-cli(7) manual page. Parameteres are described in +varnishd(1) manual page. + +Additionally, a summary of commands can be obtained by issuing the +*help* command, and a summary of parameters can be obtained by issuing +the *param.show* command. EXIT STATUS =========== From geoff at varnish-cache.org Fri Jul 8 09:47:32 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:32 +0200 Subject: [experimental-ims] 2345b5a reference varnish-cli(7) Message-ID: commit 2345b5a7d83bcd03dc1ab08f6856db7934a375ea Author: Per Buer Date: Fri Apr 29 18:46:08 2011 +0200 reference varnish-cli(7) diff --git a/doc/sphinx/reference/varnishd.rst b/doc/sphinx/reference/varnishd.rst index 1d3add5..e18c412 100644 --- a/doc/sphinx/reference/varnishd.rst +++ b/doc/sphinx/reference/varnishd.rst @@ -766,6 +766,7 @@ waiter SEE ALSO ======== +* varnish-cli(7) * varnishlog(1) * varnishhist(1) * varnishncsa(1) From geoff at varnish-cache.org Fri Jul 8 09:47:32 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:32 +0200 Subject: [experimental-ims] 44e493f Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache Message-ID: commit 44e493fed07efb15bb21d0172bf004ef50a3846b Merge: 2345b5a 5d5c345 Author: Per Buer Date: Fri Apr 29 18:46:28 2011 +0200 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache From geoff at varnish-cache.org Fri Jul 8 09:47:33 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:33 +0200 Subject: [experimental-ims] 8b892f9 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache Message-ID: commit 8b892f9ad20ffd9feac66a051ef18fb5bb649497 Merge: 44e493f 5e2c77b Author: Per Buer Date: Fri May 20 20:01:47 2011 +0200 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache From geoff at varnish-cache.org Fri Jul 8 09:47:33 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:33 +0200 Subject: [experimental-ims] c9c8716 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache Message-ID: commit c9c8716cd269db8f7ee6e9612f52ad22b6745749 Merge: 8b892f9 0fb00eb Author: Per Buer Date: Mon May 23 13:10:28 2011 +0200 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache From geoff at varnish-cache.org Fri Jul 8 09:47:33 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:33 +0200 Subject: [experimental-ims] 48392ad Fix crash in varnishadm when secret file is unreadable Message-ID: commit 48392ad84205195f8d624e281f3b93d7d736ce46 Author: Tollef Fog Heen Date: Thu Jun 9 08:51:13 2011 +0200 Fix crash in varnishadm when secret file is unreadable Record the original strdup-ed value so we can free it afterwards. Fixes: #935 diff --git a/bin/varnishadm/varnishadm.c b/bin/varnishadm/varnishadm.c index baa4048..46273bc 100644 --- a/bin/varnishadm/varnishadm.c +++ b/bin/varnishadm/varnishadm.c @@ -274,7 +274,7 @@ usage(void) static int n_arg_sock(const char *n_arg) { - char *T_arg = NULL; + char *T_arg = NULL, *T_start = NULL; char *S_arg = NULL; struct VSM_data *vsd; char *p; @@ -292,7 +292,7 @@ n_arg_sock(const char *n_arg) fprintf(stderr, "No -T arg in shared memory\n"); return (-1); } - T_arg = strdup(p); + T_start = T_arg = strdup(p); } if (S_arg == NULL) { p = VSM_Find_Chunk(vsd, "Arg", "-S", "", NULL); @@ -309,7 +309,7 @@ n_arg_sock(const char *n_arg) break; T_arg = p + 1; } - free(T_arg); + free(T_start); free(S_arg); return (sock); } From geoff at varnish-cache.org Fri Jul 8 09:47:34 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:34 +0200 Subject: [experimental-ims] 7077261 Mark synthetic as only available in vcl_error Message-ID: commit 7077261e1b1cb38ab152119742a6a001748e8901 Author: Tollef Fog Heen Date: Thu Jun 9 09:05:41 2011 +0200 Mark synthetic as only available in vcl_error Eventually, we want to be able to do synthetic everywhere, but for now, mark it as just available in vcl_error. Fixes: #936 diff --git a/bin/varnishtest/tests/r00936.vtc b/bin/varnishtest/tests/r00936.vtc new file mode 100644 index 0000000..544245a --- /dev/null +++ b/bin/varnishtest/tests/r00936.vtc @@ -0,0 +1,15 @@ +varnishtest "synthetic is only allowed in error" + +server s1 { + rxreq + txresp +} -start + +varnish v1 -badvcl { + backend foo { .host = "127.0.0.1"; } + + sub vcl_recv { + synthetic "HELLOO"; return (error); + } +} + diff --git a/lib/libvcl/vcc_action.c b/lib/libvcl/vcc_action.c index 801360a..0600fd0 100644 --- a/lib/libvcl/vcc_action.c +++ b/lib/libvcl/vcc_action.c @@ -342,7 +342,7 @@ static struct action_table { { "return", parse_return }, { "rollback", parse_rollback }, { "set", parse_set }, - { "synthetic", parse_synthetic }, + { "synthetic", parse_synthetic, VCL_MET_ERROR }, { "unset", parse_unset }, { "purge", parse_purge, VCL_MET_MISS | VCL_MET_HIT }, { NULL, NULL } From geoff at varnish-cache.org Fri Jul 8 09:47:34 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:34 +0200 Subject: [experimental-ims] d81cc9b Always exit if no socket could be connected Message-ID: commit d81cc9b5f4a1d960d6375f67b6cd0a71bbb8f565 Author: Martin Blix Grydeland Date: Thu Jun 9 14:00:09 2011 +0200 Always exit if no socket could be connected diff --git a/bin/varnishadm/varnishadm.c b/bin/varnishadm/varnishadm.c index 46273bc..151a437 100644 --- a/bin/varnishadm/varnishadm.c +++ b/bin/varnishadm/varnishadm.c @@ -349,16 +349,14 @@ main(int argc, char * const *argv) usage(); } sock = n_arg_sock(n_arg); - if (sock < 0) - exit(2); } else if (T_arg == NULL) { sock = n_arg_sock(""); - if (sock < 0) - exit(2); } else { assert(T_arg != NULL); sock = cli_sock(T_arg, S_arg); } + if (sock < 0) + exit(2); if (argc > 0) do_args(sock, argc, argv); From geoff at varnish-cache.org Fri Jul 8 09:47:34 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:34 +0200 Subject: [experimental-ims] 939d229 Seed random() on startup from /dev/urandom so vtmpfile actually returns random file names Message-ID: commit 939d2299c51c8af03b663185b79c49e3d7833d86 Author: Martin Blix Grydeland Date: Fri Jun 10 09:43:48 2011 +0200 Seed random() on startup from /dev/urandom so vtmpfile actually returns random file names diff --git a/bin/varnishd/varnishd.c b/bin/varnishd/varnishd.c index 9dae7d3..ded54ae 100644 --- a/bin/varnishd/varnishd.c +++ b/bin/varnishd/varnishd.c @@ -364,6 +364,8 @@ main(int argc, char * const *argv) for (o = getdtablesize(); o > STDERR_FILENO; o--) (void)close(o); + AZ(seed_random()); + mgt_got_fd(STDERR_FILENO); setbuf(stdout, NULL); diff --git a/include/libvarnish.h b/include/libvarnish.h index afa9f2f..317dc9e 100644 --- a/include/libvarnish.h +++ b/include/libvarnish.h @@ -99,6 +99,7 @@ struct timeval TIM_timeval(double t); void VCS_Message(const char *); /* from libvarnish/vtmpfile.c */ +int seed_random(void); int vtmpfile(char *); char *vreadfile(const char *pfx, const char *fn, ssize_t *sz); char *vreadfd(int fd, ssize_t *sz); diff --git a/lib/libvarnish/vtmpfile.c b/lib/libvarnish/vtmpfile.c index 63dde2d..60a9c21 100644 --- a/lib/libvarnish/vtmpfile.c +++ b/lib/libvarnish/vtmpfile.c @@ -41,6 +41,22 @@ #include "libvarnish.h" int +seed_random(void) +{ + int fd; + unsigned seed; + + fd = open("/dev/urandom", O_RDONLY); + if (fd == -1) + return (1); + if (read(fd, &seed, sizeof seed) != sizeof seed) + return (1); + (void)close(fd); + srandom(seed); + return (0); +} + +int vtmpfile(char *template) { char *b, *e, *p; From geoff at varnish-cache.org Fri Jul 8 09:47:36 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:36 +0200 Subject: [experimental-ims] c316746 Attempt a distclean first, something gets cached otherwise. Message-ID: commit c316746df309e7adf720cf4a1a38889e390aa273 Author: Poul-Henning Kamp Date: Tue Jun 14 08:42:04 2011 +0000 Attempt a distclean first, something gets cached otherwise. diff --git a/autogen.des b/autogen.des index a75d482..58f3c2b 100755 --- a/autogen.des +++ b/autogen.des @@ -4,6 +4,8 @@ set -ex +make -k distclean > /dev/null 2>&1 || true + # Prefer CLANG if we have it, and have not given preferences if [ -f /usr/bin/clang -a "x${CC}" = "x" ] ; then CC=clang From geoff at varnish-cache.org Fri Jul 8 09:47:36 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:36 +0200 Subject: [experimental-ims] 099c22c Request specific variables are not available in vcl_init{} and vcl_fini{} Message-ID: commit 099c22c01cadd01ef96d98f77e0c0e2b173f6ae6 Author: Poul-Henning Kamp Date: Thu Jun 16 06:25:44 2011 +0000 Request specific variables are not available in vcl_init{} and vcl_fini{} diff --git a/lib/libvcl/generate.py b/lib/libvcl/generate.py index ffb8a08..5407a51 100755 --- a/lib/libvcl/generate.py +++ b/lib/libvcl/generate.py @@ -98,107 +98,110 @@ returns =( ####################################################################### # Variables available in sessions +# +# 'all' means all methods +# 'proc' means all methods but 'init' and 'fini' sp_variables = ( ('client.ip', 'IP', - ( 'all',), + ( 'proc',), ( ), 'const struct sess *' ), ('client.identity', 'STRING', - ( 'all',), - ( 'all',), + ( 'proc',), + ( 'proc',), 'struct sess *' ), ('server.ip', 'IP', - ( 'all',), + ( 'proc',), ( ), 'struct sess *' ), ('server.hostname', 'STRING', - ( 'all',), + ( 'proc',), ( ), 'struct sess *' ), ('server.identity', 'STRING', - ( 'all',), + ( 'proc',), ( ), 'struct sess *' ), ('server.port', 'INT', - ( 'all',), + ( 'proc',), ( ), 'struct sess *' ), ('req.request', 'STRING', - ( 'all',), - ( 'all',), + ( 'proc',), + ( 'proc',), 'const struct sess *' ), ('req.url', 'STRING', - ( 'all',), - ( 'all',), + ( 'proc',), + ( 'proc',), 'const struct sess *' ), ('req.proto', 'STRING', - ( 'all',), - ( 'all',), + ( 'proc',), + ( 'proc',), 'const struct sess *' ), ('req.http.', 'HDR_REQ', - ( 'all',), - ( 'all',), + ( 'proc',), + ( 'proc',), 'const struct sess *' ), ('req.backend', 'BACKEND', - ( 'all',), - ( 'all',), + ( 'proc',), + ( 'proc',), 'struct sess *' ), ('req.restarts', 'INT', - ( 'all',), + ( 'proc',), ( ), 'const struct sess *' ), ('req.esi_level', 'INT', - ( 'all',), + ( 'proc',), ( ), 'const struct sess *' ), ('req.ttl', 'DURATION', - ( 'all',), - ( 'all',), + ( 'proc',), + ( 'proc',), 'struct sess *' ), ('req.grace', 'DURATION', - ( 'all',), - ( 'all',), + ( 'proc',), + ( 'proc',), 'struct sess *' ), ('req.keep', 'DURATION', - ( 'all',), - ( 'all',), + ( 'proc',), + ( 'proc',), 'struct sess *' ), ('req.xid', 'STRING', - ( 'all',), + ( 'proc',), ( ), 'struct sess *' ), @@ -210,13 +213,13 @@ sp_variables = ( ), ('req.can_gzip', 'BOOL', - ( 'all',), + ( 'proc',), ( ), 'struct sess *' ), ('req.backend.healthy', 'BOOL', - ( 'all',), + ( 'proc',), ( ), 'const struct sess *' ), @@ -773,6 +776,11 @@ def restrict(fo, spec): return if spec[0] == 'all': spec = vcls + if spec[0] == 'proc': + spec = list() + for i in vcls: + if i != "init" and i != "fini": + spec.append(i) p = "" n = 0 for j in spec: From geoff at varnish-cache.org Fri Jul 8 09:47:37 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:37 +0200 Subject: [experimental-ims] ecacfef Fix type for grabbing size of a regex Message-ID: commit ecacfefabffc7364e59ae5082c8d261fda5817fb Author: Tollef Fog Heen Date: Thu Jun 16 13:26:56 2011 +0200 Fix type for grabbing size of a regex The size of a regex is a size_t. Spotted by gcc 4.6 diff --git a/bin/varnishd/cache_ban.c b/bin/varnishd/cache_ban.c index d62cac6..bbfe57f 100644 --- a/bin/varnishd/cache_ban.c +++ b/bin/varnishd/cache_ban.c @@ -292,7 +292,8 @@ static int ban_parse_regexp(struct cli *cli, const struct ban *b, const char *a3) { const char *error; - int erroroffset, rc, sz; + int erroroffset, rc; + size_t sz; pcre *re; re = pcre_compile(a3, 0, &error, &erroroffset, NULL); From geoff at varnish-cache.org Fri Jul 8 09:47:37 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:37 +0200 Subject: [experimental-ims] 9d176e5 Fix docs for do_gzip default value Message-ID: commit 9d176e5b2ed233a06dbd712a020957b71e2f87d3 Author: Tollef Fog Heen Date: Thu Jun 16 13:30:35 2011 +0200 Fix docs for do_gzip default value diff --git a/doc/sphinx/reference/vcl.rst b/doc/sphinx/reference/vcl.rst index 17ccf88..46efc67 100644 --- a/doc/sphinx/reference/vcl.rst +++ b/doc/sphinx/reference/vcl.rst @@ -652,7 +652,7 @@ beresp.do_esi to true to parse the object for ESI directives. beresp.do_gzip - Boolean. Gzip the object before storing it. Defaults to true. + Boolean. Gzip the object before storing it. Defaults to false. beresp.do_gunzip Boolean. Unzip the object before storing it in the cache. Defaults From geoff at varnish-cache.org Fri Jul 8 09:47:38 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:38 +0200 Subject: [experimental-ims] a6d2df9 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache Message-ID: commit a6d2df9e75e7dda1002499e73c4b5a7ef3b16ff3 Merge: 099c22c 9d176e5 Author: Poul-Henning Kamp Date: Thu Jun 16 21:04:59 2011 +0000 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache From geoff at varnish-cache.org Fri Jul 8 09:47:38 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:38 +0200 Subject: [experimental-ims] 999cb33 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache Message-ID: commit 999cb3318220580a1ae6453fc9b7bd0284e929ac Merge: c9c8716 a6d2df9 Author: Per Buer Date: Sat Jun 18 15:25:58 2011 +0200 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache From geoff at varnish-cache.org Fri Jul 8 09:47:38 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:38 +0200 Subject: [experimental-ims] b0fb05b Change master version back to trunk Message-ID: commit b0fb05b4dd284bcb641110dd2e17e6fcc254d333 Author: Tollef Fog Heen Date: Sat Jun 18 19:01:59 2011 +0200 Change master version back to trunk diff --git a/configure.ac b/configure.ac index 57287f5..1cdaa0c 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.59) AC_COPYRIGHT([Copyright (c) 2006 Verdens Gang AS Copyright (c) 2006-2011 Varnish Software AS]) AC_REVISION([$Id$]) -AC_INIT([Varnish], [3.0.0-beta2], [varnish-dev at varnish-cache.org]) +AC_INIT([Varnish], [trunk], [varnish-dev at varnish-cache.org]) AC_CONFIG_SRCDIR(include/varnishapi.h) AM_CONFIG_HEADER(config.h) From geoff at varnish-cache.org Fri Jul 8 09:47:44 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:44 +0200 Subject: [experimental-ims] e0bed1a Move the length field to the front of entries in the vary string. Message-ID: commit e0bed1afe24db8fac6206c3ba85d5ccc0f228112 Author: Poul-Henning Kamp Date: Tue Jun 21 09:38:55 2011 +0000 Move the length field to the front of entries in the vary string. diff --git a/bin/varnishd/cache_vary.c b/bin/varnishd/cache_vary.c index 1300a20..c8578d1 100644 --- a/bin/varnishd/cache_vary.c +++ b/bin/varnishd/cache_vary.c @@ -41,13 +41,13 @@ * The vary matching string has the following format: * * Sequence of: { + * \ Length of header contents. + * / * \ *
\ Same format as argument to http_GetHdr() * ':' / * '\0' / - * \ Length of header contents. - * / - *
Only present if length != 0xffff + *
> Only present if length != 0xffff * } * '\0' */ @@ -97,9 +97,6 @@ VRY_Create(const struct sess *sp, const struct http *hp) (char)(1 + (q - p)), (int)(q - p), p, 0); AZ(VSB_finish(sbh)); - /* Append to vary matching string */ - VSB_bcat(sb, VSB_data(sbh), VSB_len(sbh)); - if (http_GetHdr(sp->http, VSB_data(sbh), &h)) { /* Trim leading and trailing space */ while (isspace(*h)) @@ -110,12 +107,15 @@ VRY_Create(const struct sess *sp, const struct http *hp) /* Encode two byte length and contents */ l = e - h; assert(!(l & ~0xffff)); - VSB_printf(sb, "%c%c", (unsigned)l >> 8, l & 0xff); - VSB_bcat(sb, h, e - h); } else { - /* Mark as "not present" */ - VSB_printf(sb, "%c%c", 0xff, 0xff); + e = h; + l = 0xffff; } + VSB_printf(sb, "%c%c", (unsigned)l >> 8, l & 0xff); + /* Append to vary matching string */ + VSB_bcat(sb, VSB_data(sbh), VSB_len(sbh)); + if (e != h) + VSB_bcat(sb, h, e - h); while (isspace(*q)) q++; @@ -125,7 +125,7 @@ VRY_Create(const struct sess *sp, const struct http *hp) p = q; } /* Terminate vary matching string */ - VSB_printf(sb, "%c", 0); + VSB_printf(sb, "%c%c%c", 0xff, 0xff, 0); VSB_delete(sbh); AZ(VSB_finish(sb)); @@ -133,12 +133,16 @@ VRY_Create(const struct sess *sp, const struct http *hp) } int -VRY_Match(const struct sess *sp, const unsigned char *vary) +VRY_Match(const struct sess *sp, const uint8_t *vary) { char *h, *e; int i, l, lh; - while (*vary) { + while (1) { + l = vary[0] * 256 + vary[1]; + vary += 2; + if (!*vary) + break; if (params->http_gzip_support && !strcasecmp(H_Accept_Encoding, (const char*)vary)) { @@ -152,8 +156,6 @@ VRY_Match(const struct sess *sp, const unsigned char *vary) * setting of http_gzip_support. */ vary += *vary + 2; - l = vary[0] * 256 + vary[1]; - vary += 2; if (l != 0xffff) vary += l; continue; @@ -162,10 +164,6 @@ VRY_Match(const struct sess *sp, const unsigned char *vary) i = http_GetHdr(sp->http, (const char*)vary, &h); vary += *vary + 2; - /* Expected length of header (or 0xffff) */ - l = vary[0] * 256 + vary[1]; - vary += 2; - /* Fail if we have the header, but shouldn't */ if (i && l == 0xffff) return (0); From geoff at varnish-cache.org Fri Jul 8 09:47:44 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:44 +0200 Subject: [experimental-ims] 7bc0068 Overhaul the Vary matching code to make it faster, by assuming (but do not trusting) that all objects under an objhdr have the same Vary string. Message-ID: commit 7bc0068d8f422c917042e35867e00a19f8956f46 Author: Poul-Henning Kamp Date: Tue Jun 21 11:55:07 2011 +0000 Overhaul the Vary matching code to make it faster, by assuming (but do not trusting) that all objects under an objhdr have the same Vary string. Build a vary string for the request on the wrk->ws as we do the comparison and use it as a cache for subsequent comparisons. This will also be first step of sky's "pre-vary" diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index f8dedb1..22fa5ff 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -298,7 +298,11 @@ struct worker { uint32_t *wlb, *wlp, *wle; unsigned wlr; + /* Lookup stuff */ struct SHA256Context *sha256ctx; + uint8_t *vary_b; + uint8_t *vary_l; + uint8_t *vary_e; struct http_conn htc[1]; struct ws ws[1]; @@ -880,7 +884,7 @@ void RES_StreamPoll(const struct sess *sp); /* cache_vary.c */ struct vsb *VRY_Create(const struct sess *sp, const struct http *hp); -int VRY_Match(const struct sess *sp, const unsigned char *vary); +int VRY_Match(const struct sess *sp, const uint8_t *vary); /* cache_vcl.c */ void VCL_Init(void); diff --git a/bin/varnishd/cache_hash.c b/bin/varnishd/cache_hash.c index 2a6dcc5..0324b57 100644 --- a/bin/varnishd/cache_hash.c +++ b/bin/varnishd/cache_hash.c @@ -330,6 +330,13 @@ HSH_Lookup(struct sess *sp, struct objhead **poh) } CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); + AZ(sp->wrk->vary_b); + AZ(sp->wrk->vary_l); + AZ(sp->wrk->vary_e); + WS_Reserve(sp->wrk->ws, 0); + sp->wrk->vary_b = (void*)sp->wrk->ws->f; + sp->wrk->vary_e = (void*)sp->wrk->ws->r; + sp->wrk->vary_b[2] = '\0'; Lck_Lock(&oh->mtx); assert(oh->refcnt > 0); busy_oc = NULL; @@ -374,6 +381,11 @@ HSH_Lookup(struct sess *sp, struct objhead **poh) } } + WS_ReleaseP(sp->wrk->ws, (void*)sp->wrk->vary_b); + sp->wrk->vary_b = NULL; + sp->wrk->vary_l = NULL; + sp->wrk->vary_e = NULL; + /* * If we have seen a busy object or the backend is unhealthy, and * we have an object in grace, use it, if req.grace is also diff --git a/bin/varnishd/cache_vary.c b/bin/varnishd/cache_vary.c index 8eab103..27abf74 100644 --- a/bin/varnishd/cache_vary.c +++ b/bin/varnishd/cache_vary.c @@ -58,6 +58,7 @@ #include #include "cache.h" +#include "vend.h" #include "vct.h" struct vsb * @@ -131,63 +132,112 @@ VRY_Create(const struct sess *sp, const struct http *hp) return(sb); } +/* + * Find length of a vary entry + */ +static unsigned +vry_len(const uint8_t *p) +{ + unsigned l = vbe16dec(p); + + return (2 + p[2] + 2 + (l == 0xffff ? 0 : l)); +} + +/* + * Compare two vary entries + */ +static int +vry_cmp(const uint8_t * const *v1, uint8_t * const *v2) +{ + unsigned retval = 0; + + if (!memcmp(*v1, *v2, vry_len(*v1))) { + /* Same same */ + retval = 0; + } else if (memcmp((*v1) + 2, (*v2) + 2, (*v1)[2] + 2)) { + /* Different header */ + retval = 1; + } else if (params->http_gzip_support && + !strcasecmp(H_Accept_Encoding, (const char*)((*v1)+2))) { + /* + * If we do gzip processing, we do not vary on Accept-Encoding, + * because we want everybody to get the gzip'ed object, and + * varnish will gunzip as necessary. We implement the skip at + * check time, rather than create time, so that object in + * persistent storage can be used with either setting of + * http_gzip_support. + */ + retval = 0; + } else { + /* Same header, different content */ + retval = 2; + } + return (retval); +} + int VRY_Match(const struct sess *sp, const uint8_t *vary) { + uint8_t *vsp = sp->wrk->vary_b; char *h, *e; - int i, l, lh; - - while (1) { - l = vary[0] * 256 + vary[1]; - vary += 2; - if (!*vary) - break; - - if (params->http_gzip_support && - !strcasecmp(H_Accept_Encoding, (const char*)vary)) { - /* - * If we do gzip processing, we do not vary on - * Accept-Encoding, because we want everybody to - * get the gzip'ed object, and varnish will gunzip - * as necessary. We implement the skip at check - * time, rather than create time, so that object - * in persistent storage can be used with either - * setting of http_gzip_support. - */ - vary += *vary + 2; - if (l != 0xffff) - vary += l; - continue; + unsigned lh, ln; + int i, retval = 1, oflo = 0; + + AN(vsp); + while (vary[2]) { + i = vry_cmp(&vary, &vsp); + if (i == 1) { + /* Build a new entry */ + + i = http_GetHdr(sp->http, (const char*)(vary+2), &h); + if (i) { + /* Trim trailing space */ + e = strchr(h, '\0'); + while (e > h && vct_issp(e[-1])) + e--; + lh = e - h; + assert(lh < 0xffff); + } else { + e = h = NULL; + lh = 0xffff; + } + + /* Length of the entire new vary entry */ + ln = 2 + vary[2] + 2 + (lh == 0xffff ? 0 : lh); + if (vsp + ln >= sp->wrk->vary_e) { + vsp = sp->wrk->vary_b; + oflo = 1; + } + + /* We MUST have space for one entry */ + assert(vsp + ln < sp->wrk->vary_e); + + vbe16enc(vsp, (uint16_t)lh); + memcpy(vsp + 2, vary + 2, vary[2] + 2); + if (h != NULL && e != NULL) + memcpy(vsp + 2 + vsp[2] + 2, h, e - h); + + i = vry_cmp(&vary, &vsp); + assert(i != 1); /* hdr must be the same now */ } - /* Look for header */ - i = http_GetHdr(sp->http, (const char*)vary, &h); - vary += *vary + 2; - - /* Fail if we have the header, but shouldn't */ - if (i && l == 0xffff) - return (0); - /* or if we don't when we should */ - if (l != 0xffff && !i) - return (0); - - /* Nothing to match */ - if (!i) - continue; - - /* Trim trailing space */ - e = strchr(h, '\0'); - while (e > h && vct_issp(e[-1])) - e--; - - /* Fail if wrong length */ - lh = e - h; - if (lh != l) - return (0); + if (i != 0) + retval = 0; + vsp += vry_len(vsp); + vary += vry_len(vary); + } + if (vsp + 3 > sp->wrk->vary_e) + oflo = 1; - /* or if wrong contents */ - if (memcmp(h, vary, l)) - return (0); - vary += l; + if (oflo) { + /* XXX: Should log this */ + vsp = sp->wrk->vary_b; } - return (1); + vsp[0] = 0xff; + vsp[1] = 0xff; + vsp[2] = 0; + if (oflo) + sp->wrk->vary_l = NULL; + else + sp->wrk->vary_l = vsp + 3; + return (retval); } From geoff at varnish-cache.org Fri Jul 8 09:47:45 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:45 +0200 Subject: [experimental-ims] 1354bed probes outside directors Message-ID: commit 1354bed1999c463a35b3f451d4b51f42b25e6403 Author: Per Buer Date: Wed Jun 22 10:03:51 2011 +0200 probes outside directors diff --git a/doc/sphinx/reference/vcl.rst b/doc/sphinx/reference/vcl.rst index 46efc67..d0d9d39 100644 --- a/doc/sphinx/reference/vcl.rst +++ b/doc/sphinx/reference/vcl.rst @@ -72,9 +72,6 @@ available where. VCL has if tests, but no loops. -You may log arbitrary strings to the shared memory log with the -keyword *log*. - The contents of another VCL file may be inserted at any point in the code by using the *include* keyword followed by the name of the other file as a quoted string. @@ -236,7 +233,8 @@ us to consider the backend healthy. .initial is how many of the probes are considered good when Varnish starts - defaults to the same amount as the threshold. -A backend with a probe can be defined like this::: +A backend with a probe can be defined like this, together with the +backend or director::: backend www { .host = "www.example.com"; @@ -250,18 +248,34 @@ A backend with a probe can be defined like this::: } } -It is also possible to specify the raw HTTP request:: +Or it can be defined separately and then referenced::: + + probe healthcheck { + .url = "/status.cgi"; + .interval = 60s; + .timeout = 0.3 s; + .window = 8; + .threshold = 3; + .initial = 3; + } backend www { .host = "www.example.com"; .port = "http"; - .probe = { + .probe = healthcheck; + } + +If you have many backends this can simplify the config a lot. + + +It is also possible to specify the raw HTTP request:: + + probe rawprobe { # NB: \r\n automatically inserted after each string! .request = "GET / HTTP/1.1" "Host: www.foo.bar" "Connection: close"; - } } ACLs @@ -819,9 +833,11 @@ based on the request URL::: default_ttl run-time parameter, as that only affects document for which the backend did not specify a TTL::: + import std; # needed for std.log + sub vcl_fetch { if (beresp.ttl < 120s) { - log "Adjusting TTL"; + std.log "Adjusting TTL"; set beresp.ttl = 120s; } } @@ -876,6 +892,7 @@ SEE ALSO ======== * varnishd(1) +* vmod_std(7) HISTORY ======= From geoff at varnish-cache.org Fri Jul 8 09:47:45 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:45 +0200 Subject: [experimental-ims] cdeea12 Don't overwrite reference results unless told to Message-ID: commit cdeea1235a6a1fe78e96327ad290d58547b4e5af Author: Poul-Henning Kamp Date: Wed Jun 22 08:31:56 2011 +0000 Don't overwrite reference results unless told to diff --git a/bin/varnishd/flint.sh b/bin/varnishd/flint.sh index d163374..d87fe66 100755 --- a/bin/varnishd/flint.sh +++ b/bin/varnishd/flint.sh @@ -20,4 +20,6 @@ if [ -f _.fl.old ] ; then diff -u _.fl.old _.fl fi -mv _.fl _.fl.old +if [ "x$1" = "x-ok" ] ; then + mv _.fl _.fl.old +fi From geoff at varnish-cache.org Fri Jul 8 09:47:45 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:45 +0200 Subject: [experimental-ims] ac1e367 Move the setup/teardown of requests vary prediction space from cache_hash to cache_center. Message-ID: commit ac1e3675fe4e573315bc2c4874869c298b206b9d Author: Poul-Henning Kamp Date: Wed Jun 22 08:34:46 2011 +0000 Move the setup/teardown of requests vary prediction space from cache_hash to cache_center. diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index 4a17c56..5b55d58 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -1028,13 +1028,28 @@ cnt_lookup(struct sess *sp) struct objcore *oc; struct object *o; struct objhead *oh; + struct worker *wrk; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC); + wrk = sp->wrk; + AZ(wrk->vary_b); + AZ(wrk->vary_l); + AZ(wrk->vary_e); + (void)WS_Reserve(wrk->ws, 0); + wrk->vary_b = (void*)wrk->ws->f; + wrk->vary_e = (void*)wrk->ws->r; + wrk->vary_b[2] = '\0'; + oc = HSH_Lookup(sp, &oh); + WS_Release(wrk->ws, 0); + wrk->vary_b = NULL; + wrk->vary_l = NULL; + wrk->vary_e = NULL; + if (oc == NULL) { /* * We lost the session to a busy object, disembark the diff --git a/bin/varnishd/cache_hash.c b/bin/varnishd/cache_hash.c index 0324b57..2a6dcc5 100644 --- a/bin/varnishd/cache_hash.c +++ b/bin/varnishd/cache_hash.c @@ -330,13 +330,6 @@ HSH_Lookup(struct sess *sp, struct objhead **poh) } CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); - AZ(sp->wrk->vary_b); - AZ(sp->wrk->vary_l); - AZ(sp->wrk->vary_e); - WS_Reserve(sp->wrk->ws, 0); - sp->wrk->vary_b = (void*)sp->wrk->ws->f; - sp->wrk->vary_e = (void*)sp->wrk->ws->r; - sp->wrk->vary_b[2] = '\0'; Lck_Lock(&oh->mtx); assert(oh->refcnt > 0); busy_oc = NULL; @@ -381,11 +374,6 @@ HSH_Lookup(struct sess *sp, struct objhead **poh) } } - WS_ReleaseP(sp->wrk->ws, (void*)sp->wrk->vary_b); - sp->wrk->vary_b = NULL; - sp->wrk->vary_l = NULL; - sp->wrk->vary_e = NULL; - /* * If we have seen a busy object or the backend is unhealthy, and * we have an object in grace, use it, if req.grace is also From geoff at varnish-cache.org Fri Jul 8 09:47:46 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:46 +0200 Subject: [experimental-ims] a20d6af Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache Message-ID: commit a20d6afad722d306b8f981bfecb53437cd685f5f Merge: ac1e367 1354bed Author: Poul-Henning Kamp Date: Wed Jun 22 08:42:30 2011 +0000 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache From geoff at varnish-cache.org Fri Jul 8 09:47:46 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:46 +0200 Subject: [experimental-ims] b64281a Make sure we neuter the next entry after the one we just created to prevent old junk on the workspace from being taken for valid. Message-ID: commit b64281a7a9f7ce74daad6763c9d34a444c8ac00a Author: Poul-Henning Kamp Date: Wed Jun 22 09:29:46 2011 +0000 Make sure we neuter the next entry after the one we just created to prevent old junk on the workspace from being taken for valid. diff --git a/bin/varnishd/cache_vary.c b/bin/varnishd/cache_vary.c index 27abf74..01816f6 100644 --- a/bin/varnishd/cache_vary.c +++ b/bin/varnishd/cache_vary.c @@ -209,13 +209,19 @@ VRY_Match(const struct sess *sp, const uint8_t *vary) oflo = 1; } - /* We MUST have space for one entry */ - assert(vsp + ln < sp->wrk->vary_e); + /* + * We MUST have space for one entry and the end marker + * after it, which prevents old junk from confusing us + */ + assert(vsp + ln + 2 < sp->wrk->vary_e); vbe16enc(vsp, (uint16_t)lh); memcpy(vsp + 2, vary + 2, vary[2] + 2); - if (h != NULL && e != NULL) + if (h != NULL && e != NULL) { memcpy(vsp + 2 + vsp[2] + 2, h, e - h); + vsp[2 + vary[2] + 2 + (e - h) + 2] = '\0'; + } else + vsp[2 + vary[2] + 2 + 2] = '\0'; i = vry_cmp(&vary, &vsp); assert(i != 1); /* hdr must be the same now */ From geoff at varnish-cache.org Fri Jul 8 09:47:47 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:47 +0200 Subject: [experimental-ims] 8f85e38 Move request vary string from wrk to sess Message-ID: commit 8f85e380960fe09cff72c6e108789f247c08a065 Author: Poul-Henning Kamp Date: Wed Jun 22 10:39:47 2011 +0000 Move request vary string from wrk to sess diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index 22fa5ff..1d3db55 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -300,9 +300,6 @@ struct worker { /* Lookup stuff */ struct SHA256Context *sha256ctx; - uint8_t *vary_b; - uint8_t *vary_l; - uint8_t *vary_e; struct http_conn htc[1]; struct ws ws[1]; @@ -554,6 +551,11 @@ struct sess { unsigned char digest[DIGEST_LEN]; + /* Built Vary string */ + uint8_t *vary_b; + uint8_t *vary_l; + uint8_t *vary_e; + struct http_conn htc[1]; /* Timestamps, all on TIM_real() timescale */ @@ -884,7 +886,7 @@ void RES_StreamPoll(const struct sess *sp); /* cache_vary.c */ struct vsb *VRY_Create(const struct sess *sp, const struct http *hp); -int VRY_Match(const struct sess *sp, const uint8_t *vary); +int VRY_Match(struct sess *sp, const uint8_t *vary); /* cache_vcl.c */ void VCL_Init(void); diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index 5b55d58..23ad92f 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -1028,28 +1028,23 @@ cnt_lookup(struct sess *sp) struct objcore *oc; struct object *o; struct objhead *oh; - struct worker *wrk; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC); - - wrk = sp->wrk; - AZ(wrk->vary_b); - AZ(wrk->vary_l); - AZ(wrk->vary_e); - (void)WS_Reserve(wrk->ws, 0); - wrk->vary_b = (void*)wrk->ws->f; - wrk->vary_e = (void*)wrk->ws->r; - wrk->vary_b[2] = '\0'; + if (sp->hash_objhead == NULL) { + /* Not a waiting list return */ + AZ(sp->vary_b); + AZ(sp->vary_l); + AZ(sp->vary_e); + (void)WS_Reserve(sp->ws, 0); + sp->vary_b = (void*)sp->ws->f; + sp->vary_e = (void*)sp->ws->r; + sp->vary_b[2] = '\0'; + } oc = HSH_Lookup(sp, &oh); - WS_Release(wrk->ws, 0); - wrk->vary_b = NULL; - wrk->vary_l = NULL; - wrk->vary_e = NULL; - if (oc == NULL) { /* * We lost the session to a busy object, disembark the @@ -1060,6 +1055,7 @@ cnt_lookup(struct sess *sp) return (1); } + CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); @@ -1067,6 +1063,14 @@ cnt_lookup(struct sess *sp) if (oc->flags & OC_F_BUSY) { sp->wrk->stats.cache_miss++; + if (sp->vary_l != NULL) + WS_ReleaseP(sp->ws, (void*)sp->vary_l); + else + WS_Release(sp->ws, 0); + sp->vary_b = NULL; + sp->vary_l = NULL; + sp->vary_e = NULL; + sp->objcore = oc; sp->step = STP_MISS; return (0); @@ -1076,6 +1080,11 @@ cnt_lookup(struct sess *sp) CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); sp->obj = o; + WS_Release(sp->ws, 0); + sp->vary_b = NULL; + sp->vary_l = NULL; + sp->vary_e = NULL; + if (oc->flags & OC_F_PASS) { sp->wrk->stats.cache_hitpass++; WSP(sp, SLT_HitPass, "%u", sp->obj->xid); diff --git a/bin/varnishd/cache_vary.c b/bin/varnishd/cache_vary.c index 01816f6..89e1675 100644 --- a/bin/varnishd/cache_vary.c +++ b/bin/varnishd/cache_vary.c @@ -176,9 +176,9 @@ vry_cmp(const uint8_t * const *v1, uint8_t * const *v2) } int -VRY_Match(const struct sess *sp, const uint8_t *vary) +VRY_Match(struct sess *sp, const uint8_t *vary) { - uint8_t *vsp = sp->wrk->vary_b; + uint8_t *vsp = sp->vary_b; char *h, *e; unsigned lh, ln; int i, retval = 1, oflo = 0; @@ -204,8 +204,8 @@ VRY_Match(const struct sess *sp, const uint8_t *vary) /* Length of the entire new vary entry */ ln = 2 + vary[2] + 2 + (lh == 0xffff ? 0 : lh); - if (vsp + ln >= sp->wrk->vary_e) { - vsp = sp->wrk->vary_b; + if (vsp + ln >= sp->vary_e) { + vsp = sp->vary_b; oflo = 1; } @@ -213,7 +213,7 @@ VRY_Match(const struct sess *sp, const uint8_t *vary) * We MUST have space for one entry and the end marker * after it, which prevents old junk from confusing us */ - assert(vsp + ln + 2 < sp->wrk->vary_e); + assert(vsp + ln + 2 < sp->vary_e); vbe16enc(vsp, (uint16_t)lh); memcpy(vsp + 2, vary + 2, vary[2] + 2); @@ -231,19 +231,19 @@ VRY_Match(const struct sess *sp, const uint8_t *vary) vsp += vry_len(vsp); vary += vry_len(vary); } - if (vsp + 3 > sp->wrk->vary_e) + if (vsp + 3 > sp->vary_e) oflo = 1; if (oflo) { /* XXX: Should log this */ - vsp = sp->wrk->vary_b; + vsp = sp->vary_b; } vsp[0] = 0xff; vsp[1] = 0xff; vsp[2] = 0; if (oflo) - sp->wrk->vary_l = NULL; + sp->vary_l = NULL; else - sp->wrk->vary_l = vsp + 3; + sp->vary_l = vsp + 3; return (retval); } From geoff at varnish-cache.org Fri Jul 8 09:47:47 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:47 +0200 Subject: [experimental-ims] 91f22a1 Remove unused/unreferenced stuff. Message-ID: commit 91f22a160fe2f63d4a85d525fa0e70b4c3c9395e Author: Poul-Henning Kamp Date: Wed Jun 22 10:51:08 2011 +0000 Remove unused/unreferenced stuff. Not detected by: FlexeLint 9.00f Detected by: FlexeLint 9.00g diff --git a/include/libvarnish.h b/include/libvarnish.h index 317dc9e..157a64e 100644 --- a/include/libvarnish.h +++ b/include/libvarnish.h @@ -104,8 +104,6 @@ int vtmpfile(char *); char *vreadfile(const char *pfx, const char *fn, ssize_t *sz); char *vreadfd(int fd, ssize_t *sz); -const char* VCS_Version(void); - /* Safe printf into a fixed-size buffer */ #define bprintf(buf, fmt, ...) \ do { \ diff --git a/lib/libvcl/vcc_backend.c b/lib/libvcl/vcc_backend.c index 3198ce1..f90c1b1 100644 --- a/lib/libvcl/vcc_backend.c +++ b/lib/libvcl/vcc_backend.c @@ -211,44 +211,6 @@ Emit_Sockaddr(struct vcc *tl, const struct token *t_host, const char *port) } /*-------------------------------------------------------------------- - * When a new VCL is loaded, it is likely to contain backend declarations - * identical to other loaded VCL programs, and we want to reuse the state - * of those in order to not have to relearn statistics, DNS etc. - * - * This function emits a space separated text-string of the tokens which - * define a given backend which can be used to determine "identical backend" - * in that context. - */ - -void -vcc_EmitBeIdent(const struct vcc *tl, struct vsb *v, - int serial, const struct token *first, const struct token *last) -{ - - assert(first != last); - VSB_printf(v, "\t.ident ="); - if (serial >= 0) { - VSB_printf(v, "\n\t \"%.*s %.*s [%d] \"", - PF(tl->t_policy), PF(tl->t_dir), serial); - } else { - VSB_printf(v, "\n\t \"%.*s %.*s \"", - PF(tl->t_policy), PF(tl->t_dir)); - } - while (1) { - if (first->dec != NULL) - VSB_printf(v, "\n\t \"\\\"\" %.*s \"\\\" \"", - PF(first)); - else - VSB_printf(v, "\n\t \"%.*s \"", PF(first)); - if (first == last) - break; - first = VTAILQ_NEXT(first, list); - AN(first); - } - VSB_printf(v, ",\n"); -} - -/*-------------------------------------------------------------------- * Parse a backend probe specification */ diff --git a/lib/libvcl/vcc_compile.h b/lib/libvcl/vcc_compile.h index c90d225..b8c8454 100644 --- a/lib/libvcl/vcc_compile.h +++ b/lib/libvcl/vcc_compile.h @@ -210,8 +210,6 @@ void vcc_IsField(struct vcc *tl, struct token **t, struct fld_spec *fs); void vcc_FieldsOk(struct vcc *tl, const struct fld_spec *fs); void Emit_Sockaddr(struct vcc *tl, const struct token *t_host, const char *port); -void vcc_EmitBeIdent(const struct vcc *tl, struct vsb *v, - int serial, const struct token *first, const struct token *last); /* vcc_compile.c */ extern struct method method_tab[]; @@ -245,7 +243,6 @@ parsedirector_f vcc_ParseRoundRobinDirector; void vcc_RTimeVal(struct vcc *tl, double *); void vcc_TimeVal(struct vcc *tl, double *); unsigned vcc_UintVal(struct vcc *tl); -double vcc_DoubleVal(struct vcc *tl); void vcc_Expr(struct vcc *tl, enum var_type typ); void vcc_Expr_Call(struct vcc *tl, const struct symbol *sym); void vcc_Expr_Init(struct vcc *tl); @@ -267,8 +264,6 @@ sym_wildcard_t vcc_Stv_Wildcard; /* vcc_string.c */ char *vcc_regexp(struct vcc *tl); -int vcc_StringVal(struct vcc *tl); -void vcc_ExpectedStringval(struct vcc *tl); /* vcc_symb.c */ struct symbol *VCC_AddSymbolStr(struct vcc *tl, const char *name, enum symkind); @@ -303,8 +298,6 @@ void vcc_AddToken(struct vcc *tl, unsigned tok, const char *b, sym_wildcard_t vcc_Var_Wildcard; const struct var *vcc_FindVar(struct vcc *tl, const struct token *t, int wr_access, const char *use); -void vcc_VarVal(struct vcc *tl, const struct var *vp, - const struct token *vt); /* vcc_vmod.c */ void vcc_ParseImport(struct vcc *tl); diff --git a/lib/libvcl/vcc_expr.c b/lib/libvcl/vcc_expr.c index 82a8aba..9a504e5 100644 --- a/lib/libvcl/vcc_expr.c +++ b/lib/libvcl/vcc_expr.c @@ -145,7 +145,7 @@ vcc_NumVal(struct vcc *tl, double *d, int *frac) vcc_NextToken(tl); } -double +static double vcc_DoubleVal(struct vcc *tl) { double d; diff --git a/lib/libvcl/vcc_var.c b/lib/libvcl/vcc_var.c index 94a5fb9..3871dbc 100644 --- a/lib/libvcl/vcc_var.c +++ b/lib/libvcl/vcc_var.c @@ -121,29 +121,3 @@ vcc_FindVar(struct vcc *tl, const struct token *t, int wr_access, vcc_ErrWhere(tl, t); return (NULL); } - -/*--------------------------------------------------------------------*/ - -void -vcc_VarVal(struct vcc *tl, const struct var *vp, const struct token *vt) -{ - double d; - - if (vp->fmt == TIME) { - vcc_TimeVal(tl, &d); - ERRCHK(tl); - Fb(tl, 0, "%g", d); - } else if (vp->fmt == DURATION) { - vcc_RTimeVal(tl, &d); - ERRCHK(tl); - Fb(tl, 0, "%g", d); - } else if (vp->fmt == INT) { - Fb(tl, 0, "%u", vcc_UintVal(tl)); - } else { - AN(vt); - VSB_printf(tl->sb, - "Variable has incompatible type.\n"); - vcc_ErrWhere(tl, vt); - return; - } -} From geoff at varnish-cache.org Fri Jul 8 09:47:51 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:51 +0200 Subject: [experimental-ims] 01d9c22 Fix a compiler fault if two IP comparisons were on the same line of source code. Message-ID: commit 01d9c22319c04940aff6743a9ca9e9a474cd194c Author: Poul-Henning Kamp Date: Thu Jun 30 08:30:40 2011 +0000 Fix a compiler fault if two IP comparisons were on the same line of source code. This is substantially DocWilcos fix, but instead of adding yet another unique numbering variable, I have collapsed the once we have into a single one. Fixes #948 diff --git a/bin/varnishtest/tests/r00948.vtc b/bin/varnishtest/tests/r00948.vtc new file mode 100644 index 0000000..559cbbc --- /dev/null +++ b/bin/varnishtest/tests/r00948.vtc @@ -0,0 +1,30 @@ +varnishtest "anon acl numbering" + + +server s1 { + rxreq + expect req.http.foo1 == "Match" + expect req.http.foo2 == "Match" + txresp -bodylen 40 +} -start + +varnish v1 -vcl+backend { + +sub vcl_recv { + if (client.ip == "${s1_addr}" || client.ip == "${bad_ip}") { + set req.http.foo1 = "Match"; + } + if (client.ip == "${bad_ip}" || client.ip == "${s1_addr}") { + set req.http.foo2 = "Match"; + } +} + +} -start + +client c1 { + txreq + rxresp + expect resp.bodylen == 40 +} -run + + diff --git a/lib/libvcl/vcc_acl.c b/lib/libvcl/vcc_acl.c index c506c78..30c9eea 100644 --- a/lib/libvcl/vcc_acl.c +++ b/lib/libvcl/vcc_acl.c @@ -454,7 +454,7 @@ vcc_Acl_Hack(struct vcc *tl, char *b) VTAILQ_INIT(&tl->acl); tcond = tl->t->tok; vcc_NextToken(tl); - bprintf(acln, "%u", tl->cnt); + bprintf(acln, "%u", tl->unique++); vcc_acl_entry(tl); vcc_acl_emit(tl, acln, 1); sprintf(b, "%smatch_acl_anon_%s(sp, \v1)", diff --git a/lib/libvcl/vcc_backend.c b/lib/libvcl/vcc_backend.c index f90c1b1..babfe01 100644 --- a/lib/libvcl/vcc_backend.c +++ b/lib/libvcl/vcc_backend.c @@ -83,7 +83,7 @@ emit_sockaddr(struct vcc *tl, void *sa, unsigned sal) AN(sal); assert(sal < 256); Fh(tl, 0, "\nstatic const unsigned char sockaddr%u[%d] = {\n", - tl->nsockaddr, sal + 1); + tl->unique, sal + 1); Fh(tl, 0, " %3u, /* Length */\n", sal); u = sa; for (len = 0; len nsockaddr++); + return (tl->unique++); } /*-------------------------------------------------------------------- diff --git a/lib/libvcl/vcc_compile.h b/lib/libvcl/vcc_compile.h index b8c8454..ec7caed 100644 --- a/lib/libvcl/vcc_compile.h +++ b/lib/libvcl/vcc_compile.h @@ -162,8 +162,7 @@ struct vcc { struct token *t_dir; struct token *t_policy; - unsigned recnt; - unsigned nsockaddr; + unsigned unique; unsigned nvmodpriv; unsigned err_unref; diff --git a/lib/libvcl/vcc_string.c b/lib/libvcl/vcc_string.c index 06e7277..ed91c35 100644 --- a/lib/libvcl/vcc_string.c +++ b/lib/libvcl/vcc_string.c @@ -63,7 +63,7 @@ vcc_regexp(struct vcc *tl) return (NULL); } VRE_free(&t); - sprintf(buf, "VGC_re_%u", tl->recnt++); + sprintf(buf, "VGC_re_%u", tl->unique++); p = TlAlloc(tl, strlen(buf) + 1); strcpy(p, buf); From geoff at varnish-cache.org Fri Jul 8 09:47:51 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:51 +0200 Subject: [experimental-ims] 41aa97b Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache Message-ID: commit 41aa97bf87080af20b3976a6e2718c1307f18e62 Merge: e1f1d8f 91023bb Author: Per Buer Date: Thu Jun 30 10:23:30 2011 +0200 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache From geoff at varnish-cache.org Fri Jul 8 09:47:51 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:51 +0200 Subject: [experimental-ims] b998711 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache Message-ID: commit b998711ca9b2565dc959d4652993951e3a7145b6 Merge: 01d9c22 41aa97b Author: Poul-Henning Kamp Date: Thu Jun 30 08:32:15 2011 +0000 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache From geoff at varnish-cache.org Fri Jul 8 09:47:51 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:51 +0200 Subject: [experimental-ims] 90b7074 Reintroduce TTL VCL logging that was lost in commit a21746d23d4047ce209a0c283e12ff684f478b72. Message-ID: commit 90b7074b4cad090743f5a9797007ab448fa95a39 Author: Martin Blix Grydeland Date: Tue Jun 28 15:47:26 2011 +0200 Reintroduce TTL VCL logging that was lost in commit a21746d23d4047ce209a0c283e12ff684f478b72. Fixes: #941 diff --git a/bin/varnishd/cache_vrt_var.c b/bin/varnishd/cache_vrt_var.c index 5f3ecb5..297151c 100644 --- a/bin/varnishd/cache_vrt_var.c +++ b/bin/varnishd/cache_vrt_var.c @@ -385,10 +385,13 @@ VRT_DO_EXP(req, sp->exp, ttl, ) VRT_DO_EXP(req, sp->exp, grace, ) VRT_DO_EXP(req, sp->exp, keep, ) VRT_DO_EXP(obj, sp->obj->exp, grace, EXP_Rearm(sp->obj)) -VRT_DO_EXP(obj, sp->obj->exp, ttl, EXP_Rearm(sp->obj)) +VRT_DO_EXP(obj, sp->obj->exp, ttl, + EXP_Rearm(sp->obj); + WSP(sp, SLT_TTL, "%u VCL %.0f %.0f", sp->obj->xid, a, sp->t_req)) VRT_DO_EXP(obj, sp->obj->exp, keep, EXP_Rearm(sp->obj)) VRT_DO_EXP(beresp, sp->wrk->exp, grace, ) -VRT_DO_EXP(beresp, sp->wrk->exp, ttl, ) +VRT_DO_EXP(beresp, sp->wrk->exp, ttl, + WSP(sp, SLT_TTL, "%u VCL %.0f %.0f", sp->xid, a, sp->t_req)) VRT_DO_EXP(beresp, sp->wrk->exp, keep, ) /*-------------------------------------------------------------------- diff --git a/bin/varnishtest/tests/r00941.vtc b/bin/varnishtest/tests/r00941.vtc new file mode 100644 index 0000000..1028e2d --- /dev/null +++ b/bin/varnishtest/tests/r00941.vtc @@ -0,0 +1,24 @@ +varnishtest "beresp.ttl set in vcl takes effect" + +server s1 { + rxreq + txresp -hdr "Cache-control: max-age=1" -body "FOO" + rxreq + txresp -body "FOOBAR" +} -start + +varnish v1 -vcl+backend { + sub vcl_fetch { + set beresp.ttl = 1000s; + } +} -start + +client c1 { + txreq + rxresp + expect resp.bodylen == 3 + delay 2 + txreq + rxresp + expect resp.bodylen == 3 +} -run From geoff at varnish-cache.org Fri Jul 8 09:47:52 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:52 +0200 Subject: [experimental-ims] 7209a66 Split registration and selection of backend poll functions into two different functions. Message-ID: commit 7209a66e764e7afd9d8ca179494b1656f0ec0c9b Author: Poul-Henning Kamp Date: Thu Jun 30 11:06:51 2011 +0000 Split registration and selection of backend poll functions into two different functions. I have not managed to write a vtc case for this one, but I am pretty sure this: Fixes: #945 diff --git a/bin/varnishd/cache_backend.c b/bin/varnishd/cache_backend.c index 8c13112..3d6a405 100644 --- a/bin/varnishd/cache_backend.c +++ b/bin/varnishd/cache_backend.c @@ -430,7 +430,7 @@ VBE_UseHealth(const struct director *vdi) CAST_OBJ_NOTNULL(vs, vdi->priv, VDI_SIMPLE_MAGIC); if (vs->vrt->probe == NULL) return; - VBP_Start(vs->backend, vs->vrt->probe, vs->vrt->hosthdr); + VBP_Use(vs->backend, vs->vrt->probe); } /*-------------------------------------------------------------------- @@ -475,7 +475,8 @@ vdi_simple_fini(const struct director *d) CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); CAST_OBJ_NOTNULL(vs, d->priv, VDI_SIMPLE_MAGIC); - VBP_Stop(vs->backend, vs->vrt->probe); + if (vs->vrt->probe != NULL) + VBP_Remove(vs->backend, vs->vrt->probe); VBE_DropRefVcl(vs->backend); free(vs->dir.vcl_name); vs->dir.magic = 0; @@ -506,8 +507,8 @@ VRT_init_dir_simple(struct cli *cli, struct director **bp, int idx, vs->vrt = t; vs->backend = VBE_AddBackend(cli, t); - if (vs->backend->probe == NULL) - VBP_Start(vs->backend, vs->vrt->probe, vs->vrt->hosthdr); + if (vs->vrt->probe != NULL) + VBP_Insert(vs->backend, vs->vrt->probe, vs->vrt->hosthdr); bp[idx] = &vs->dir; } diff --git a/bin/varnishd/cache_backend.h b/bin/varnishd/cache_backend.h index cb707ba..c065218 100644 --- a/bin/varnishd/cache_backend.h +++ b/bin/varnishd/cache_backend.h @@ -145,8 +145,9 @@ void VBE_DropRefVcl(struct backend *); void VBE_DropRefLocked(struct backend *b); /* cache_backend_poll.c */ -void VBP_Start(struct backend *b, struct vrt_backend_probe const *p, const char *hosthdr); -void VBP_Stop(struct backend *b, struct vrt_backend_probe const *p); +void VBP_Insert(struct backend *b, struct vrt_backend_probe const *p, const char *hosthdr); +void VBP_Remove(struct backend *b, struct vrt_backend_probe const *p); +void VBP_Use(struct backend *b, const struct vrt_backend_probe const *p); /* Init functions for directors */ typedef void dir_init_f(struct cli *, struct director **, int , const void*); diff --git a/bin/varnishd/cache_backend_poll.c b/bin/varnishd/cache_backend_poll.c index d1acf2a..d7b5268 100644 --- a/bin/varnishd/cache_backend_poll.c +++ b/bin/varnishd/cache_backend_poll.c @@ -463,11 +463,11 @@ vbp_new_vcl(const struct vrt_backend_probe *p, const char *hosthdr) } /*-------------------------------------------------------------------- - * Start/Stop called from cache_backend.c + * Insert/Remove/Use called from cache_backend.c */ void -VBP_Start(struct backend *b, const struct vrt_backend_probe *p, const char *hosthdr) +VBP_Insert(struct backend *b, const struct vrt_backend_probe *p, const char *hosthdr) { struct vbp_target *vt; struct vbp_vcl *vcl; @@ -475,9 +475,7 @@ VBP_Start(struct backend *b, const struct vrt_backend_probe *p, const char *host unsigned u; ASSERT_CLI(); - - if (p == NULL) - return; + AN(p); if (b->probe == NULL) { ALLOC_OBJ(vt, VBP_TARGET_MAGIC); @@ -493,21 +491,12 @@ VBP_Start(struct backend *b, const struct vrt_backend_probe *p, const char *host vt = b->probe; } - VTAILQ_FOREACH(vcl, &vt->vcls, list) { - if (vcl->probep != p) - continue; - - AZ(startthread); - Lck_Lock(&vbp_mtx); - VTAILQ_REMOVE(&vt->vcls, vcl, list); - VTAILQ_INSERT_HEAD(&vt->vcls, vcl, list); - Lck_Unlock(&vbp_mtx); - return; - } + VTAILQ_FOREACH(vcl, &vt->vcls, list) + assert (vcl->probep != p); vcl = vbp_new_vcl(p, hosthdr); Lck_Lock(&vbp_mtx); - VTAILQ_INSERT_HEAD(&vt->vcls, vcl, list); + VTAILQ_INSERT_TAIL(&vt->vcls, vcl, list); Lck_Unlock(&vbp_mtx); if (startthread) { @@ -521,21 +510,42 @@ VBP_Start(struct backend *b, const struct vrt_backend_probe *p, const char *host } void -VBP_Stop(struct backend *b, struct vrt_backend_probe const *p) +VBP_Use(struct backend *b, const struct vrt_backend_probe *p) { struct vbp_target *vt; struct vbp_vcl *vcl; - void *ret; ASSERT_CLI(); + AN(p); + CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC); + AN(b->probe); + vt = b->probe; - if (p == NULL) + VTAILQ_FOREACH(vcl, &vt->vcls, list) { + if (vcl->probep != p) + continue; + + Lck_Lock(&vbp_mtx); + VTAILQ_REMOVE(&vt->vcls, vcl, list); + VTAILQ_INSERT_HEAD(&vt->vcls, vcl, list); + Lck_Unlock(&vbp_mtx); return; + } +} - CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC); +void +VBP_Remove(struct backend *b, struct vrt_backend_probe const *p) +{ + struct vbp_target *vt; + struct vbp_vcl *vcl; + void *ret; + ASSERT_CLI(); + AN(p); + CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC); AN(b->probe); vt = b->probe; + VTAILQ_FOREACH(vcl, &vt->vcls, list) if (vcl->probep == p) break; From geoff at varnish-cache.org Fri Jul 8 09:47:53 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:53 +0200 Subject: [experimental-ims] 321be3e Merged conditional backend request feature Message-ID: commit 321be3ed610227bcb8dd88a6bb29e2227c1fa6c6 Author: Geoff Simmons Date: Thu Jun 2 21:42:28 2011 +0200 Merged conditional backend request feature diff --git a/bin/varnishtest/tests/i00000.vtc b/bin/varnishtest/tests/i00000.vtc new file mode 100644 index 0000000..773e1e5 --- /dev/null +++ b/bin/varnishtest/tests/i00000.vtc @@ -0,0 +1,498 @@ +# $Id$ + +test "VCL compiler coverage test: conditional refresh extension" + +## stale_obj is r/o in miss, fetch and error, illegal everywhere else + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { if (stale_obj) { return(pass); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { set stale_obj = true; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { if (stale_obj.proto ~ "foo") { return(pass); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { set stale_obj.proto = "foo"; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { if (stale_obj.status == 200) { return(pass); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { set stale_obj.status = 200; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { if (stale_obj.response ~ "foo") { return(pass); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { set stale_obj.response = "foo"; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { if (stale_obj.hits > 100) { return(pass); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { set stale_obj.hits = 100; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { if (stale_obj.http.Foo ~ "foo") { return(pass); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { set stale_obj.http.Foo = "foo"; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { if (stale_obj.ttl > 1m) { return(pass); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { set stale_obj.ttl = 1m; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { if (stale_obj.grace > 1m) { return(pass); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { set stale_obj.grace = 1m; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { if (stale_obj.lastuse > 1m) { return(pass); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { set stale_obj.lastuse = 1m; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { if (stale_obj.keep > 1m) { return(pass); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { set stale_obj.keep = 1m; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { if (stale_obj) { return(deliver); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { set stale_obj = true; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { if (stale_obj.proto ~ "foo") { return(deliver); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { set stale_obj.proto = "foo"; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { if (stale_obj.status == 200) { return(deliver); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { set stale_obj.status = 200; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { if (stale_obj.response ~ "foo") { return(deliver); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { set stale_obj.response = "foo"; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { if (stale_obj.hits > 100) { return(deliver); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { set stale_obj.hits = 100; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { if (stale_obj.http.Foo ~ "foo") { return(deliver); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { set stale_obj.http.Foo = "foo"; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { if (stale_obj.ttl > 1m) { return(deliver); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { set stale_obj.ttl = 1m; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { if (stale_obj.grace > 1m) { return(deliver); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { set stale_obj.grace = 1m; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { if (stale_obj.lastuse > 1m) { return(deliver); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { set stale_obj.lastuse = 1m; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { if (stale_obj.keep > 1m) { return(deliver); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { set stale_obj.keep = 1m; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { if (stale_obj) { return(deliver); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { set stale_obj = true; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { if (stale_obj.proto ~ "foo") { return(deliver); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { set stale_obj.proto = "foo"; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { if (stale_obj.status == 200) { return(deliver); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { set stale_obj.status = 200; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { if (stale_obj.response ~ "foo") { return(deliver); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { set stale_obj.response = "foo"; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { if (stale_obj.hits > 100) { return(deliver); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { set stale_obj.hits = 100; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { if (stale_obj.http.Foo ~ "foo") { return(deliver); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { set stale_obj.http.Foo = "foo"; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { if (stale_obj.ttl > 1m) { return(deliver); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { set stale_obj.ttl = 1m; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { if (stale_obj.grace > 1m) { return(deliver); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { set stale_obj.grace = 1m; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { if (stale_obj.lastuse > 1m) { return(deliver); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { set stale_obj.lastuse = 1m; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { if (stale_obj.keep > 1m) { return(deliver); } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { set stale_obj.keep = 1m; } +} + +## keep is r/w for req everywhere +## r/w for beresp in fetch +## r/w for obj in hit and error (like ttl and grace) +## r/o for stale_obj in fetch, miss and error (already tested) + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_recv { set req.keep = 1s; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_recv { if (req.keep > 1s) { set req.keep = 1s; } } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_pipe { set req.keep = 1s; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_pipe { if (req.keep > 1s) { set req.keep = 1s; } } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_pass { set req.keep = 1s; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_pass { if (req.keep > 1s) { set req.keep = 1s; } } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_hash { set req.keep = 1s; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_hash { if (req.keep > 1s) { set req.keep = 1s; } } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { set req.keep = 1s; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { if (req.keep > 1s) { set req.keep = 1s; } } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_hit { set req.keep = 1s; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_hit { if (req.keep > 1s) { set req.keep = 1s; } } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { set req.keep = 1s; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { if (req.keep > 1s) { set req.keep = 1s; } } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_deliver { set req.keep = 1s; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_deliver { if (req.keep > 1s) { set req.keep = 1s; } } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { set req.keep = 1s; } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { if (req.keep > 1s) { set req.keep = 1s; } } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { if (beresp.keep > 1s) { set req.keep = 1s; } } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { set beresp.keep = 1s; } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { if (obj.keep > 1s) { set req.keep = 1s; } } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_hit { set obj.keep = 1s; } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { if (obj.keep > 1s) { set req.keep = 1s; } } +} + +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + sub vcl_error { if (obj.keep > 1s) { set req.keep = 1s; } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_miss { set obj.keep = 1s; } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_fetch { set obj.keep = 1s; } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_recv { if (obj.keep > 1s) { set req.keep = 1s; } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_recv { set obj.keep = 1s; } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_pipe { if (obj.keep > 1s) { set req.keep = 1s; } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_pipe { set obj.keep = 1s; } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_pass { if (obj.keep > 1s) { set req.keep = 1s; } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_pass { set obj.keep = 1s; } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_hash { if (obj.keep > 1s) { set req.keep = 1s; } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_hash { set obj.keep = 1s; } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_deliver { if (obj.keep > 1s) { set req.keep = 1s; } } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_deliver { set obj.keep = 1s; } +} + +varnish v1 -cliok "param.show default_keep" + +varnish v1 -cliok "param.set default_keep 30s" + +## XXX: This is not caught as an error +#varnish v1 -clierr 106 "param.set default_keep foo" + diff --git a/bin/varnishtest/tests/i00001.vtc b/bin/varnishtest/tests/i00001.vtc new file mode 100644 index 0000000..488305f --- /dev/null +++ b/bin/varnishtest/tests/i00001.vtc @@ -0,0 +1,271 @@ +# $Id$ + +test "Test basic conditional requests to backends" + +## By default (default_keep = default_grace), cond. requests happen during grace + +server s1 { + rxreq + expect req.url == "/foo" + txresp -status 200 \ + -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \ + -hdr "ETag: foo" \ + -body "123456" + + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT" + expect req.http.If-None-Match == "foo" + txresp -status 304 +} -start + +varnish v1 -vcl+backend { + sub vcl_fetch { + set beresp.ttl = 0.5s; + } +} -start + +client c1 { + txreq -url "/foo" + rxresp + expect resp.status == 200 + expect resp.http.content-length == 6 + expect resp.bodylen == 6 + expect resp.http.Age == 0 +} -run + +delay 0.6 + +client c1 -run + +varnish v1 -expect fetch_304 == 1 +varnish v1 -expect cond_not_validated == 0 + +server s1 -wait +varnish v1 -stop + +## With keep > 0, using both If-Modified-Since and If-None-Match + +server s1 { + rxreq + expect req.url == "/foo" + txresp -status 200 \ + -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \ + -hdr "ETag: foo" \ + -body "123456" + + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT" + expect req.http.If-None-Match == "foo" + txresp -status 304 + + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT" + expect req.http.If-None-Match == "foo" + txresp -status 200 \ + -hdr "Last-Modified: Wed, 27 Jun 2008 12:00:01 GMT" \ + -hdr "ETag: foo" \ + -body "ABCDEF" + + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since == "Wed, 27 Jun 2008 12:00:01 GMT" + expect req.http.If-None-Match == "foo" + txresp -status 304 + +} -start + +varnish v1 -vcl { + backend s1 { + .host = "${s1_addr}"; .port = "${s1_port}"; + } + + sub vcl_fetch { + set beresp.http.X-Original-Keep = beresp.keep; + set beresp.grace = 0s; + set beresp.ttl = 1s; + set beresp.keep = 1m; + } +} -start + +client c1 { + txreq -url "/foo" + rxresp + expect resp.status == 200 + expect resp.http.ETag == "foo" + expect resp.http.content-length == 6 + expect resp.bodylen == 6 + expect resp.http.Age == 0 + expect resp.http.X-Original-Keep == 10.000 +} + +client c1 -run + +delay 1.1 + +client c1 -run + +delay 1.1 + +client c1 -run + +delay 1.1 + +client c1 -run + +varnish v1 -expect fetch_304 == 2 +varnish v1 -expect cond_not_validated == 1 + +server s1 -wait +varnish v1 -stop + +## Just If-Modified-Since + +server s1 { + rxreq + expect req.url == "/foo" + txresp -status 200 \ + -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \ + -body "123456" + + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT" + txresp -status 304 + + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT" + txresp -status 200 \ + -hdr "Last-Modified: Wed, 27 Jun 2008 12:00:01 GMT" \ + -body "ABCDEF" + + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since == "Wed, 27 Jun 2008 12:00:01 GMT" + txresp -status 304 + +} -start + +varnish v1 -vcl { + backend s1 { + .host = "${s1_addr}"; .port = "${s1_port}"; + } + sub vcl_fetch { + set beresp.http.X-Original-Keep = beresp.keep; + set beresp.grace = 0s; + set beresp.ttl = 1s; + set beresp.keep = 1m; + } +} -start + +client c1 { + txreq -url "/foo" + rxresp + expect resp.status == 200 + expect resp.http.content-length == 6 + expect resp.bodylen == 6 + expect resp.http.Age == 0 + expect resp.http.X-Original-Keep == 10.000 +} + +client c1 -run + +delay 1.1 + +client c1 -run + +delay 1.1 + +client c1 -run + +delay 1.1 + +client c1 -run + +varnish v1 -expect fetch_304 == 2 +varnish v1 -expect cond_not_validated == 1 + +server s1 -wait +varnish v1 -stop + +## Just If-None-Match + +server s1 { + rxreq + expect req.url == "/foo" + txresp -status 200 \ + -hdr "ETag: foo" \ + -body "123456" + + rxreq + expect req.url == "/foo" + expect req.http.If-None-Match == "foo" + txresp -status 304 + + rxreq + expect req.url == "/foo" + expect req.http.If-None-Match == "foo" + txresp -status 200 \ + -hdr "ETag: bar" \ + -body "ABCDEF" + + rxreq + expect req.url == "/foo" + expect req.http.If-None-Match == "bar" + txresp -status 304 + +} -start + +varnish v1 -vcl { + backend s1 { + .host = "${s1_addr}"; .port = "${s1_port}"; + } + sub vcl_fetch { + set beresp.http.X-Original-Keep = beresp.keep; + set beresp.grace = 0s; + set beresp.ttl = 1s; + set beresp.keep = 1m; + } +} -start + +client c1 { + txreq -url "/foo" + rxresp + expect resp.status == 200 + expect resp.http.ETag == "foo" + expect resp.http.content-length == 6 + expect resp.bodylen == 6 + expect resp.http.Age == 0 + expect resp.http.X-Original-Keep == 10.000 +} + +client c2 { + txreq -url "/foo" + rxresp + expect resp.status == 200 + expect resp.http.ETag == "bar" + expect resp.http.content-length == 6 + expect resp.bodylen == 6 + expect resp.http.Age == 0 + expect resp.http.X-Original-Keep == 10.000 +} + +client c1 -run + +delay 1.1 + +client c1 -run + +delay 1.1 + +client c2 -run + +delay 1.1 + +client c2 -run + +varnish v1 -expect fetch_304 == 2 +varnish v1 -expect cond_not_validated == 1 diff --git a/bin/varnishtest/tests/i00002.vtc b/bin/varnishtest/tests/i00002.vtc new file mode 100644 index 0000000..3725532 --- /dev/null +++ b/bin/varnishtest/tests/i00002.vtc @@ -0,0 +1,108 @@ +# $Id$ + +test "handling stale_obj in vcl_miss() and vcl_fetch()" + +server s1 { + rxreq + expect req.url == "/foo" + expect req.http.X-VT-Stale == "false" + expect req.http.X-VT-Stale-Status == 503 + expect req.http.X-VT-Stale-Hits == 0 + expect req.http.X-VT-Stale-TTL == -1.000 + expect req.http.X-VT-Stale-Grace == -1.000 + expect req.http.X-VT-Stale-Last-Use == 0.000 + expect req.http.X-VT-Stale-Keep == -1.000 + txresp -status 200 \ + -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \ + -body "1234567890" + + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT" + expect req.http.X-VT-Stale == "true" + expect req.http.X-VT-Stale-Proto == "HTTP/1.1" + expect req.http.X-VT-Stale-Status == 200 + expect req.http.X-VT-Stale-Response == "Ok" + expect req.http.X-VT-Stale-Last-Modified == "Thu, 26 Jun 2008 12:00:01 GMT" + expect req.http.X-VT-Stale-TTL == 0.500 + expect req.http.X-VT-Stale-Grace == 0.500 + expect req.http.X-VT-Stale-Last-Use != 0.000 + expect req.http.X-VT-Stale-Keep == 1.000 + txresp -status 304 +} -start + +varnish v1 -vcl+backend { + sub vcl_fetch { + set beresp.grace = 0.5s; + set beresp.ttl = 0.5s; + set beresp.keep = 1s; + + if (stale_obj) { + set beresp.http.X-VT-Stale = "true"; + } + else { + set beresp.http.X-VT-Stale = "false"; + } + set beresp.http.X-VT-Stale-Proto = stale_obj.proto; + set beresp.http.X-VT-Stale-Status = stale_obj.status; + set beresp.http.X-VT-Stale-Response = stale_obj.response; + set beresp.http.X-VT-Stale-Hits = stale_obj.hits; + set beresp.http.X-VT-Stale-Last-Modified = stale_obj.http.Last-Modified; + set beresp.http.X-VT-Stale-TTL = stale_obj.ttl; + set beresp.http.X-VT-Stale-Grace = stale_obj.grace; + set beresp.http.X-VT-Stale-Last-Use = stale_obj.lastuse; + set beresp.http.X-VT-Stale-Keep = stale_obj.keep; + } + + sub vcl_miss { + if (stale_obj) { + set bereq.http.X-VT-Stale = "true"; + } + else { + set bereq.http.X-VT-Stale = "false"; + } + set bereq.http.X-VT-Stale-Proto = stale_obj.proto; + set bereq.http.X-VT-Stale-Status = stale_obj.status; + set bereq.http.X-VT-Stale-Response = stale_obj.response; + set bereq.http.X-VT-Stale-Hits = stale_obj.hits; + set bereq.http.X-VT-Stale-Last-Modified = stale_obj.http.Last-Modified; + set bereq.http.X-VT-Stale-TTL = stale_obj.ttl; + set bereq.http.X-VT-Stale-Grace = stale_obj.grace; + set bereq.http.X-VT-Stale-Last-Use = stale_obj.lastuse; + set bereq.http.X-VT-Stale-Keep = stale_obj.keep; + } +} -start + +client c1 { + txreq -url "/foo" + rxresp + expect resp.status == 200 + expect resp.http.content-length == 10 + expect resp.http.X-VT-Stale == "false" + expect resp.http.X-VT-Stale-Status == 503 + expect resp.http.X-VT-Stale-Hits == 0 + expect resp.http.X-VT-Stale-TTL == -1.000 + expect resp.http.X-VT-Stale-Grace == -1.000 + expect resp.http.X-VT-Stale-Last-Use == 0.000 + expect resp.http.X-VT-Stale-Keep == -1.000 +} -run + +delay 1.1 + +client c1 { + txreq -url "/foo" + rxresp + expect resp.status == 200 + expect resp.bodylen == 10 + expect resp.http.Content-Length == 10 + expect resp.http.X-VT-Stale == "true" + expect resp.http.X-VT-Stale-Proto == "HTTP/1.1" + expect resp.http.X-VT-Stale-Status == 200 + expect resp.http.X-VT-Stale-Response == "Ok" + expect resp.http.X-VT-Stale-Hits == 0 + expect resp.http.X-VT-Stale-Last-Modified == "Thu, 26 Jun 2008 12:00:01 GMT" + expect resp.http.X-VT-Stale-TTL == 0.500 + expect resp.http.X-VT-Stale-Grace == 0.500 + expect resp.http.X-VT-Stale-Last-Use != 0.000 + expect resp.http.X-VT-Stale-Keep == 1.000 +} -run diff --git a/bin/varnishtest/tests/i00003.vtc b/bin/varnishtest/tests/i00003.vtc new file mode 100644 index 0000000..809b317 --- /dev/null +++ b/bin/varnishtest/tests/i00003.vtc @@ -0,0 +1,146 @@ +# $Id$ + +test "Test some anticipated use cases for conditional backend requests" + +## In vcl_miss(), it is possible to veto a conditional request by removing any +## If-Modified-Since or If-None-Match header. + +server s1 { + rxreq + expect req.url == "/foo" + txresp -status 200 \ + -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \ + -hdr "ETag: foo" \ + -body "abcdefghijklmonpqrstuvwxyz" + + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since != "Thu, 26 Jun 2008 12:00:01 GMT" + expect req.http.If-None-Match != "foo" + txresp -status 200 -body "abcdefghijklmonpqrstuvwxyz" +} -start + +varnish v1 -vcl+backend { + sub vcl_fetch { + set beresp.grace = 0s; + set beresp.ttl = 1s; + set beresp.keep = 1m; + } + + sub vcl_miss { + unset bereq.http.If-Modified-Since; + unset bereq.http.If-None-Match; + } +} -start + +client c1 { + txreq -url "/foo" + rxresp + expect resp.status == 200 + expect resp.http.content-length == 26 +} + +client c1 -run + +delay 1.1 + +client c1 -run + +varnish v1 -expect fetch_304 == 0 +varnish v1 -expect cond_not_validated == 0 + +server s1 -wait +varnish v1 -stop + +## Verify that if a client sends a conditional request to Varnish, then Varnish +## can return a 304 response to the client after it got 304 from the backend + +server s2 { + rxreq + expect req.url == "/foo" + txresp -status 200 \ + -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \ + -body "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT" + txresp -status 304 +} -start + +varnish v1 -vcl { + backend s2 { + .host = "${s2_addr}"; .port = "${s2_port}"; + } + + sub vcl_fetch { + set beresp.grace = 0s; + set beresp.ttl = 1s; + set beresp.keep = 1m; + } +} -start + +client c2 { + txreq -url "/foo" \ + -hdr "If-Modified-Since: Thu, 26 Jun 2008 12:00:01 GMT" + rxresp + expect resp.status == 304 +} + +client c1 -run + +delay 1.1 + +client c2 -run + +varnish v1 -expect fetch_304 == 1 +varnish v1 -expect cond_not_validated == 0 + +server s2 -wait +varnish v1 -stop + +## +## If stale_obj has a gzipped body, make sure it interacts correctly with clients +## + +server s2 { + rxreq + expect req.http.accept-encoding == "gzip" + txresp -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" -gzipbody FOO + + rxreq + expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT" + txresp -status 304 +} -start + +varnish v1 -cliok "param.set http_gzip_support true" -vcl { + backend s2 { + .host = "${s2_addr}"; .port = "${s2_port}"; + } + + sub vcl_fetch { + set beresp.grace = 0s; + set beresp.ttl = 1s; + set beresp.keep = 1m; + } +} -start + +client c1 { + txreq -hdr "Accept-encoding: gzip;q=0.1" + rxresp + expect resp.http.content-encoding == "gzip" + gunzip + expect resp.bodylen == "3" +} -run + +delay 1.1 + +client c2 { + txreq + rxresp + expect resp.bodylen == "3" + expect resp.http.content-encoding != "gzip" +} -run + +varnish v1 -expect fetch_304 == 1 +varnish v1 -expect cond_not_validated == 0 diff --git a/bin/varnishtest/tests/i00004.vtc b/bin/varnishtest/tests/i00004.vtc new file mode 100644 index 0000000..0943f98 --- /dev/null +++ b/bin/varnishtest/tests/i00004.vtc @@ -0,0 +1,201 @@ +# $Id$ + +test "Verify the semantics of keep (timeout for conditional requests)" + +server s1 { + rxreq + expect req.url == "/foo" + txresp -status 200 \ + -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \ + -body "foo bar baz quux" + + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT" + txresp -status 304 + + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since != "Thu, 26 Jun 2008 12:00:01 GMT" + txresp -status 200 -body "foo bar baz quux" +} -start + +varnish v1 -vcl+backend { + sub vcl_fetch { + set beresp.grace = 0s; + set beresp.ttl = 1s; + } +} -start + +client c1 { + txreq -url "/foo" + rxresp + expect resp.status == 200 + expect resp.http.content-length == 16 + expect resp.http.Age == 0 +} + +varnish v1 -cli "param.set default_keep 1" + +client c1 -run + +delay 1.1 + +client c1 -run + +delay 2.1 + +client c1 -run + +varnish v1 -expect fetch_304 == 1 +varnish v1 -expect cond_not_validated == 0 + +server s1 -wait +varnish v1 -stop + +## Start a new varnish (now using the default default_keep), +## and manipulate beresp.keep in VCL + +server s1 -start + +varnish v1 -vcl { + backend s1 { + .host = "${s1_addr}"; .port = "${s1_port}"; + } + + sub vcl_fetch { + set beresp.grace = 0s; + set beresp.ttl = 1s; + set beresp.keep = 1s; + } +} -start + +client c1 -run + +delay 1.1 + +client c1 -run + +delay 2.1 + +client c1 -run + +varnish v1 -expect fetch_304 == 1 +varnish v1 -expect cond_not_validated == 0 + +server s1 -wait +varnish v1 -stop + +## Manipulate obj.keep in vcl_hit() + +server s1 -start + +varnish v1 -vcl { + backend s1 { + .host = "${s1_addr}"; .port = "${s1_port}"; + } + + sub vcl_fetch { + set beresp.grace = 0s; + set beresp.ttl = 1s; + } + + sub vcl_hit { + set obj.keep = 1s; + } +} -start + +client c1 -run + +delay 1.1 + +client c1 -run + +delay 2.1 + +client c1 -run + +varnish v1 -expect fetch_304 == 1 +varnish v1 -expect cond_not_validated == 0 + +server s1 -wait +varnish v1 -stop + +## Manipulate obj.keep in vcl_error() + +server s1 -start + +varnish v1 -vcl { + backend s1 { + .host = "${s1_addr}"; .port = "${s1_port}"; + } + + sub vcl_fetch { + set beresp.grace = 0s; + set beresp.ttl = 1s; + } + + sub vcl_hit { + error 200 "Ok"; + } + + sub vcl_error { + set obj.keep = 1s; + return(deliver); + } +} -start + +client c1 { + txreq -url "/foo" + rxresp + expect resp.status == 200 +} + +client c1 -run + +delay 1.1 + +client c1 -run + +delay 2.1 + +client c1 -run + +varnish v1 -expect fetch_304 == 1 +varnish v1 -expect cond_not_validated == 0 + +server s1 -wait +varnish v1 -stop + +## req.keep sets an upper bound for all *.keeps in a session + +server s1 -start + +varnish v1 -vcl { + backend s1 { + .host = "${s1_addr}"; .port = "${s1_port}"; + } + + sub vcl_recv { + set req.keep = 0.5s; + } + + sub vcl_fetch { + set beresp.grace = 0s; + set beresp.ttl = 1s; + set beresp.keep = 1s; + } +} -start + +client c1 -run + +delay 1.1 + +client c1 -run + +delay 1.6 + +client c1 -run + +varnish v1 -expect fetch_304 == 1 +varnish v1 -expect cond_not_validated == 0 diff --git a/bin/varnishtest/tests/i00005.vtc b/bin/varnishtest/tests/i00005.vtc new file mode 100644 index 0000000..0bcac4f --- /dev/null +++ b/bin/varnishtest/tests/i00005.vtc @@ -0,0 +1,147 @@ +# $Id$ + +test "Verify interactions of ttl, keep, grace and bans" + +## Banned objects are not used for conditional requests + +server s1 { + rxreq + expect req.url == "/foo" + txresp -status 200 \ + -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \ + -body "The quick brown fox jumps over the lazy dog." + + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since != "Thu, 26 Jun 2008 12:00:01 GMT" + txresp -status 200 -body "The quick brown fox jumps over the lazy dog." +} -start + +varnish v1 -vcl+backend { + sub vcl_fetch { + set beresp.grace = 0s; + set beresp.ttl = 1s; + set beresp.keep = 1m; + } +} -start + +client c1 { + txreq -url "/foo" + rxresp + expect resp.status == 200 + expect resp.bodylen == 44 +} + +client c1 -run + +delay 1.1 + +varnish v1 -cli "ban.url \"/foo\"" + +client c1 -run + +varnish v1 -expect fetch_304 == 0 +varnish v1 -expect cond_not_validated == 0 + +server s1 -wait +varnish v1 -stop + +## If keep is set to non-zero, but then ttl is set to 0, +## then the object is not used for conditional requests + +server s1 -start + +varnish v1 -vcl { + backend s2 { + .host = "${s1_addr}"; .port = "${s1_port}"; + } + + sub vcl_fetch { + set beresp.keep = 1m; + set beresp.ttl = 0s; + } +} -start + +client c1 -run + +client c1 -run + +varnish v1 -expect fetch_304 == 0 +varnish v1 -expect cond_not_validated == 0 + +server s1 -wait +varnish v1 -stop + +## If ttl is set to 0 but keep is then set to non-zero, +## then the object is used for conditional requests +## First test using beresp in vcl_fetch() + +server s2 { + rxreq + expect req.url == "/foo" + txresp -status 200 \ + -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \ + -body "The quick brown fox jumps over the lazy dog." + + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT" + txresp -status 304 +} -start + +varnish v1 -vcl { + backend s2 { + .host = "${s2_addr}"; .port = "${s2_port}"; + } + + # NB: return(deliver) necessary here, because default vcl_fetch() returns + # hit_for_pass if beresp.ttl <= 0 + sub vcl_fetch { + set beresp.ttl = 0s; + set beresp.keep = 1m; + return (deliver); + } +} -start + +client c2 { + txreq -url "/foo" + rxresp + expect resp.status == 200 + expect resp.bodylen == 44 +} -run + +delay 0.5 + +client c2 -run + +varnish v1 -expect fetch_304 == 1 +varnish v1 -expect cond_not_validated == 0 + +server s2 -wait +varnish v1 -stop + +## Verify using obj.ttl in vcl_hit() + +server s2 -start + +varnish v1 -vcl { + backend s2 { + .host = "${s2_addr}"; .port = "${s2_port}"; + } + + sub vcl_hit { + set obj.ttl = 0s; + set obj.keep = 1m; + } +} -start + +client c1 -run + +client c1 -run + +delay 0.5 + +client c1 -run + +varnish v1 -expect fetch_304 == 1 +varnish v1 -expect cond_not_validated == 0 diff --git a/bin/varnishtest/tests/i00006.vtc b/bin/varnishtest/tests/i00006.vtc new file mode 100644 index 0000000..87c6192 --- /dev/null +++ b/bin/varnishtest/tests/i00006.vtc @@ -0,0 +1,156 @@ +# $Id$ + +test "Verify effects of ttl, keep and grace on expiration" + +## Verify that an object's lifetime in the cache is +## obj.ttl + max(obj.grace, obj.keep) +## First with grace < keep + +server s1 { + rxreq + expect req.url == "/foo" + txresp -status 200 \ + -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \ + -body "fred garply waldo xyzzy" + + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT" + txresp -status 304 + + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since != "Thu, 26 Jun 2008 12:00:01 GMT" + txresp -status 200 -body "fred garply waldo xyzzy" +} -start + +varnish v1 -vcl+backend { + sub vcl_fetch { + set beresp.ttl = 0.5s; + set beresp.grace = 0.5s; + set beresp.keep = 1s; + } +} -start + +client c1 { + txreq -url "/foo" + rxresp + expect resp.status == 200 + expect resp.bodylen == 23 +} -run + +delay 1.1 + +client c2 { + txreq -url "/foo" + rxresp + expect resp.status == 200 + expect resp.bodylen == 23 + expect resp.msg == "Ok Not Modified" +} -run + +delay 1.6 + +client c3 { + txreq -url "/foo" + rxresp + expect resp.msg == "Ok" +} -run + +varnish v1 -expect fetch_304 == 1 +varnish v1 -expect cond_not_validated == 0 + +server s1 -wait +varnish v1 -stop + +## Now with keep < grace + +server s1 { + rxreq + expect req.url == "/foo" + txresp -status 200 \ + -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \ + -body "fred garply waldo xyzzy" + + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT" + txresp -status 304 + + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since != "Thu, 26 Jun 2008 12:00:01 GMT" + txresp -status 200 -body "fred garply waldo xyzzy" +} -start + +varnish v1 -vcl+backend { + sub vcl_fetch { + set beresp.ttl = 1s; + set beresp.grace = 1s; + set beresp.keep = 0.5s; + } +} -start + +client c1 { + txreq -url "/foo" + rxresp + expect resp.status == 200 + expect resp.bodylen == 23 +} -run + +delay 1.1 + +client c2 { + txreq -url "/foo" + rxresp + expect resp.status == 200 + expect resp.bodylen == 23 + expect resp.msg == "Ok Not Modified" +} -run + +delay 1.6 + +client c3 { + txreq -url "/foo" + rxresp + expect resp.msg == "Ok" +} -run + +varnish v1 -expect fetch_304 == 1 +varnish v1 -expect cond_not_validated == 0 + +server s1 -wait +varnish v1 -stop + +## Verify that req.keep sets an upper bound in the session + +server s1 -start + +varnish v1 -vcl { + backend s1 { + .host = "${s1_addr}"; .port = "${s1_port}"; + } + + sub vcl_recv { + set req.keep = 1s; + } + + sub vcl_fetch { + set beresp.ttl = 1s; + set beresp.grace = 0s; + set beresp.keep = 2s; + } +} -start + +client c1 -run + +delay 1.1 + +client c2 -run + +delay 2.1 + +client c3 -run + +varnish v1 -expect fetch_304 == 1 +varnish v1 -expect cond_not_validated == 0 diff --git a/bin/varnishtest/tests/i00007.vtc b/bin/varnishtest/tests/i00007.vtc new file mode 100644 index 0000000..487c0d0 --- /dev/null +++ b/bin/varnishtest/tests/i00007.vtc @@ -0,0 +1,129 @@ +# $Id$ + +test "Passes through responses to backend conditionals to the client if status != 304 or 200" + +# Testing a sample from each of the Nxx status codes + +server s1 { + rxreq + expect req.url == "/foo" + txresp -status 200 \ + -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \ + -body "Varnish has poked you" + + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT" + txresp -status 304 + + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT" + txresp -status 201 -msg "Created" \ + -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \ + -body "Varnish has poked you" + + # 3xx responses typically do not include Last-Modified or a body + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT" + txresp -status 301 -msg "Moved Permanently" + + # Restore a cached object with Last-Modified + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since != "Thu, 26 Jun 2008 12:00:01 GMT" + txresp -status 200 \ + -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \ + -body "Varnish has poked you" + + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT" + txresp -status 400 -msg "Bad Request" \ + -body "Varnish has poked you" + + # Restore a cached object with Last-Modified + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since != "Thu, 26 Jun 2008 12:00:01 GMT" + txresp -status 200 \ + -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \ + -body "Varnish has poked you" + + rxreq + expect req.url == "/foo" + expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT" + txresp -status 500 -msg "Internal Server Error" \ + -body "Varnish has poked you" +} -start + +varnish v1 -vcl+backend { + sub vcl_fetch { + set beresp.ttl = 1s; + set beresp.grace = 0s; + set beresp.keep = 1s; + } +} -start + +client c1 { + txreq -url "/foo" + rxresp + expect resp.status == 200 + expect resp.bodylen == 21 +} -run + +delay 1.1 + +client c1 -run + +delay 1.1 + +client c2 { + txreq -url "/foo" + rxresp + expect resp.status == 201 + expect resp.msg == "Created" + expect resp.http.Last-Modified == "Thu, 26 Jun 2008 12:00:01 GMT" + expect resp.bodylen == 21 +} -run + +delay 1.1 + +client c2 { + txreq -url "/foo" + rxresp + expect resp.status == 301 + expect resp.msg == "Moved Permanently" +} -run + +delay 1.1 + +client c1 -run + +delay 1.1 + +client c2 { + txreq -url "/foo" + rxresp + expect resp.status == 400 + expect resp.msg == "Bad Request" + expect resp.bodylen == 21 +} -run + +delay 1.1 + +client c1 -run + +delay 1.1 + +client c2 { + txreq -url "/foo" + rxresp + expect resp.status == 500 + expect resp.msg == "Internal Server Error" + expect resp.bodylen == 21 +} -run + +varnish v1 -expect fetch_304 == 1 +varnish v1 -expect cond_not_validated == 4 From geoff at varnish-cache.org Fri Jul 8 09:47:53 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:53 +0200 Subject: [experimental-ims] ffaedcc Merged conditional backend request feature Message-ID: commit ffaedccbbb526e54edbb092ebc50ce8d0dd62642 Author: Geoff Simmons Date: Thu Jun 2 21:47:07 2011 +0200 Merged conditional backend request feature diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index a875071..8515c5e 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -596,6 +596,7 @@ struct sess { struct objcore *objcore; struct VCL_conf *vcl; + struct object *stale_obj; /* The busy objhead we sleep on */ struct objhead *hash_objhead; @@ -753,6 +754,12 @@ void http_SetResp(struct http *to, const char *proto, int status, void http_FilterFields(struct worker *w, int fd, struct http *to, const struct http *fm, unsigned how); void http_FilterHeader(const struct sess *sp, unsigned how); + +/* Check if a refresh should be done */ +void http_CheckRefresh(struct sess *sp); +/* Check if we got 304 response */ +void http_Check304(struct sess *sp); + void http_PutProtocol(struct worker *w, int fd, const struct http *to, const char *protocol); void http_PutStatus(struct http *to, int status); diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index 23ad92f..6455985 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -558,6 +558,7 @@ cnt_fetch(struct sess *sp) sp->wrk->age = 0; EXP_Clr(&sp->wrk->exp); sp->wrk->exp.ttl = RFC2616_Ttl(sp); + sp->wrk->exp.keep = params->default_keep; /* pass from vclrecv{} has negative TTL */ if (sp->objcore == NULL) @@ -638,7 +639,7 @@ cnt_fetchbody(struct sess *sp) int i; struct http *hp, *hp2; char *b; - unsigned l, nhttp; + unsigned l, nhttp, stale_nhttp; struct vsb *vary = NULL; int varyl = 0, pass; @@ -724,6 +725,10 @@ cnt_fetchbody(struct sess *sp) l = http_EstimateWS(sp->wrk->beresp, pass ? HTTPH_R_PASS : HTTPH_A_INS, &nhttp); + if (sp->stale_obj) { + l += http_EstimateWS(sp->stale_obj->http, 0, &stale_nhttp); + nhttp += stale_nhttp; + } /* Create Vary instructions */ if (sp->objcore != NULL) { @@ -763,6 +768,7 @@ cnt_fetchbody(struct sess *sp) return (0); } CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); + sp->obj->exp.keep = sp->wrk->exp.keep; sp->wrk->storage_hint = NULL; @@ -789,11 +795,29 @@ cnt_fetchbody(struct sess *sp) hp2->logtag = HTTP_Obj; http_CopyResp(hp2, hp); - http_FilterFields(sp->wrk, sp->fd, hp2, hp, - pass ? HTTPH_R_PASS : HTTPH_A_INS); - http_CopyHome(sp->wrk, sp->fd, hp2); - - if (http_GetHdr(hp, H_Last_Modified, &b)) + + http_FilterFields(sp->wrk, sp->fd, hp2, hp, + pass ? HTTPH_R_PASS : HTTPH_A_INS); + + /* + * If we found a candidate for conditional backend request, attempt it + * now. If backend responds with 304, http_Check304() merges stale_obj + * into sp->obj, any other response is handled as usual. In either case, + * the stale_obj is no longer needed in the cache, so discard it. + */ + if (sp->stale_obj) { + http_Check304(sp); + if (sp->wrk->beresp->status == 304) + assert(sp->obj->http->status == 200); + EXP_Clr(&sp->stale_obj->exp); + EXP_Rearm(sp->stale_obj); + HSH_Deref(sp->wrk, NULL, &sp->stale_obj); + AZ(sp->stale_obj); + } + http_CopyHome(sp->wrk, sp->fd, hp2); + + if (http_GetHdr(hp, H_Last_Modified, &b) + || http_GetHdr(sp->obj->http, H_Last_Modified, &b)) sp->obj->last_modified = TIM_parse(b); else sp->obj->last_modified = floor(sp->wrk->entered); @@ -1089,6 +1113,8 @@ cnt_lookup(struct sess *sp) sp->wrk->stats.cache_hitpass++; WSP(sp, SLT_HitPass, "%u", sp->obj->xid); (void)HSH_Deref(sp->wrk, NULL, &sp->obj); + if (sp->stale_obj != NULL) + (void)HSH_Deref(sp->wrk, NULL, &sp->stale_obj); sp->objcore = NULL; sp->step = STP_PASS; return (0); @@ -1149,6 +1175,13 @@ cnt_miss(struct sess *sp) sp->wrk->connect_timeout = 0; sp->wrk->first_byte_timeout = 0; sp->wrk->between_bytes_timeout = 0; + + /* If a candidate for a conditional backend request was found, + * add If-Modified-Since and/or If-None-Match to the bereq. + */ + if (sp->stale_obj) + http_CheckRefresh(sp); + VCL_miss_method(sp); switch(sp->handling) { case VCL_RET_ERROR: diff --git a/bin/varnishd/cache_fetch.c b/bin/varnishd/cache_fetch.c index 1063c6b..b3704b4 100644 --- a/bin/varnishd/cache_fetch.c +++ b/bin/varnishd/cache_fetch.c @@ -498,8 +498,13 @@ FetchBody(struct sess *sp) AN(sp->director); AssertObjPassOrBusy(sp->obj); + /* If we've freshened from another object and got a "Not Modified" + * response, then we have already duped the other object's body. + */ + if (sp->wrk->beresp->status != 304) + AZ(VTAILQ_FIRST(&sp->obj->store)); + AZ(sp->wrk->vgz_rx); - AZ(VTAILQ_FIRST(&sp->obj->store)); switch (sp->wrk->body_status) { case BS_NONE: cls = 0; diff --git a/bin/varnishd/cache_hash.c b/bin/varnishd/cache_hash.c index 6fdff15..7f9eacd 100644 --- a/bin/varnishd/cache_hash.c +++ b/bin/varnishd/cache_hash.c @@ -305,13 +305,16 @@ HSH_Lookup(struct sess *sp, struct objhead **poh) struct objcore *oc; struct objcore *busy_oc, *grace_oc; struct object *o; - double grace_ttl; + struct object *stale_o; /* for freshness check */ + double grace_ttl, stale_ttl; + char *p; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(sp->http, HTTP_MAGIC); CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC); AN(hash); + AZ(sp->stale_obj); w = sp->wrk; HSH_Prealloc(sp); @@ -339,7 +342,9 @@ HSH_Lookup(struct sess *sp, struct objhead **poh) assert(oh->refcnt > 0); busy_oc = NULL; grace_oc = NULL; + stale_o = NULL; /* for freshness check */ grace_ttl = NAN; + stale_ttl = NAN; VTAILQ_FOREACH(oc, &oh->objcs, list) { /* Must be at least our own ref + the objcore we examine */ assert(oh->refcnt > 1); @@ -362,7 +367,8 @@ HSH_Lookup(struct sess *sp, struct objhead **poh) o = oc_getobj(sp->wrk, oc); CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); - if (o->exp.ttl <= 0.) + if (o->exp.ttl <= 0. && o->exp.grace <= 0. + && o->exp.keep <= 0.) continue; if (BAN_CheckObject(o, sp)) continue; @@ -384,6 +390,24 @@ HSH_Lookup(struct sess *sp, struct objhead **poh) grace_ttl = o->entered + o->exp.ttl; } } + + /* At this point we know: + * - o's TTL has elapsed + * - o is not busy or banned, + * - o is not a Vary match. + * The object may be used for a conditional backend request if + * - the keep time has not elapsed, and + * - it has a Last-Modified and/or an ETag header. + * If there are several, use the least expired one. + */ + if (EXP_Keep(sp, o) >= sp->t_req + && (http_GetHdr(o->http, H_Last_Modified, &p) + || http_GetHdr(o->http, H_ETag, &p))) + if (stale_o == NULL || stale_ttl < o->entered + o->exp.ttl) { + stale_o = o; + stale_ttl = o->entered + o->exp.ttl; + } + } /* @@ -451,6 +475,18 @@ HSH_Lookup(struct sess *sp, struct objhead **poh) return (NULL); } + /* If we're not serving a valid or graced object and we saved stale_o, + * it is a candidate for the conditional backend request. */ + AZ(oc && !sp->hash_always_miss); + AZ(busy_oc); + if (stale_o != NULL) { + AZ(stale_o->objcore->flags & OC_F_BUSY); + CHECK_OBJ_NOTNULL(stale_o->objcore, OBJCORE_MAGIC); + Lck_AssertHeld(&oh->mtx); + stale_o->objcore->refcnt++; + sp->stale_obj = stale_o; + } + /* Insert (precreated) objcore in objecthead */ oc = w->nobjcore; w->nobjcore = NULL; diff --git a/bin/varnishd/cache_http.c b/bin/varnishd/cache_http.c index 5d8050a..f0e1756 100644 --- a/bin/varnishd/cache_http.c +++ b/bin/varnishd/cache_http.c @@ -40,6 +40,8 @@ #include "vct.h" #include "cache.h" +#include "hash_slinger.h" +#include "stevedore.h" #define HTTPH(a, b, c, d, e, f, g) char b[] = "*" a ":"; #include "http_headers.h" @@ -65,6 +67,10 @@ static const enum VSL_tag_e logmtx[][HTTP_HDR_FIRST + 1] = { /*lint -restore */ static enum VSL_tag_e + +void http_FilterMissingFields(struct worker *w, int fd, struct http *to, + const struct http *fm); + http2shmlog(const struct http *hp, int t) { @@ -848,6 +854,36 @@ http_FilterFields(struct worker *w, int fd, struct http *to, } } +/*--------------------------------------------------------------------- + * Same as http_FilterFields but keep any existing hdrs in fm. + * Furthermore, before copy, check if fm already has that hdr, and if so + * do not copy. Used for 304 refresh processing. + */ + +/* XXX: uplex/GS: Also, don't filter according to the "how" bitmap in + * http_headers.h. We only use this to copy from one cached object to + * another, so if a header made into the first object, we want it. + */ + +void +http_FilterMissingFields(struct worker *w, int fd, struct http *to, + const struct http *fm) +{ + unsigned u; + unsigned hdrlen; + + CHECK_OBJ_NOTNULL(fm, HTTP_MAGIC); + CHECK_OBJ_NOTNULL(to, HTTP_MAGIC); + for (u = HTTP_HDR_FIRST; u < fm->nhd; u++) { + if (fm->hd[u].b == NULL) + continue; + hdrlen = strchr(fm->hd[u].b, ':') - fm->hd[u].b; + if (http_findhdr(to, hdrlen, fm->hd[u].b)) + continue; + http_copyheader(w, fd, to, fm, u); + } +} + /*--------------------------------------------------------------------*/ void @@ -869,6 +905,89 @@ http_FilterHeader(const struct sess *sp, unsigned how) http_PrintfHeader(sp->wrk, sp->fd, hp, "X-Varnish: %u", sp->xid); } +/*------------------------------------------------------------------- + * This function checks for sp->freshen_obj. If present, HSH_Lookup() + * found an expired object that qualifies for a refresh check, + * so add the appropriate headers. + */ + +void +http_CheckRefresh(struct sess *sp) +{ + struct object *freshen_obj; + struct http *obj_hp, *bereq_hp; + char *p; + + freshen_obj = sp->stale_obj; + CHECK_OBJ_NOTNULL(freshen_obj, OBJECT_MAGIC); + bereq_hp = sp->wrk->bereq; + CHECK_OBJ_NOTNULL(bereq_hp, HTTP_MAGIC); + obj_hp = freshen_obj->http; + CHECK_OBJ_NOTNULL(obj_hp, HTTP_MAGIC); + + if(http_GetHdr(obj_hp, H_ETag, &p)) + http_PrintfHeader(sp->wrk, sp->fd, bereq_hp, "If-None-Match: %s", p); + + if(http_GetHdr(obj_hp, H_Last_Modified, &p)) + http_PrintfHeader(sp->wrk, sp->fd, bereq_hp, "If-Modified-Since: %s",p); +} + +/*------------------------------------------------------------------- + * Called after fetch and sp->freshen_obj present. Check + * response and handle as needed. + */ + +void +http_Check304(struct sess *sp) +{ + struct object *o, *o_stale; + char *p; + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + o_stale = sp->stale_obj; + CHECK_OBJ_NOTNULL(o_stale, OBJECT_MAGIC); + o = sp->obj; + CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); + + if (sp->wrk->beresp->status != 304) { + /* + * IMS/INM headers may have been removed in VCL, so only count a + * non-validating response if they were present in the request. + */ + if (http_GetHdr(sp->wrk->bereq, H_If_Modified_Since, &p) + || http_GetHdr(sp->wrk->bereq, H_If_None_Match, &p)) + sp->wrk->stats.cond_not_validated++; + return; + } + + /* + * Copy headers we need from the stale object into the 304 response + */ + http_FilterMissingFields(sp->wrk, sp->fd, sp->obj->http, + sp->stale_obj->http); + + /* + * Dup the stale object's storage in to the new object + * and reset Content-Length from the size of the storage. + */ + STV_dup(sp, o_stale, o); + http_Unset(o->http, H_Content_Length); + http_PrintfHeader(sp->wrk, sp->fd, o->http, "Content-Length: %u", o->len); + + http_SetResp(o->http, "HTTP/1.1", 200, "Ok Not Modified"); + http_SetH(o->http, HTTP_HDR_REQ, "GET"); + http_copyh(o->http, sp->wrk->bereq, HTTP_HDR_URL); + + /* + * XXX: Are we copying all the necessary fields from stale_obj? + * Should we copy o_stale->hits into o->hits? + */ + o->response = 200; + o->gziped = o_stale->gziped; + + AZ(o_stale->objcore->flags & OC_F_BUSY); +} + /*-------------------------------------------------------------------- * This function copies any header fields which reference foreign * storage into our own WS. diff --git a/bin/varnishd/cache_vrt.c b/bin/varnishd/cache_vrt.c index 65b7522..07adeac 100644 --- a/bin/varnishd/cache_vrt.c +++ b/bin/varnishd/cache_vrt.c @@ -112,6 +112,10 @@ vrt_selecthttp(const struct sess *sp, enum gethdr_e where) CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); hp = sp->obj->http; break; + case HDR_STALE_OBJ: + CHECK_OBJ_NOTNULL(sp->stale_obj, OBJECT_MAGIC); + hp = sp->stale_obj->http; + break; default: INCOMPL(); } @@ -126,6 +130,11 @@ VRT_GetHdr(const struct sess *sp, enum gethdr_e where, const char *n) struct http *hp; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + if (where == HDR_STALE_OBJ && sp->stale_obj == NULL) { + WSP(sp, SLT_VCL_error, + "stale_obj does not exist (reading header %s)", n); + return NULL; + } hp = vrt_selecthttp(sp, where); if (!http_GetHdr(hp, n, &p)) return (NULL); diff --git a/bin/varnishd/cache_vrt_var.c b/bin/varnishd/cache_vrt_var.c index 297151c..3396726 100644 --- a/bin/varnishd/cache_vrt_var.c +++ b/bin/varnishd/cache_vrt_var.c @@ -40,6 +40,9 @@ #include "cache_backend.h" #include "hash_slinger.h" +#define ILLEGAL_R(sess, obj, field) \ +WSP(sess, SLT_VCL_error, "%s does not exist (reading field %s)", obj, field) + static char vrt_hostname[255] = ""; /*--------------------------------------------------------------------*/ @@ -61,7 +64,7 @@ vrt_do_string(struct worker *w, int fd, const struct http *hp, int fld, va_end(ap); } -#define VRT_DO_HDR(obj, hdr, http, fld) \ +#define VRT_DO_HDR_l(obj, hdr, cont, http, fld) \ void \ VRT_l_##obj##_##hdr(const struct sess *sp, const char *p, ...) \ { \ @@ -69,53 +72,74 @@ VRT_l_##obj##_##hdr(const struct sess *sp, const char *p, ...) \ \ va_start(ap, p); \ vrt_do_string(sp->wrk, sp->fd, \ - http, fld, #obj "." #hdr, p, ap); \ + cont->http, fld, #obj "." #hdr, p, ap); \ va_end(ap); \ -} \ - \ +} + +#define VRT_DO_HDR_r(obj, hdr, cont, http, fld, nullable) \ const char * \ VRT_r_##obj##_##hdr(const struct sess *sp) \ { \ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \ - CHECK_OBJ_NOTNULL(http, HTTP_MAGIC); \ - return (http->hd[fld].b); \ -} - -VRT_DO_HDR(req, request, sp->http, HTTP_HDR_REQ) -VRT_DO_HDR(req, url, sp->http, HTTP_HDR_URL) -VRT_DO_HDR(req, proto, sp->http, HTTP_HDR_PROTO) -VRT_DO_HDR(bereq, request, sp->wrk->bereq, HTTP_HDR_REQ) -VRT_DO_HDR(bereq, url, sp->wrk->bereq, HTTP_HDR_URL) -VRT_DO_HDR(bereq, proto, sp->wrk->bereq, HTTP_HDR_PROTO) -VRT_DO_HDR(obj, proto, sp->obj->http, HTTP_HDR_PROTO) -VRT_DO_HDR(obj, response, sp->obj->http, HTTP_HDR_RESPONSE) -VRT_DO_HDR(resp, proto, sp->wrk->resp, HTTP_HDR_PROTO) -VRT_DO_HDR(resp, response, sp->wrk->resp, HTTP_HDR_RESPONSE) -VRT_DO_HDR(beresp, proto, sp->wrk->beresp, HTTP_HDR_PROTO) -VRT_DO_HDR(beresp, response, sp->wrk->beresp, HTTP_HDR_RESPONSE) + if (!nullable || cont != NULL) { \ + CHECK_OBJ_NOTNULL(cont->http, HTTP_MAGIC); \ + return (cont->http->hd[fld].b); \ + } \ + ILLEGAL_R(sp, #obj, #hdr); \ + return(NULL); \ +} \ + +#define VRT_DO_HDR(obj, hdr, cont, http, fld, nullable) \ +VRT_DO_HDR_l(obj, hdr, cont, http, fld) \ +VRT_DO_HDR_r(obj, hdr, cont, http, fld, nullable) \ + +VRT_DO_HDR(req, request, sp, http, HTTP_HDR_REQ, 0) +VRT_DO_HDR(req, url, sp, http, HTTP_HDR_URL, 0) +VRT_DO_HDR(req, proto, sp, http, HTTP_HDR_PROTO, 0) +VRT_DO_HDR(bereq, request, sp->wrk, bereq, HTTP_HDR_REQ, 0) +VRT_DO_HDR(bereq, url, sp->wrk, bereq, HTTP_HDR_URL, 0) +VRT_DO_HDR(bereq, proto, sp->wrk, bereq, HTTP_HDR_PROTO, 0) +VRT_DO_HDR(obj, proto, sp->obj, http, HTTP_HDR_PROTO, 0) +VRT_DO_HDR(obj, response, sp->obj, http, HTTP_HDR_RESPONSE, 0) +VRT_DO_HDR(resp, proto, sp->wrk, resp, HTTP_HDR_PROTO, 0) +VRT_DO_HDR(resp, response, sp->wrk, resp, HTTP_HDR_RESPONSE, 0) +VRT_DO_HDR(beresp, proto, sp->wrk, beresp, HTTP_HDR_PROTO, 0) +VRT_DO_HDR(beresp, response, sp->wrk, beresp, HTTP_HDR_RESPONSE, 0) +VRT_DO_HDR_r(stale_obj, proto, sp->stale_obj, http, HTTP_HDR_PROTO, 1) +VRT_DO_HDR_r(stale_obj, response, sp->stale_obj, http, HTTP_HDR_RESPONSE, 1) /*--------------------------------------------------------------------*/ -#define VRT_DO_STATUS(obj, http) \ +#define VRT_DO_STATUS_l(obj, cont, http) \ void \ VRT_l_##obj##_status(const struct sess *sp, int num) \ { \ \ assert(num >= 100 && num <= 999); \ - http->status = num; \ -} \ - \ + cont->http->status = num; \ +} + +#define VRT_DO_STATUS_r(obj, cont, http, nullable) \ int \ VRT_r_##obj##_status(const struct sess *sp) \ { \ \ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \ - return(http->status); \ + if (nullable && cont == NULL) { \ + ILLEGAL_R(sp, #obj, "status"); \ + return (503); \ + } \ + return(cont->http->status); \ } -VRT_DO_STATUS(obj, sp->obj->http) -VRT_DO_STATUS(beresp, sp->wrk->beresp) -VRT_DO_STATUS(resp, sp->wrk->resp) +#define VRT_DO_STATUS(obj, cont, http, nullable) \ +VRT_DO_STATUS_l(obj, cont, http) \ +VRT_DO_STATUS_r(obj, cont, http, nullable) \ + +VRT_DO_STATUS(obj, sp->obj, http, 0) +VRT_DO_STATUS(beresp, sp->wrk, beresp, 0) +VRT_DO_STATUS(resp, sp->wrk, resp, 0) +VRT_DO_STATUS_r(stale_obj, sp->stale_obj, http, 1) /*--------------------------------------------------------------------*/ @@ -362,37 +386,48 @@ VRT_r_req_restarts(const struct sess *sp) /*--------------------------------------------------------------------*/ -#define VRT_DO_EXP(which, exp, fld, extra) \ - \ -void __match_proto__() \ -VRT_l_##which##_##fld(struct sess *sp, double a) \ -{ \ - \ - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \ - EXP_Set_##fld(&exp, a); \ - extra; \ -} \ - \ -double __match_proto__() \ -VRT_r_##which##_##fld(struct sess *sp) \ -{ \ - \ - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \ - return(EXP_Get_##fld(&exp)); \ +#define VRT_DO_EXP_l(which, cont, fld, extra) \ +void __match_proto__() \ +VRT_l_##which##_##fld(struct sess *sp, double a) \ +{ \ + \ + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \ + EXP_Set_##fld(&cont->exp, a); \ + extra; \ +} + +#define VRT_DO_EXP_r(which, cont, fld, nullable) \ +double __match_proto__() \ +VRT_r_##which##_##fld(struct sess *sp) \ +{ \ + \ + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \ + if (nullable && cont == NULL) { \ + ILLEGAL_R(sp, #which, #fld); \ + return (-1); \ + } \ + return(EXP_Get_##fld(&cont->exp)); \ } -VRT_DO_EXP(req, sp->exp, ttl, ) -VRT_DO_EXP(req, sp->exp, grace, ) -VRT_DO_EXP(req, sp->exp, keep, ) -VRT_DO_EXP(obj, sp->obj->exp, grace, EXP_Rearm(sp->obj)) -VRT_DO_EXP(obj, sp->obj->exp, ttl, +#define VRT_DO_EXP(which, cont, fld, nullable, extra) \ +VRT_DO_EXP_l(which, cont, fld, extra) \ +VRT_DO_EXP_r(which, cont, fld, nullable) \ + +VRT_DO_EXP(req, sp, ttl, 0, ) +VRT_DO_EXP(req, sp, grace, 0, ) +VRT_DO_EXP(req, sp, keep, 0, ) +VRT_DO_EXP(obj, sp->obj, grace, 0, EXP_Rearm(sp->obj)) +VRT_DO_EXP(obj, sp->obj, ttl, 0, EXP_Rearm(sp->obj); WSP(sp, SLT_TTL, "%u VCL %.0f %.0f", sp->obj->xid, a, sp->t_req)) -VRT_DO_EXP(obj, sp->obj->exp, keep, EXP_Rearm(sp->obj)) -VRT_DO_EXP(beresp, sp->wrk->exp, grace, ) -VRT_DO_EXP(beresp, sp->wrk->exp, ttl, +VRT_DO_EXP(obj, sp->obj, keep, 0, EXP_Rearm(sp->obj)) +VRT_DO_EXP(beresp, sp->wrk, grace, 0, ) +VRT_DO_EXP(beresp, sp->wrk, ttl, 0, WSP(sp, SLT_TTL, "%u VCL %.0f %.0f", sp->xid, a, sp->t_req)) -VRT_DO_EXP(beresp, sp->wrk->exp, keep, ) +VRT_DO_EXP(beresp, sp->wrk, keep, 0, ) +VRT_DO_EXP_r(stale_obj, sp->stale_obj, grace, 1) +VRT_DO_EXP_r(stale_obj, sp->stale_obj, ttl, 1) +VRT_DO_EXP_r(stale_obj, sp->stale_obj, keep, 1) /*-------------------------------------------------------------------- * req.xid @@ -493,6 +528,8 @@ VRT_r_server_port(struct sess *sp) /*--------------------------------------------------------------------*/ +/* XXX: uplex/GS: a nice macro would eliminate the repetition here ... */ + int VRT_r_obj_hits(const struct sess *sp) { @@ -502,6 +539,19 @@ VRT_r_obj_hits(const struct sess *sp) return (sp->obj->hits); } +int +VRT_r_stale_obj_hits(const struct sess *sp) +{ + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + if (sp->stale_obj == NULL) { + ILLEGAL_R(sp, "stale_obj", "hits"); + return (0); + } + CHECK_OBJ(sp->stale_obj, OBJECT_MAGIC); /* XXX */ + return (sp->stale_obj->hits); +} + double VRT_r_obj_lastuse(const struct sess *sp) { @@ -511,6 +561,19 @@ VRT_r_obj_lastuse(const struct sess *sp) return (TIM_real() - sp->obj->last_use); } +double +VRT_r_stale_obj_lastuse(const struct sess *sp) +{ + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + if (sp->stale_obj == NULL) { + ILLEGAL_R(sp, "stale_obj", "lastuse"); + return (0); + } + CHECK_OBJ(sp->stale_obj, OBJECT_MAGIC); /* XXX */ + return (TIM_real() - sp->stale_obj->last_use); +} + unsigned VRT_r_req_backend_healthy(const struct sess *sp) { @@ -519,3 +582,9 @@ VRT_r_req_backend_healthy(const struct sess *sp) return (VDI_Healthy(sp->director, sp)); } +unsigned +VRT_r_stale_obj(const struct sess *sp) +{ + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + return (sp->stale_obj != NULL); +} diff --git a/bin/varnishd/mgt_param.c b/bin/varnishd/mgt_param.c index 26fcb31..f811198 100644 --- a/bin/varnishd/mgt_param.c +++ b/bin/varnishd/mgt_param.c @@ -582,13 +582,13 @@ static const struct parspec input_parspec[] = { "10", "seconds" }, { "default_keep", tweak_timeout_double, &master.default_keep, 0, UINT_MAX, - "Default keep period. We will keep a useless object " + "Default keep period. We will keep a stale object " "around this long, making it available for conditional " "backend fetches. " "That means that the object will be removed from the " - "cache at the end of ttl+grace+keep.", + "cache at the end of ttl+max(grace,keep).", DELAYED_EFFECT, - "0", "seconds" }, + "10", "seconds" }, { "sess_timeout", tweak_timeout, &master.sess_timeout, 0, 0, "Idle timeout for persistent sessions. " "If a HTTP request has not been received in this many " diff --git a/bin/varnishd/stevedore.c b/bin/varnishd/stevedore.c index 413e0b6..7c1665e 100644 --- a/bin/varnishd/stevedore.c +++ b/bin/varnishd/stevedore.c @@ -370,6 +370,30 @@ STV_trim(struct storage *st, size_t size) st->stevedore->trim(st, size); } +/* + * Duplicate the object storage (HTML body) from src into target, using a + * stevedore-specific dup method for src's stevedore. + * + * Currently, every method just copies storage from one object to the other, + * but this method of encapsulation opens the path to future techniques of + * sharing storage together with reference counting. + */ +void +STV_dup(const struct sess *sp, struct object *src, struct object *target) +{ + struct stevedore *stv; + + CHECK_OBJ_NOTNULL(src, OBJECT_MAGIC); + CHECK_OBJ_NOTNULL(target, OBJECT_MAGIC); + CHECK_OBJ_NOTNULL(src->objstore, STORAGE_MAGIC); + CHECK_OBJ_NOTNULL(src->objstore->stevedore, STEVEDORE_MAGIC); + + stv = src->objstore->stevedore; + AN(stv->dup); + + stv->dup(sp, src, target); +} + void STV_free(struct storage *st) { @@ -586,3 +610,24 @@ VRT_Stv_##nm(const char *nm) \ #include "vrt_stv_var.h" #undef VRTSTVVAR + +/* + * Default object store dup just copies the storage. + */ +void +default_dup(const struct sess *sp, struct object *src, struct object *target) +{ + struct storage *st, *st2; + unsigned cl; + + VTAILQ_FOREACH(st2, &src->store, list) { + cl = st2->len; + st = STV_alloc(sp, cl); + XXXAN(st); + assert(st->space >= cl); + VTAILQ_INSERT_TAIL(&target->store, st, list); + st->len = cl; + target->len += cl; + memcpy(st->ptr, st2->ptr, cl); + } +} diff --git a/bin/varnishd/stevedore.h b/bin/varnishd/stevedore.h index 5a5cc4b..1c0d2ee 100644 --- a/bin/varnishd/stevedore.h +++ b/bin/varnishd/stevedore.h @@ -39,6 +39,7 @@ struct stv_objsecrets; typedef void storage_init_f(struct stevedore *, int ac, char * const *av); typedef void storage_open_f(const struct stevedore *); typedef struct storage *storage_alloc_f(struct stevedore *, size_t size); +typedef void storage_dup_f(const struct sess *sp, struct object *src, struct object *target); typedef void storage_trim_f(struct storage *, size_t size); typedef void storage_free_f(struct storage *); typedef struct object *storage_allocobj_f(struct stevedore *, struct sess *sp, @@ -70,6 +71,7 @@ struct stevedore { storage_open_f *open; /* called by cache process */ storage_alloc_f *alloc; /* --//-- */ storage_trim_f *trim; /* --//-- */ + storage_dup_f *dup; /* --//-- */ storage_free_f *free; /* --//-- */ storage_close_f *close; /* --//-- */ storage_allocobj_f *allocobj; /* --//-- */ @@ -93,6 +95,7 @@ struct object *STV_MkObject(struct sess *sp, void *ptr, unsigned ltot, struct object *STV_NewObject(struct sess *sp, const char *hint, unsigned len, struct exp *, unsigned nhttp); struct storage *STV_alloc(const struct sess *sp, size_t size); +void STV_dup(const struct sess *sp, struct object *src, struct object *target); void STV_trim(struct storage *st, size_t size); void STV_free(struct storage *st); void STV_open(void); @@ -117,3 +120,6 @@ extern const struct stevedore smp_stevedore; #ifdef HAVE_LIBUMEM extern const struct stevedore smu_stevedore; #endif + +/* Default dup method */ +void default_dup(const struct sess *sp, struct object *src, struct object *target); diff --git a/bin/varnishd/storage_file.c b/bin/varnishd/storage_file.c index 27cc86f..84e56ce 100644 --- a/bin/varnishd/storage_file.c +++ b/bin/varnishd/storage_file.c @@ -551,6 +551,7 @@ const struct stevedore smf_stevedore = { .alloc = smf_alloc, .trim = smf_trim, .free = smf_free, + .dup = default_dup, }; #ifdef INCLUDE_TEST_DRIVER diff --git a/bin/varnishd/storage_malloc.c b/bin/varnishd/storage_malloc.c index 12a390f..2e9b81f 100644 --- a/bin/varnishd/storage_malloc.c +++ b/bin/varnishd/storage_malloc.c @@ -221,4 +221,5 @@ const struct stevedore sma_stevedore = { .trim = sma_trim, .var_free_space = sma_free_space, .var_used_space = sma_used_space, + .dup = default_dup, }; diff --git a/bin/varnishd/storage_persistent.c b/bin/varnishd/storage_persistent.c index a4ba598..4cc0eca 100644 --- a/bin/varnishd/storage_persistent.c +++ b/bin/varnishd/storage_persistent.c @@ -567,6 +567,7 @@ const struct stevedore smp_stevedore = { .allocobj = smp_allocobj, .free = smp_free, .trim = smp_trim, + .dup = default_dup, }; /*-------------------------------------------------------------------- diff --git a/bin/varnishd/storage_synth.c b/bin/varnishd/storage_synth.c index 24479e3..3ddab87 100644 --- a/bin/varnishd/storage_synth.c +++ b/bin/varnishd/storage_synth.c @@ -67,6 +67,7 @@ static struct stevedore sms_stevedore = { .magic = STEVEDORE_MAGIC, .name = "synth", .free = sms_free, + .dup = default_dup, }; struct vsb * diff --git a/bin/varnishd/storage_umem.c b/bin/varnishd/storage_umem.c index 6e28a94..474f809 100644 --- a/bin/varnishd/storage_umem.c +++ b/bin/varnishd/storage_umem.c @@ -163,6 +163,7 @@ const struct stevedore smu_stevedore = { .alloc = smu_alloc, .free = smu_free, .trim = smu_trim, + .dup = default_dup, }; #endif /* HAVE_UMEM_H */ diff --git a/include/vrt.h b/include/vrt.h index cfafe75..9d9ce16 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -159,7 +159,7 @@ int VRT_rewrite(const char *, const char *); void VRT_error(struct sess *, unsigned, const char *); int VRT_switch_config(const char *); -enum gethdr_e { HDR_REQ, HDR_RESP, HDR_OBJ, HDR_BEREQ, HDR_BERESP }; +enum gethdr_e { HDR_REQ, HDR_RESP, HDR_OBJ, HDR_STALE_OBJ, HDR_BEREQ, HDR_BERESP }; char *VRT_GetHdr(const struct sess *, enum gethdr_e where, const char *); void VRT_SetHdr(const struct sess *, enum gethdr_e where, const char *, const char *, ...); diff --git a/include/vsc_fields.h b/include/vsc_fields.h index 0289b81..534501a 100644 --- a/include/vsc_fields.h +++ b/include/vsc_fields.h @@ -155,6 +155,8 @@ VSC_F(vmods, uint64_t, 0, 'i', "Loaded VMODs") VSC_F(n_gzip, uint64_t, 0, 'a', "Gzip operations") VSC_F(n_gunzip, uint64_t, 0, 'a', "Gunzip operations") +VSC_F(cond_not_validated, uint64_t, 1, 'a', "Non-validating responses") + #endif /**********************************************************************/ diff --git a/lib/libvcl/generate.py b/lib/libvcl/generate.py index 5407a51..28375fa 100755 --- a/lib/libvcl/generate.py +++ b/lib/libvcl/generate.py @@ -427,6 +427,66 @@ sp_variables = ( ( ), 'const struct sess *' ), + ('stale_obj', + 'BOOL', + ( 'error', 'miss', 'fetch',), + ( ), + 'const struct sess *' + ), + ('stale_obj.proto', + 'STRING', + ( 'error', 'miss', 'fetch',), + ( ), + 'const struct sess *' + ), + ('stale_obj.status', + 'INT', + ( 'error', 'miss', 'fetch',), + ( ), + 'const struct sess *' + ), + ('stale_obj.response', + 'STRING', + ( 'error', 'miss', 'fetch',), + ( ), + 'const struct sess *' + ), + ('stale_obj.hits', + 'INT', + ( 'error', 'miss', 'fetch',), + ( ), + 'const struct sess *' + ), + ('stale_obj.http.', + 'HDR_STALE_OBJ', + ( 'error', 'miss', 'fetch',), + ( ), # XXX ? + 'const struct sess *' + ), + ('stale_obj.ttl', + 'DURATION', + ( 'error', 'miss', 'fetch',), + ( ), + 'struct sess *' + ), + ('stale_obj.grace', + 'DURATION', + ( 'error', 'miss', 'fetch',), + ( ), + 'struct sess *' + ), + ('stale_obj.lastuse', + 'DURATION', + ( 'error', 'miss', 'fetch',), + ( ), + 'const struct sess *' + ), + ('stale_obj.keep', + 'DURATION', + ( 'error', 'miss', 'fetch',), + ( ), + 'struct sess *' + ), ('resp.proto', 'STRING', ( 'deliver',), From geoff at varnish-cache.org Fri Jul 8 09:47:48 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:48 +0200 Subject: [experimental-ims] a343a0d Beef the gzip parameters up to the usual defaults: window=15 and memlevel 8. Message-ID: commit a343a0dad8bd4faa7ad46187f5914e5d4fefb852 Author: Poul-Henning Kamp Date: Wed Jun 22 14:48:57 2011 +0000 Beef the gzip parameters up to the usual defaults: window=15 and memlevel 8. Fix testcases which depend on older values. diff --git a/bin/varnishd/mgt_param.c b/bin/varnishd/mgt_param.c index 1b996e5..26fcb31 100644 --- a/bin/varnishd/mgt_param.c +++ b/bin/varnishd/mgt_param.c @@ -888,13 +888,15 @@ static const struct parspec input_parspec[] = { 0, "6", ""}, { "gzip_window", tweak_uint, &master.gzip_window, 8, 15, - "Gzip window size 8=least, 15=most compression", + "Gzip window size 8=least, 15=most compression.\n" + "Memory impact is 8=1k, 9=2k, ... 15=128k.", 0, - "8", ""}, - { "gzip_window", tweak_uint, &master.gzip_memlevel, 1, 9, - "Gzip memory level 1=least, 9=most compression", + "15", ""}, + { "gzip_memlevel", tweak_uint, &master.gzip_memlevel, 1, 9, + "Gzip memory level 1=slow/least, 9=fast/most compression.\n" + "Memory impact is 1=1k, 2=2k, ... 9=256k.", 0, - "1", ""}, + "8", ""}, { "gzip_stack_buffer", tweak_uint, &master.gzip_stack_buffer, 2048, UINT_MAX, "Size of stack buffer used for gzip processing.\n" diff --git a/bin/varnishtest/tests/e00022.vtc b/bin/varnishtest/tests/e00022.vtc index e402c5e..39302b4 100644 --- a/bin/varnishtest/tests/e00022.vtc +++ b/bin/varnishtest/tests/e00022.vtc @@ -26,6 +26,8 @@ varnish v1 -arg "-p sess_workspace=131072 -p thread_pool_stack=262144" -vcl+back varnish v1 -cliok "param.set esi_syntax 0xc" varnish v1 -cliok "param.set http_gzip_support true" varnish v1 -cliok "param.set gzip_tmp_space 1" +varnish v1 -cliok "param.set gzip_window 8" +varnish v1 -cliok "param.set gzip_memlevel 1" client c1 { txreq -hdr "Accept-Encoding: gzip" diff --git a/bin/varnishtest/tests/g00002.vtc b/bin/varnishtest/tests/g00002.vtc index 4d713c7..dba75ae 100644 --- a/bin/varnishtest/tests/g00002.vtc +++ b/bin/varnishtest/tests/g00002.vtc @@ -11,7 +11,10 @@ server s1 { txresp -body {

} } -start -varnish v1 -cliok "param.set http_gzip_support true" -vcl+backend { +varnish v1 \ + -cliok "param.set http_gzip_support true" \ + -cliok "param.set gzip_memlevel 1" \ + -vcl+backend { sub vcl_fetch { set beresp.do_esi = true; From geoff at varnish-cache.org Fri Jul 8 09:47:41 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:41 +0200 Subject: [experimental-ims] 4f59702 Optimize the objhead layout to avoid packing on 64bit systems. Message-ID: commit 4f59702c160b0456f2956938b777d86eab9031f4 Author: Poul-Henning Kamp Date: Mon Jun 20 08:09:48 2011 +0000 Optimize the objhead layout to avoid packing on 64bit systems. diff --git a/bin/varnishd/hash_slinger.h b/bin/varnishd/hash_slinger.h index b9430c7..2c142cf 100644 --- a/bin/varnishd/hash_slinger.h +++ b/bin/varnishd/hash_slinger.h @@ -75,8 +75,8 @@ struct objhead { unsigned magic; #define OBJHEAD_MAGIC 0x1b96615d - struct lock mtx; int refcnt; + struct lock mtx; VTAILQ_HEAD(,objcore) objcs; unsigned char digest[DIGEST_LEN]; struct waitinglist *waitinglist; From geoff at varnish-cache.org Fri Jul 8 09:47:54 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:54 +0200 Subject: [experimental-ims] ff52bbd Merge conditional backend requests with current trunk Message-ID: commit ff52bbd5888533f4255c57681608b6b3aab08100 Author: Geoff Simmons Date: Tue Jun 7 06:59:57 2011 +0200 Merge conditional backend requests with current trunk diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index 8515c5e..d80dd74 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -701,6 +701,7 @@ void EXP_Set_keep(struct exp *e, double v); double EXP_Ttl(const struct sess *, const struct object*); double EXP_Grace(const struct sess *, const struct object*); +double EXP_Keep(const struct sess *, const struct object*); void EXP_Insert(struct object *o); void EXP_Inject(struct objcore *oc, struct lru *lru, double when); void EXP_Init(void); diff --git a/bin/varnishd/cache_expire.c b/bin/varnishd/cache_expire.c index c0e79cc..5fc944a 100644 --- a/bin/varnishd/cache_expire.c +++ b/bin/varnishd/cache_expire.c @@ -97,7 +97,7 @@ EXP_ACCESS(keep, 0.,) * by per-session limits. */ -static double +double EXP_Keep(const struct sess *sp, const struct object *o) { double r; diff --git a/bin/varnishd/cache_http.c b/bin/varnishd/cache_http.c index f0e1756..0f1491e 100644 --- a/bin/varnishd/cache_http.c +++ b/bin/varnishd/cache_http.c @@ -66,11 +66,10 @@ static const enum VSL_tag_e logmtx[][HTTP_HDR_FIRST + 1] = { }; /*lint -restore */ -static enum VSL_tag_e - void http_FilterMissingFields(struct worker *w, int fd, struct http *to, const struct http *fm); +static enum VSL_tag_e http2shmlog(const struct http *hp, int t) { diff --git a/bin/varnishtest/tests/i00000.vtc b/bin/varnishtest/tests/i00000.vtc index 773e1e5..4c4aeb5 100644 --- a/bin/varnishtest/tests/i00000.vtc +++ b/bin/varnishtest/tests/i00000.vtc @@ -1,6 +1,6 @@ # $Id$ -test "VCL compiler coverage test: conditional refresh extension" +varnishtest "VCL compiler coverage test: conditional refresh extension" ## stale_obj is r/o in miss, fetch and error, illegal everywhere else diff --git a/bin/varnishtest/tests/i00001.vtc b/bin/varnishtest/tests/i00001.vtc index 488305f..306cc57 100644 --- a/bin/varnishtest/tests/i00001.vtc +++ b/bin/varnishtest/tests/i00001.vtc @@ -1,6 +1,6 @@ # $Id$ -test "Test basic conditional requests to backends" +varnishtest "Test basic conditional requests to backends" ## By default (default_keep = default_grace), cond. requests happen during grace diff --git a/bin/varnishtest/tests/i00002.vtc b/bin/varnishtest/tests/i00002.vtc index 3725532..adae568 100644 --- a/bin/varnishtest/tests/i00002.vtc +++ b/bin/varnishtest/tests/i00002.vtc @@ -1,6 +1,6 @@ # $Id$ -test "handling stale_obj in vcl_miss() and vcl_fetch()" +varnishtest "handling stale_obj in vcl_miss() and vcl_fetch()" server s1 { rxreq diff --git a/bin/varnishtest/tests/i00003.vtc b/bin/varnishtest/tests/i00003.vtc index 809b317..293e843 100644 --- a/bin/varnishtest/tests/i00003.vtc +++ b/bin/varnishtest/tests/i00003.vtc @@ -1,6 +1,6 @@ # $Id$ -test "Test some anticipated use cases for conditional backend requests" +varnishtest "Test some anticipated use cases for conditional backend requests" ## In vcl_miss(), it is possible to veto a conditional request by removing any ## If-Modified-Since or If-None-Match header. diff --git a/bin/varnishtest/tests/i00004.vtc b/bin/varnishtest/tests/i00004.vtc index 0943f98..bb70176 100644 --- a/bin/varnishtest/tests/i00004.vtc +++ b/bin/varnishtest/tests/i00004.vtc @@ -1,6 +1,6 @@ # $Id$ -test "Verify the semantics of keep (timeout for conditional requests)" +varnishtest "Verify the semantics of keep (timeout for conditional requests)" server s1 { rxreq diff --git a/bin/varnishtest/tests/i00005.vtc b/bin/varnishtest/tests/i00005.vtc index 0bcac4f..983afb2 100644 --- a/bin/varnishtest/tests/i00005.vtc +++ b/bin/varnishtest/tests/i00005.vtc @@ -1,6 +1,6 @@ # $Id$ -test "Verify interactions of ttl, keep, grace and bans" +varnishtest "Verify interactions of ttl, keep, grace and bans" ## Banned objects are not used for conditional requests diff --git a/bin/varnishtest/tests/i00006.vtc b/bin/varnishtest/tests/i00006.vtc index 87c6192..db15078 100644 --- a/bin/varnishtest/tests/i00006.vtc +++ b/bin/varnishtest/tests/i00006.vtc @@ -1,6 +1,6 @@ # $Id$ -test "Verify effects of ttl, keep and grace on expiration" +varnishtest "Verify effects of ttl, keep and grace on expiration" ## Verify that an object's lifetime in the cache is ## obj.ttl + max(obj.grace, obj.keep) diff --git a/bin/varnishtest/tests/i00007.vtc b/bin/varnishtest/tests/i00007.vtc index 487c0d0..4a9b8c0 100644 --- a/bin/varnishtest/tests/i00007.vtc +++ b/bin/varnishtest/tests/i00007.vtc @@ -1,6 +1,6 @@ # $Id$ -test "Passes through responses to backend conditionals to the client if status != 304 or 200" +varnishtest "Passes through responses to backend conditionals to the client if status != 304 or 200" # Testing a sample from each of the Nxx status codes From geoff at varnish-cache.org Fri Jul 8 09:47:50 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:50 +0200 Subject: [experimental-ims] 85f39f0 Explain what a purge is. Message-ID: commit 85f39f0d4dfb1e351e19095688e387416de172b5 Author: Per Buer Date: Thu Jun 30 10:18:36 2011 +0200 Explain what a purge is. diff --git a/doc/sphinx/tutorial/purging.rst b/doc/sphinx/tutorial/purging.rst index bd00e49..284080a 100644 --- a/doc/sphinx/tutorial/purging.rst +++ b/doc/sphinx/tutorial/purging.rst @@ -17,6 +17,10 @@ bans. First, let me explain the HTTP purges. HTTP Purges =========== +A *purge* is what happens when you pick out an object from the cache +and discard it along with its variants. Usually a purge is invoked +through HTTP with the method PURGE. + An HTTP purge is similar to an HTTP GET request, except that the *method* is PURGE. Actually you can call the method whatever you'd like, but most people refer to this as purging. Squid supports the From geoff at varnish-cache.org Fri Jul 8 09:47:48 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:48 +0200 Subject: [experimental-ims] ca5fe96 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache Message-ID: commit ca5fe96964088e3ff44df22ea678a7700ac3a762 Merge: 8f85e38 403a361 Author: Poul-Henning Kamp Date: Wed Jun 22 11:00:50 2011 +0000 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache From geoff at varnish-cache.org Fri Jul 8 09:47:49 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:49 +0200 Subject: [experimental-ims] 9cc19dd Introduce the "busyobj" structure which is only valid for busy objects. Message-ID: commit 9cc19dd79740f6788cae2c4fed590e05523bb84b Author: Poul-Henning Kamp Date: Mon Jun 27 12:11:41 2011 +0000 Introduce the "busyobj" structure which is only valid for busy objects. Use it to hold the derived vary string for the request (if any) and skip busy objects with non-matching Vary during hash lookup. Idea by: sky diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index eb7077c..a875071 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -97,6 +97,7 @@ struct director; struct object; struct objhead; struct objcore; +struct busyobj; struct storage; struct workreq; struct vrt_backend; @@ -281,6 +282,7 @@ struct worker { struct objhead *nobjhead; struct objcore *nobjcore; struct waitinglist *nwaitinglist; + struct busyobj *nbusyobj; void *nhashpriv; struct dstat stats; @@ -416,6 +418,7 @@ struct objcore { void *priv; unsigned priv2; struct objhead *objhead; + struct busyobj *busyobj; double timer_when; unsigned flags; #define OC_F_BUSY (1<<1) @@ -470,7 +473,16 @@ oc_getlru(const struct objcore *oc) return (oc->methods->getlru(oc)); } +/* Busy Object structure ---------------------------------------------*/ + +struct busyobj { + unsigned magic; +#define BUSYOBJ_MAGIC 0x23b95567 + uint8_t *vary; +}; + /* Object structure --------------------------------------------------*/ + VTAILQ_HEAD(storagehead, storage); struct object { diff --git a/bin/varnishd/cache_hash.c b/bin/varnishd/cache_hash.c index d5c5ebe..6fdff15 100644 --- a/bin/varnishd/cache_hash.c +++ b/bin/varnishd/cache_hash.c @@ -111,6 +111,11 @@ HSH_Prealloc(const struct sess *sp) } CHECK_OBJ_NOTNULL(w->nwaitinglist, WAITINGLIST_MAGIC); + if (w->nbusyobj == NULL) { + ALLOC_OBJ(w->nbusyobj, BUSYOBJ_MAGIC); + XXXAN(w->nbusyobj); + } + if (hash->prep != NULL) hash->prep(sp); } @@ -342,8 +347,15 @@ HSH_Lookup(struct sess *sp, struct objhead **poh) assert(oc->objhead == oh); if (oc->flags & OC_F_BUSY) { - if (!sp->hash_ignore_busy) - busy_oc = oc; + CHECK_OBJ_NOTNULL(oc->busyobj, BUSYOBJ_MAGIC); + if (sp->hash_ignore_busy) + continue; + + if (oc->busyobj->vary != NULL && + !VRY_Match(sp, oc->busyobj->vary)) + continue; + + busy_oc = oc; continue; } @@ -445,6 +457,10 @@ HSH_Lookup(struct sess *sp, struct objhead **poh) AN(oc->flags & OC_F_BUSY); oc->refcnt = 1; + w->nbusyobj->vary = sp->vary_b; + oc->busyobj = w->nbusyobj; + w->nbusyobj = NULL; + /* * Busy objects go on the tail, so they will not trip up searches. * HSH_Unbusy() will move them to the front. @@ -609,6 +625,9 @@ HSH_Unbusy(const struct sess *sp) VTAILQ_REMOVE(&oh->objcs, oc, list); VTAILQ_INSERT_HEAD(&oh->objcs, oc, list); oc->flags &= ~OC_F_BUSY; + AZ(sp->wrk->nbusyobj); + sp->wrk->nbusyobj = oc->busyobj; + oc->busyobj = NULL; hsh_rush(oh); AN(oc->ban); Lck_Unlock(&oh->mtx); diff --git a/bin/varnishtest/tests/c00043.vtc b/bin/varnishtest/tests/c00043.vtc new file mode 100644 index 0000000..46cc4e1 --- /dev/null +++ b/bin/varnishtest/tests/c00043.vtc @@ -0,0 +1,44 @@ +varnishtest "predictive vary" + + +server s1 { + rxreq + txresp -hdr "Vary: foo" -bodylen 1 + rxreq + sema r2 sync 2 + sema r1 sync 2 + txresp -hdr "Vary: foo" -bodylen 2 +} -start + +server s2 { + rxreq + txresp -hdr "Vary: foo" -bodylen 3 +} -start + +varnish v1 -vcl+backend { + sub vcl_recv { + if (req.http.bar) { + set req.backend = s2; + } + } +} -start + +client c1 { + txreq -hdr "Foo: vary1" + rxresp + expect resp.bodylen == 1 + txreq -hdr "Foo: vary2" + rxresp + expect resp.bodylen == 2 +} -start + +client c2 { + sema r2 sync 2 + txreq -hdr "Foo: vary3" -hdr "bar: yes" + rxresp + sema r1 sync 2 + expect resp.bodylen == 3 +} -start + +client c1 -wait +client c2 -wait From geoff at varnish-cache.org Fri Jul 8 09:47:43 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:43 +0200 Subject: [experimental-ims] 2d7d3c8 Pack struct ws better to avoid padding. Message-ID: commit 2d7d3c8610d1507a976576f9ed9e3c880cff8b6f Author: Poul-Henning Kamp Date: Mon Jun 20 09:16:20 2011 +0000 Pack struct ws better to avoid padding. Repack struct object, reducing a couple of field widths along the way. This shaves 16 bytes of struct object. diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index 48d1456..f8dedb1 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -143,12 +143,12 @@ enum step { struct ws { unsigned magic; #define WS_MAGIC 0x35fac554 + unsigned overflow; /* workspace overflowed */ const char *id; /* identity */ char *s; /* (S)tart of buffer */ char *f; /* (F)ree pointer */ char *r; /* (R)eserved length */ char *e; /* (E)nd of buffer */ - int overflow; /* workspace overflowed */ }; /*-------------------------------------------------------------------- @@ -479,12 +479,13 @@ struct object { struct objcore *objcore; struct ws ws_o[1]; - unsigned char *vary; - unsigned response; + uint8_t *vary; + unsigned hits; + uint16_t response; /* XXX: make bitmap */ - unsigned gziped; + uint8_t gziped; /* Bit positions in the gzip stream */ ssize_t gzip_start; ssize_t gzip_last; @@ -507,7 +508,6 @@ struct object { double last_use; - int hits; }; /* -------------------------------------------------------------------*/ @@ -566,7 +566,7 @@ struct sess { unsigned handling; unsigned char sendbody; unsigned char wantbody; - int err_code; + uint16_t err_code; const char *err_reason; VTAILQ_ENTRY(sess) list; diff --git a/bin/varnishd/cache_cli.c b/bin/varnishd/cache_cli.c index 387dffb..2d3066c 100644 --- a/bin/varnishd/cache_cli.c +++ b/bin/varnishd/cache_cli.c @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -124,7 +125,7 @@ cli_debug_sizeof(struct cli *cli, const char * const *av, void *priv) (void)priv; #define SZOF(foo) VCLI_Out(cli, \ - "sizeof(%s) = %zd = 0x%zx\n", #foo, sizeof(foo), sizeof(foo)); + "sizeof(%s) = %zd = 0x%zx\n", #foo, sizeof(foo), sizeof(foo)) SZOF(struct ws); SZOF(struct http); SZOF(struct http_conn); @@ -139,6 +140,63 @@ cli_debug_sizeof(struct cli *cli, const char * const *av, void *priv) SZOF(struct vbc); SZOF(struct VSC_C_main); SZOF(struct lock); +#define OFOF(foo, bar) { foo __foo; VCLI_Out(cli, \ + "%-30s = 0x%4zx @ 0x%4zx\n", \ + #foo "." #bar, sizeof(__foo.bar), offsetof(foo, bar)); } +#if 0 + OFOF(struct objhead, magic); + OFOF(struct objhead, refcnt); + OFOF(struct objhead, mtx); + OFOF(struct objhead, objcs); + OFOF(struct objhead, digest); + OFOF(struct objhead, waitinglist); + OFOF(struct objhead, _u); +#endif +#if 0 + OFOF(struct http, magic); + OFOF(struct http, logtag); + OFOF(struct http, ws); + OFOF(struct http, hd); + OFOF(struct http, hdf); + OFOF(struct http, shd); + OFOF(struct http, nhd); + OFOF(struct http, status); + OFOF(struct http, protover); + OFOF(struct http, conds); +#endif +#if 0 + OFOF(struct storage, magic); + OFOF(struct storage, fd); + OFOF(struct storage, where); + OFOF(struct storage, list); + OFOF(struct storage, stevedore); + OFOF(struct storage, priv); + OFOF(struct storage, ptr); + OFOF(struct storage, len); + OFOF(struct storage, space); +#endif + OFOF(struct object, magic); + OFOF(struct object, xid); + OFOF(struct object, objstore); + OFOF(struct object, objcore); + OFOF(struct object, ws_o); + OFOF(struct object, vary); + OFOF(struct object, hits); + OFOF(struct object, response); + OFOF(struct object, gziped); + OFOF(struct object, gzip_start); + OFOF(struct object, gzip_last); + OFOF(struct object, gzip_stop); + OFOF(struct object, len); + OFOF(struct object, age); + OFOF(struct object, entered); + OFOF(struct object, exp); + OFOF(struct object, last_modified); + OFOF(struct object, last_lru); + OFOF(struct object, http); + OFOF(struct object, store); + OFOF(struct object, esidata); + OFOF(struct object, last_use); } /*--------------------------------------------------------------------*/ From geoff at varnish-cache.org Fri Jul 8 09:47:50 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:50 +0200 Subject: [experimental-ims] 91023bb obj and beresp.cacheable are gone Message-ID: commit 91023bb8dca3d8dba6ec4799be4256fcef83ed12 Author: Per Buer Date: Wed Jun 29 23:14:22 2011 +0200 obj and beresp.cacheable are gone diff --git a/doc/sphinx/reference/vcl.rst b/doc/sphinx/reference/vcl.rst index 8861404..b9aaddc 100644 --- a/doc/sphinx/reference/vcl.rst +++ b/doc/sphinx/reference/vcl.rst @@ -681,15 +681,6 @@ beresp.status beresp.response The HTTP status message returned by the server. -beresp.cacheable - True if the request resulted in a cacheable response. A response is - considered cacheable if HTTP status code is 200, 203, 300, 301, 302, - 404 or 410 and pass wasn't called in vcl_recv. If however, both the - TTL and the grace time for the response are 0 beresp.cacheable will - be 0. - - beresp.cacheable is writable. - beresp.ttl The object's remaining time to live, in seconds. beresp.ttl is writable. @@ -706,10 +697,6 @@ obj.status obj.response The HTTP status message returned by the server. -obj.cacheable - True if the object had beresp.cacheable. Unless you've forced delivery - in your VCL obj.cacheable will always be true. - obj.ttl The object's remaining time to live, in seconds. obj.ttl is writable. From geoff at varnish-cache.org Fri Jul 8 09:47:44 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:44 +0200 Subject: [experimental-ims] 0f354ac Use VCT instead of . Trust HTTP_GetHdr() to remove leading white space. Message-ID: commit 0f354aca14c7ee41c22ba8f56ff43d7ba5e7e443 Author: Poul-Henning Kamp Date: Tue Jun 21 09:46:35 2011 +0000 Use VCT instead of . Trust HTTP_GetHdr() to remove leading white space. diff --git a/bin/varnishd/cache_vary.c b/bin/varnishd/cache_vary.c index c8578d1..8eab103 100644 --- a/bin/varnishd/cache_vary.c +++ b/bin/varnishd/cache_vary.c @@ -54,11 +54,11 @@ #include "config.h" -#include #include #include #include "cache.h" +#include "vct.h" struct vsb * VRY_Create(const struct sess *sp, const struct http *hp) @@ -86,9 +86,9 @@ VRY_Create(const struct sess *sp, const struct http *hp) for (p = v; *p; p++) { /* Find next header-name */ - if (isspace(*p)) + if (vct_issp(*p)) continue; - for (q = p; *q && !isspace(*q) && *q != ','; q++) + for (q = p; *q && !vct_issp(*q) && *q != ','; q++) continue; /* Build a header-matching string out of it */ @@ -98,11 +98,10 @@ VRY_Create(const struct sess *sp, const struct http *hp) AZ(VSB_finish(sbh)); if (http_GetHdr(sp->http, VSB_data(sbh), &h)) { - /* Trim leading and trailing space */ - while (isspace(*h)) - h++; + AZ(vct_issp(*h)); + /* Trim trailing space */ e = strchr(h, '\0'); - while (e > h && isspace(e[-1])) + while (e > h && vct_issp(e[-1])) e--; /* Encode two byte length and contents */ l = e - h; @@ -117,7 +116,7 @@ VRY_Create(const struct sess *sp, const struct http *hp) if (e != h) VSB_bcat(sb, h, e - h); - while (isspace(*q)) + while (vct_issp(*q)) q++; if (*q == '\0') break; @@ -175,11 +174,9 @@ VRY_Match(const struct sess *sp, const uint8_t *vary) if (!i) continue; - /* Trim leading & trailing space */ - while (isspace(*h)) - h++; + /* Trim trailing space */ e = strchr(h, '\0'); - while (e > h && isspace(e[-1])) + while (e > h && vct_issp(e[-1])) e--; /* Fail if wrong length */ From geoff at varnish-cache.org Fri Jul 8 09:47:42 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:42 +0200 Subject: [experimental-ims] 0b4c694 reduce some fieldwidths and pack struct http to avoid packing. Message-ID: commit 0b4c69419a603a7dadf87e82c5a98e78724ccfb6 Author: Poul-Henning Kamp Date: Mon Jun 20 08:39:17 2011 +0000 reduce some fieldwidths and pack struct http to avoid packing. diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index 0fe1271..48d1456 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -166,18 +166,17 @@ struct http { unsigned magic; #define HTTP_MAGIC 0x6428b5c9 - struct ws *ws; - - unsigned char conds; /* If-* headers present */ enum httpwhence logtag; - int status; - uint8_t protover; - unsigned shd; /* Size of hd space */ + struct ws *ws; txt *hd; unsigned char *hdf; #define HDF_FILTER (1 << 0) /* Filtered by Connection */ - unsigned nhd; /* Next free hd */ + uint16_t shd; /* Size of hd space */ + uint16_t nhd; /* Next free hd */ + uint16_t status; + uint8_t protover; + uint8_t conds; /* If-* headers present */ }; /*-------------------------------------------------------------------- From geoff at varnish-cache.org Fri Jul 8 09:47:42 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:42 +0200 Subject: [experimental-ims] 2f535f8 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache Message-ID: commit 2f535f8061ba7357c18da0f5f63af912563720be Merge: 0b4c694 78df00d Author: Poul-Henning Kamp Date: Mon Jun 20 08:39:44 2011 +0000 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache From geoff at varnish-cache.org Fri Jul 8 09:47:54 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:54 +0200 Subject: [experimental-ims] e1406a8 Resolves conflict between 90b7074b4cad090743f5a9797007ab448fa95a39 (fix #941) and experimental-ims experimental-ims needs left- and right-side macros/functions for updating timeouts in cache_vrt_var.c since stale_obj is read-only Message-ID: commit e1406a833de77d1088ea596c57749ebf4ad5a47b Merge: ff52bbd cd23977 Author: Geoff Simmons Date: Fri Jul 8 11:43:54 2011 +0200 Resolves conflict between 90b7074b4cad090743f5a9797007ab448fa95a39 (fix #941) and experimental-ims experimental-ims needs left- and right-side macros/functions for updating timeouts in cache_vrt_var.c since stale_obj is read-only Conflicts: bin/varnishd/cache_vrt_var.c From geoff at varnish-cache.org Fri Jul 8 09:47:43 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:43 +0200 Subject: [experimental-ims] 749b6d6 ifdef offsetoff output in debug.sizeof Message-ID: commit 749b6d683871778c36c874a5e0b2515a3530b405 Author: Poul-Henning Kamp Date: Mon Jun 20 09:28:41 2011 +0000 ifdef offsetoff output in debug.sizeof diff --git a/bin/varnishd/cache_cli.c b/bin/varnishd/cache_cli.c index 2d3066c..60e63bf 100644 --- a/bin/varnishd/cache_cli.c +++ b/bin/varnishd/cache_cli.c @@ -175,6 +175,7 @@ cli_debug_sizeof(struct cli *cli, const char * const *av, void *priv) OFOF(struct storage, len); OFOF(struct storage, space); #endif +#if 0 OFOF(struct object, magic); OFOF(struct object, xid); OFOF(struct object, objstore); @@ -197,6 +198,7 @@ cli_debug_sizeof(struct cli *cli, const char * const *av, void *priv) OFOF(struct object, store); OFOF(struct object, esidata); OFOF(struct object, last_use); +#endif } /*--------------------------------------------------------------------*/ From geoff at varnish-cache.org Fri Jul 8 09:47:41 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:41 +0200 Subject: [experimental-ims] 78df00d Use file locking on SHMFILE to indicate this file is currently in use Message-ID: commit 78df00d176c2cc323b4a66024aac2087a09a9e0b Author: Martin Blix Grydeland Date: Tue Jun 14 13:09:56 2011 +0200 Use file locking on SHMFILE to indicate this file is currently in use Fixes: #876 diff --git a/bin/varnishd/mgt_shmem.c b/bin/varnishd/mgt_shmem.c index f28bc9b..4fc905c 100644 --- a/bin/varnishd/mgt_shmem.c +++ b/bin/varnishd/mgt_shmem.c @@ -101,6 +101,7 @@ #include "heritage.h" #include "vmb.h" #include "vsm.h" +#include "flopen.h" #ifndef MAP_HASSEMAPHORE #define MAP_HASSEMAPHORE 0 /* XXX Linux */ @@ -125,11 +126,24 @@ vsl_n_check(int fd) struct VSM_head slh; int i; struct stat st; + pid_t pid; AZ(fstat(fd, &st)); if (!S_ISREG(st.st_mode)) ARGV_ERR("\tshmlog: Not a file\n"); + /* Test if the SHMFILE is locked by other Varnish */ + if (fltest(fd, &pid) > 0) { + fprintf(stderr, + "SHMFILE locked by running varnishd master (pid=%jd)\n", + (intmax_t)pid); + fprintf(stderr, + "(Use unique -n arguments if you want multiple " + "instances)\n"); + exit(2); + } + + /* Read owning pid from SHMFILE */ memset(&slh, 0, sizeof slh); /* XXX: for flexelint */ i = read(fd, &slh, sizeof slh); if (i != sizeof slh) @@ -138,15 +152,11 @@ vsl_n_check(int fd) return; if (slh.hdrsize != sizeof slh) return; - if (slh.master_pid != 0 && !kill(slh.master_pid, 0)) { - fprintf(stderr, - "SHMFILE owned by running varnishd master (pid=%jd)\n", - (intmax_t)slh.master_pid); - fprintf(stderr, - "(Use unique -n arguments if you want multiple " - "instances.)\n"); - exit(2); + fprintf(stderr, + "WARNING: Taking over SHMFILE marked as owned by " + "running process (pid=%jd)\n", + (intmax_t)slh.master_pid); } } @@ -161,15 +171,20 @@ vsl_buildnew(const char *fn, unsigned size, int fill) int i; unsigned u; char buf[64*1024]; + int flags; (void)unlink(fn); - vsl_fd = open(fn, O_RDWR | O_CREAT | O_EXCL, 0644); + vsl_fd = flopen(fn, O_RDWR | O_CREAT | O_EXCL | O_NONBLOCK, 0644); if (vsl_fd < 0) { fprintf(stderr, "Could not create %s: %s\n", fn, strerror(errno)); exit (1); } - + flags = fcntl(vsl_fd, F_GETFL); + assert(flags != -1); + flags &= ~O_NONBLOCK; + AZ(fcntl(vsl_fd, F_SETFL, flags)); + memset(&slh, 0, sizeof slh); slh.magic = VSM_HEAD_MAGIC; slh.hdrsize = sizeof slh; @@ -277,7 +292,6 @@ mgt_SHM_Init(const char *l_arg) vsl_n_check(i); (void)close(i); } - (void)close(i); vsl_buildnew(VSM_FILENAME, size, fill); VSM_head = (void *)mmap(NULL, size, diff --git a/include/flopen.h b/include/flopen.h index 4bd0209..e5b6030 100644 --- a/include/flopen.h +++ b/include/flopen.h @@ -31,6 +31,9 @@ #ifndef FLOPEN_H_INCLUDED #define FLOPEN_H_INCLUDED +#include + int flopen(const char *, int, ...); +int fltest(int fd, pid_t *pid); #endif diff --git a/lib/libvarnish/flopen.c b/lib/libvarnish/flopen.c index 43882fe..483d8d6 100644 --- a/lib/libvarnish/flopen.c +++ b/lib/libvarnish/flopen.c @@ -107,3 +107,27 @@ flopen(const char *path, int flags, ...) return (fd); } } + +/* Tests if the given fd is locked through flopen + * If pid is non-NULL, stores the pid of the process holding the lock there + * Returns 1 if the file is locked + * Returns 0 if the file is unlocked + * Returns -1 on error (and errno) + */ +int +fltest(int fd, pid_t *pid) +{ + struct flock lock; + + memset(&lock, 0, sizeof lock); + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + + if (fcntl(fd, F_GETLK, &lock) == -1) + return (-1); + if (lock.l_type == F_UNLCK) + return (0); + if (pid != NULL) + *pid = lock.l_pid; + return (1); +} From geoff at varnish-cache.org Fri Jul 8 09:47:48 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:48 +0200 Subject: [experimental-ims] 2b56653 Minor doc fixup Message-ID: commit 2b566531d08e68027fd4ae3709d3aebd26e07c71 Author: Tollef Fog Heen Date: Mon Jun 27 09:54:28 2011 +0200 Minor doc fixup diff --git a/doc/sphinx/reference/vcl.rst b/doc/sphinx/reference/vcl.rst index d0d9d39..8861404 100644 --- a/doc/sphinx/reference/vcl.rst +++ b/doc/sphinx/reference/vcl.rst @@ -897,10 +897,10 @@ SEE ALSO HISTORY ======= -The VCL language was developed by Poul-Henning Kamp in cooperation -with Verdens Gang AS, Varnish Software AS and Varnish Software. This manual -page was written by Dag-Erling Sm?rgrav and later edited by -Poul-Henning Kamp and Per Buer. +VCL was developed by Poul-Henning Kamp in cooperation with Verdens +Gang AS, Redpill Linpro and Varnish Software. This manual page was +written by Dag-Erling Sm?rgrav and later edited by Poul-Henning Kamp +and Per Buer. COPYRIGHT ========= From geoff at varnish-cache.org Fri Jul 8 09:47:48 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:48 +0200 Subject: [experimental-ims] bd96df2 Make all three gzip parameter varnish parameters: gzip_level, gzip_window and gzip_memlevel. Message-ID: commit bd96df29180f52ccdc399feff9659dd03477d11c Author: Poul-Henning Kamp Date: Wed Jun 22 14:28:36 2011 +0000 Make all three gzip parameter varnish parameters: gzip_level, gzip_window and gzip_memlevel. Still same pessimal values though. diff --git a/bin/varnishd/cache_gzip.c b/bin/varnishd/cache_gzip.c index e9ae902..f320a0a 100644 --- a/bin/varnishd/cache_gzip.c +++ b/bin/varnishd/cache_gzip.c @@ -202,8 +202,8 @@ VGZ_NewGzip(struct sess *sp, const char *id) i = deflateInit2(&vg->vz, params->gzip_level, /* Level */ Z_DEFLATED, /* Method */ - 16 + 8, /* Window bits (16=gzip + 15) */ - 1, /* memLevel */ + 16 + params->gzip_window, /* Window bits (16=gzip + 15) */ + params->gzip_memlevel, /* memLevel */ Z_DEFAULT_STRATEGY); if (i != Z_OK) printf("deflateInit2() = %d\n", i); diff --git a/bin/varnishd/heritage.h b/bin/varnishd/heritage.h index 16828ed..084d5dc 100644 --- a/bin/varnishd/heritage.h +++ b/bin/varnishd/heritage.h @@ -204,6 +204,8 @@ struct params { unsigned gzip_stack_buffer; unsigned gzip_tmp_space; unsigned gzip_level; + unsigned gzip_window; + unsigned gzip_memlevel; double critbit_cooloff; diff --git a/bin/varnishd/mgt_param.c b/bin/varnishd/mgt_param.c index 1caa563..1b996e5 100644 --- a/bin/varnishd/mgt_param.c +++ b/bin/varnishd/mgt_param.c @@ -887,6 +887,14 @@ static const struct parspec input_parspec[] = { "Gzip compression level: 0=debug, 1=fast, 9=best", 0, "6", ""}, + { "gzip_window", tweak_uint, &master.gzip_window, 8, 15, + "Gzip window size 8=least, 15=most compression", + 0, + "8", ""}, + { "gzip_window", tweak_uint, &master.gzip_memlevel, 1, 9, + "Gzip memory level 1=least, 9=most compression", + 0, + "1", ""}, { "gzip_stack_buffer", tweak_uint, &master.gzip_stack_buffer, 2048, UINT_MAX, "Size of stack buffer used for gzip processing.\n" From geoff at varnish-cache.org Fri Jul 8 09:47:49 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:49 +0200 Subject: [experimental-ims] 4b3da05 Fix up varnishlog matching example Message-ID: commit 4b3da0568508ed00d046b93bc77c44111d65ca28 Author: Tollef Fog Heen Date: Mon Jun 27 10:00:03 2011 +0200 Fix up varnishlog matching example diff --git a/doc/sphinx/reference/varnishlog.rst b/doc/sphinx/reference/varnishlog.rst index 8f67765..c0d73c9 100644 --- a/doc/sphinx/reference/varnishlog.rst +++ b/doc/sphinx/reference/varnishlog.rst @@ -149,7 +149,7 @@ The following command line simply copies all log entries to a log file::: The following command line reads that same log file and displays requests for the front page::: - $ varnishlog -r /var/log/varnish.log -c -o RxURL '^/$' + $ varnishlog -r /var/log/varnish.log -c -m 'RxURL:^/$' SEE ALSO ======== From geoff at varnish-cache.org Fri Jul 8 09:47:49 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:49 +0200 Subject: [experimental-ims] 6c51567 Enforce that oc_getobj() does not work on BUSY objcores. Message-ID: commit 6c51567a2724a8da62b3e2af8845e39aeb3d335f Author: Poul-Henning Kamp Date: Mon Jun 27 11:12:42 2011 +0000 Enforce that oc_getobj() does not work on BUSY objcores. diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index 1d3db55..eb7077c 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -434,6 +434,7 @@ oc_getobj(struct worker *wrk, struct objcore *oc) { CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); + AZ(oc->flags & OC_F_BUSY); AN(oc->methods); AN(oc->methods->getobj); return (oc->methods->getobj(wrk, oc)); diff --git a/bin/varnishd/cache_hash.c b/bin/varnishd/cache_hash.c index 2a6dcc5..d5c5ebe 100644 --- a/bin/varnishd/cache_hash.c +++ b/bin/varnishd/cache_hash.c @@ -594,7 +594,6 @@ HSH_Unbusy(const struct sess *sp) AssertObjBusy(o); AN(oc->ban); - assert(oc_getobj(sp->wrk, oc) == o); assert(oc->refcnt > 0); assert(oh->refcnt > 0); if (o->ws_o->overflow) @@ -613,6 +612,7 @@ HSH_Unbusy(const struct sess *sp) hsh_rush(oh); AN(oc->ban); Lck_Unlock(&oh->mtx); + assert(oc_getobj(sp->wrk, oc) == o); } void From geoff at varnish-cache.org Fri Jul 8 09:47:42 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:42 +0200 Subject: [experimental-ims] 0d276b4 Reduce the http.protover field from double to uint8_t for space reasons. Message-ID: commit 0d276b43db1baf703519d907a80a4b98ab73e874 Author: Poul-Henning Kamp Date: Mon Jun 20 08:33:35 2011 +0000 Reduce the http.protover field from double to uint8_t for space reasons. diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index f3558ff..0fe1271 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -171,7 +171,7 @@ struct http { unsigned char conds; /* If-* headers present */ enum httpwhence logtag; int status; - double protover; + uint8_t protover; unsigned shd; /* Size of hd space */ txt *hd; diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index 4375344..4a17c56 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -200,7 +200,7 @@ cnt_prepresp(struct sess *sp) sp->wrk->res_mode |= RES_LEN; else if (!sp->wantbody) { /* Nothing */ - } else if (sp->http->protover >= 1.1) { + } else if (sp->http->protover >= 11) { sp->wrk->res_mode |= RES_CHUNKED; } else { sp->wrk->res_mode |= RES_EOF; diff --git a/bin/varnishd/cache_http.c b/bin/varnishd/cache_http.c index 8df780a..5d8050a 100644 --- a/bin/varnishd/cache_http.c +++ b/bin/varnishd/cache_http.c @@ -420,7 +420,7 @@ http_DoConnection(const struct http *hp) unsigned u; if (!http_GetHdr(hp, H_Connection, &p)) { - if (hp->protover < 1.1) + if (hp->protover < 11) return ("not HTTP/1.1"); return (NULL); } @@ -640,11 +640,11 @@ http_ProtoVer(struct http *hp) { if (!strcasecmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.0")) - hp->protover = 1.0; + hp->protover = 10; else if (!strcasecmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.1")) - hp->protover = 1.1; + hp->protover = 11; else - hp->protover = 0.9; + hp->protover = 9; } diff --git a/bin/varnishd/rfc2616.c b/bin/varnishd/rfc2616.c index 83ebd71..7b2525f 100644 --- a/bin/varnishd/rfc2616.c +++ b/bin/varnishd/rfc2616.c @@ -186,7 +186,7 @@ RFC2616_Body(const struct sess *sp) hp = sp->wrk->beresp; - if (hp->protover < 1.1 && !http_HdrIs(hp, H_Connection, "keep-alive")) + if (hp->protover < 11 && !http_HdrIs(hp, H_Connection, "keep-alive")) sp->wrk->do_close = 1; else if (http_HdrIs(hp, H_Connection, "close")) sp->wrk->do_close = 1; @@ -262,7 +262,7 @@ RFC2616_Body(const struct sess *sp) return (BS_EOF); } - if (hp->protover < 1.1) { + if (hp->protover < 11) { /* * With no Connection header, assume EOF. */ From geoff at varnish-cache.org Fri Jul 8 09:47:50 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:50 +0200 Subject: [experimental-ims] e1f1d8f do_stream Message-ID: commit e1f1d8f157eda6545b93161792f095615228a35d Author: Per Buer Date: Thu Jun 30 10:23:25 2011 +0200 do_stream diff --git a/doc/sphinx/reference/vcl.rst b/doc/sphinx/reference/vcl.rst index 4a88dd1..8ed308d 100644 --- a/doc/sphinx/reference/vcl.rst +++ b/doc/sphinx/reference/vcl.rst @@ -647,6 +647,12 @@ The following variables are available after the requested object has been retrieved from the backend, before it is entered into the cache. In other words, they are available in vcl_fetch: +beresp.do_stream + Deliver the object to the client directly without fetching the whole + object into varnish. If this request is pass'ed it will not be + stored in memory. As of Varnish Cache 3.0 the object will marked as busy + as it is delivered so only client can access the object. + beresp.do_esi Boolean. ESI-process the object after fetching it. Defaults to false. Set it to true to parse the object for ESI directives. From geoff at varnish-cache.org Fri Jul 8 09:47:38 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:38 +0200 Subject: [experimental-ims] a03c58d Pass priv2 member instead of objcore pointer, thats all we need. Message-ID: commit a03c58d40ecf4b656a2e41f5865b24b277c23505 Author: Poul-Henning Kamp Date: Mon Jun 20 07:38:19 2011 +0000 Pass priv2 member instead of objcore pointer, thats all we need. diff --git a/bin/varnishd/storage_persistent_silo.c b/bin/varnishd/storage_persistent_silo.c index d4ccf1e..a1eb98b 100644 --- a/bin/varnishd/storage_persistent_silo.c +++ b/bin/varnishd/storage_persistent_silo.c @@ -308,15 +308,13 @@ smp_close_seg(struct smp_sc *sc, struct smp_seg *sg) */ static struct smp_object * -smp_find_so(const struct smp_seg *sg, const struct objcore *oc) +smp_find_so(const struct smp_seg *sg, unsigned priv2) { struct smp_object *so; - unsigned smp_idx; - smp_idx = oc->priv2; - assert(smp_idx > 0); - assert(smp_idx <= sg->p.lobjlist); - so = &sg->objs[sg->p.lobjlist - smp_idx]; + assert(priv2 > 0); + assert(priv2 <= sg->p.lobjlist); + so = &sg->objs[sg->p.lobjlist - priv2]; return (so); } @@ -390,7 +388,7 @@ smp_oc_getobj(struct worker *wrk, struct objcore *oc) AZ(oc->flags & OC_F_NEEDFIXUP); CAST_OBJ_NOTNULL(sg, oc->priv, SMP_SEG_MAGIC); - so = smp_find_so(sg, oc); + so = smp_find_so(sg, oc->priv2); o = (void*)(sg->sc->base + so->ptr); /* @@ -456,7 +454,7 @@ smp_oc_updatemeta(struct objcore *oc) CAST_OBJ_NOTNULL(sg, oc->priv, SMP_SEG_MAGIC); CHECK_OBJ_NOTNULL(sg->sc, SMP_SC_MAGIC); - so = smp_find_so(sg, oc); + so = smp_find_so(sg, oc->priv2); mttl = EXP_Grace(NULL, o); @@ -481,7 +479,7 @@ smp_oc_freeobj(struct objcore *oc) CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); CAST_OBJ_NOTNULL(sg, oc->priv, SMP_SEG_MAGIC); - so = smp_find_so(sg, oc); + so = smp_find_so(sg, oc->priv2); Lck_Lock(&sg->sc->mtx); so->ttl = 0; From geoff at varnish-cache.org Fri Jul 8 09:47:47 2011 From: geoff at varnish-cache.org (Geoff Simmons) Date: Fri, 08 Jul 2011 11:47:47 +0200 Subject: [experimental-ims] 403a361 Don't force a rerun to save reference if we just ran it. Message-ID: commit 403a361928841ab66d52471f0a439480aa125a98 Author: Poul-Henning Kamp Date: Wed Jun 22 10:52:47 2011 +0000 Don't force a rerun to save reference if we just ran it. diff --git a/bin/varnishd/flint.sh b/bin/varnishd/flint.sh index d87fe66..690e445 100755 --- a/bin/varnishd/flint.sh +++ b/bin/varnishd/flint.sh @@ -1,5 +1,11 @@ #!/bin/sh +if [ "x$1" = "x-ok" -a -f _.fl ] ; then + echo "Saved as reference" + mv _.fl _.fl.old + exit 0 +fi + flexelint \ ../flint.lnt \ flint.lnt \ @@ -21,5 +27,6 @@ if [ -f _.fl.old ] ; then fi if [ "x$1" = "x-ok" ] ; then + echo "Saved as reference" mv _.fl _.fl.old fi From tfheen at varnish-cache.org Mon Jul 11 07:50:36 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Mon, 11 Jul 2011 09:50:36 +0200 Subject: [master] fe7e315 Print 0, not - for zero-byte replies Message-ID: commit fe7e315cb98ffdc2e4f510e43c7b54bc1af840c1 Author: Tollef Fog Heen Date: Mon Jul 11 09:50:09 2011 +0200 Print 0, not - for zero-byte replies Fixes: #949 diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index 89c1ee1..521d52e 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -546,7 +546,7 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, case 'b': /* %b */ - fprintf(fo, "%s", lp->df_b ? lp->df_b : "-"); + fprintf(fo, "%s", lp->df_b ? lp->df_b : "0"); break; case 'H': From martin at varnish-cache.org Mon Jul 11 07:55:48 2011 From: martin at varnish-cache.org (Martin Blix Grydeland) Date: Mon, 11 Jul 2011 09:55:48 +0200 Subject: [master] 3a0d628 Don't assert on sleep failure due to signals in VSL library (some utils expect to receive SIGHUP). Message-ID: commit 3a0d628c1e2dff4b7a15253739f7cecdff8ec19c Author: Martin Blix Grydeland Date: Fri Jul 8 16:30:06 2011 +0200 Don't assert on sleep failure due to signals in VSL library (some utils expect to receive SIGHUP). Fixes: #947 diff --git a/lib/libvarnishapi/vsl.c b/lib/libvarnishapi/vsl.c index 2b3b45e..4141c28 100644 --- a/lib/libvarnishapi/vsl.c +++ b/lib/libvarnishapi/vsl.c @@ -184,7 +184,7 @@ vsl_nextlog(struct vsl *vsl, uint32_t **pp) if (vsl->flags & F_NON_BLOCKING) return (-1); w += SLEEP_USEC; - AZ(usleep(SLEEP_USEC)); + assert(usleep(SLEEP_USEC) == 0 || errno == EINTR); continue; } *pp = (void*)(uintptr_t)vsl->log_ptr; /* Loose volatile */ From tfheen at varnish-cache.org Mon Jul 11 08:16:57 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Mon, 11 Jul 2011 10:16:57 +0200 Subject: [3.0] 9f2dcde obj and beresp.cacheable are gone Message-ID: commit 9f2dcdeade83e3755573923310e6e56265c22d55 Author: Per Buer Date: Wed Jun 29 23:14:22 2011 +0200 obj and beresp.cacheable are gone diff --git a/doc/sphinx/reference/vcl.rst b/doc/sphinx/reference/vcl.rst index 8861404..b9aaddc 100644 --- a/doc/sphinx/reference/vcl.rst +++ b/doc/sphinx/reference/vcl.rst @@ -681,15 +681,6 @@ beresp.status beresp.response The HTTP status message returned by the server. -beresp.cacheable - True if the request resulted in a cacheable response. A response is - considered cacheable if HTTP status code is 200, 203, 300, 301, 302, - 404 or 410 and pass wasn't called in vcl_recv. If however, both the - TTL and the grace time for the response are 0 beresp.cacheable will - be 0. - - beresp.cacheable is writable. - beresp.ttl The object's remaining time to live, in seconds. beresp.ttl is writable. @@ -706,10 +697,6 @@ obj.status obj.response The HTTP status message returned by the server. -obj.cacheable - True if the object had beresp.cacheable. Unless you've forced delivery - in your VCL obj.cacheable will always be true. - obj.ttl The object's remaining time to live, in seconds. obj.ttl is writable. From tfheen at varnish-cache.org Mon Jul 11 08:44:03 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Mon, 11 Jul 2011 10:44:03 +0200 Subject: [master] c11ac80 Avoid segfaulting if hitmiss or handling hasn't been set yet Message-ID: commit c11ac805b50dcf77aac5d4ba3d210207924250bf Author: Tollef Fog Heen Date: Mon Jul 11 10:14:40 2011 +0200 Avoid segfaulting if hitmiss or handling hasn't been set yet Fall back to "-" if the handling has not been decided yet. Fixes: #950 Fixes: #944 Fixes: #918 diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index 521d52e..969cc22 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -654,11 +654,11 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, p += 9+15; break; } else if (strncmp(what, "hitmiss}x", 9) == 0) { - fprintf(fo, "%s", lp->df_hitmiss); + fprintf(fo, "%s", (lp->df_hitmiss ? lp->df_hitmiss : "-")); p += 9+8; break; } else if (strncmp(what, "handling}x", 10) == 0) { - fprintf(fo, "%s", lp->df_handling); + fprintf(fo, "%s", (lp->df_handling ? lp->df_handling : "-")); p += 9+9; break; } From tfheen at varnish-cache.org Mon Jul 11 08:44:03 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Mon, 11 Jul 2011 10:44:03 +0200 Subject: [master] 17df9a6 Fix compilation errors (set-but-unused variables) Message-ID: commit 17df9a6a0656a4b11487d7b9c9fdafcadde0af91 Author: Tollef Fog Heen Date: Mon Jul 11 10:43:36 2011 +0200 Fix compilation errors (set-but-unused variables) Thanks to new GCC for spotting those. diff --git a/bin/varnishd/cache_response.c b/bin/varnishd/cache_response.c index f52eb4b..4788a23 100644 --- a/bin/varnishd/cache_response.c +++ b/bin/varnishd/cache_response.c @@ -265,6 +265,7 @@ res_WriteGunzipObj(struct sess *sp) st->ptr, st->len, obuf, sizeof obuf, &obufl); /* XXX: error check */ + (void)i; } if (obufl) { (void)WRW_Write(sp->wrk, obuf, obufl); diff --git a/bin/varnishreplay/varnishreplay.c b/bin/varnishreplay/varnishreplay.c index 71a9c81..f7355cb 100644 --- a/bin/varnishreplay/varnishreplay.c +++ b/bin/varnishreplay/varnishreplay.c @@ -494,7 +494,6 @@ replay_thread(void *arg) struct replay_thread *thr = arg; struct message *msg; enum VSL_tag_e tag; - size_t len; char *ptr; const char *next; @@ -504,7 +503,6 @@ replay_thread(void *arg) while ((msg = mailbox_get(&thr->mbox)) != NULL) { tag = msg->tag; - len = msg->len; ptr = msg->ptr; thread_log(2, 0, "%s(%s)", VSL_tags[tag], msg->ptr); @@ -639,14 +637,11 @@ gen_traffic(void *priv, enum VSL_tag_e tag, unsigned fd, unsigned len, unsigned spec, const char *ptr, uint64_t bitmap) { struct replay_thread *thr; - const char *end; struct message *msg; (void)priv; (void)bitmap; - end = ptr + len; - if (fd == 0 || !(spec & VSL_S_CLIENT)) return (0); From tfheen at varnish-cache.org Fri Jul 15 06:39:45 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Fri, 15 Jul 2011 08:39:45 +0200 Subject: [master] ba20513 Fix up syntax for matching in docs Message-ID: commit ba2051320e581c84026821ed3e86fa3681e294dc Author: Tollef Fog Heen Date: Fri Jul 15 08:39:37 2011 +0200 Fix up syntax for matching in docs diff --git a/doc/sphinx/faq/general.rst b/doc/sphinx/faq/general.rst index 12617f5..5a1fbac 100644 --- a/doc/sphinx/faq/general.rst +++ b/doc/sphinx/faq/general.rst @@ -86,13 +86,13 @@ The "varnishlog" utility may produce a horrendous amount of output. To be able The ReqStart token will include the client IP address. To see log entries matching this, type:: - $ varnishlog -c -o ReqStart 192.0.2.123 + $ varnishlog -c -m ReqStart:192.0.2.123 To see the backend requests generated by a client IP address, we can match on the TxHeader token, since the IP address of the client is included in the X-Forwarded-For header in the request sent to the backend. At the shell command line, type:: - $ varnishlog -b -o TxHeader 192.0.2.123 + $ varnishlog -b -m TxHeader:192.0.2.123 **How can I rewrite URLS before they are sent to the backend?** diff --git a/doc/sphinx/tutorial/troubleshooting.rst b/doc/sphinx/tutorial/troubleshooting.rst index aeb2786..7ab9435 100644 --- a/doc/sphinx/tutorial/troubleshooting.rst +++ b/doc/sphinx/tutorial/troubleshooting.rst @@ -80,13 +80,13 @@ give you a clue. Since varnishlog logs so much data it might be hard to track the entries down. You can set varnishlog to log all your 503 errors by issuing the following command::: - $ varnishlog -c -o TxStatus 503 + $ varnishlog -c -m TxStatus:503 If the error happened just a short time ago the transaction might still be in the shared memory log segment. To get varnishlog to process the whole shared memory log just add the -d option::: - $ varnishlog -d -c -o TxStatus 503 + $ varnishlog -d -c -m TxStatus:503 Please see the varnishlog man page for elaborations on further filtering capabilities and explanation of the various options. From tfheen at varnish-cache.org Fri Jul 15 06:42:17 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Fri, 15 Jul 2011 08:42:17 +0200 Subject: [master] 044141f Remove obsolete bits from varnishlog man page Message-ID: commit 044141f625258b661fdd9e29c3f7c24d1b6d115b Author: Tollef Fog Heen Date: Fri Jul 15 08:41:52 2011 +0200 Remove obsolete bits from varnishlog man page diff --git a/doc/sphinx/reference/varnishlog.rst b/doc/sphinx/reference/varnishlog.rst index c0d73c9..be9c9c5 100644 --- a/doc/sphinx/reference/varnishlog.rst +++ b/doc/sphinx/reference/varnishlog.rst @@ -81,10 +81,6 @@ The following options are available: -x tag Exclude log entries with the specified tag. -If the -o option was specified, an additional tag and regex may be -specified to select only requests which generated a log entry with the -given tag whose contents match the given regex. - TAGS ==== The following log entry tags are currently defined: From tfheen at varnish-cache.org Fri Jul 15 08:57:21 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Fri, 15 Jul 2011 10:57:21 +0200 Subject: [master] e6a9571 Use vsb for varnishncsa to prevent partial lines on error in format strings Message-ID: commit e6a9571a5810105939c330c53dd18cc5be7feb0e Author: Tollef Fog Heen Date: Fri Jul 15 09:02:05 2011 +0200 Use vsb for varnishncsa to prevent partial lines on error in format strings diff --git a/bin/varnishncsa/Makefile.am b/bin/varnishncsa/Makefile.am index f34a0e2..9b652da 100644 --- a/bin/varnishncsa/Makefile.am +++ b/bin/varnishncsa/Makefile.am @@ -13,6 +13,7 @@ varnishncsa_SOURCES = \ $(top_builddir)/lib/libvarnish/assert.c \ $(top_builddir)/lib/libvarnish/flopen.c \ $(top_builddir)/lib/libvarnish/version.c \ + $(top_builddir)/lib/libvarnish/vsb.c \ $(top_builddir)/lib/libvarnish/vpf.c varnishncsa_LDADD = \ diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index 969cc22..934fdf3 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -485,6 +485,7 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, FILE *fo = priv; char *q, tbuf[64]; const char *p; + struct vsb *os; if (fd >= nll) { struct logline **newll = ll; @@ -533,12 +534,12 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, /* We have a complete data set - log a line */ fo = priv; + os = VSB_new_auto(); for (p = format; *p != '\0'; p++) { - if (*p != '%') { - fprintf(fo, "%c", *p); + VSB_putc(os, *p); continue; } p++; @@ -546,29 +547,29 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, case 'b': /* %b */ - fprintf(fo, "%s", lp->df_b ? lp->df_b : "0"); + VSB_cat(os, lp->df_b ? lp->df_b : "0"); break; case 'H': - fprintf(fo, "%s", lp->df_H); + VSB_cat(os, lp->df_H); break; case 'h': if (!lp->df_h && spec & VSL_S_BACKEND) - fprintf(fo, "127.0.0.1"); + VSB_cat(os, "127.0.0.1"); else - fprintf(fo, "%s", lp->df_h ? lp->df_h : "-"); + VSB_cat(os, lp->df_h ? lp->df_h : "-"); break; case 'l': - fprintf(fo, "-"); + VSB_putc(os, '-'); break; case 'm': - fprintf(fo, "%s", lp->df_m); + VSB_cat(os, lp->df_m); break; case 'q': - fprintf(fo, "%s", lp->df_q ? lp->df_q : ""); + VSB_cat(os, lp->df_q ? lp->df_q : ""); break; case 'r': @@ -576,30 +577,32 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, * Fake "%r". This would be a lot easier if Varnish * normalized the request URL. */ - fprintf(fo, "%s ", lp->df_m); + VSB_cat(os, lp->df_m); + VSB_putc(os, ' '); if (lp->df_Host) { if (strncmp(lp->df_Host, "http://", 7) != 0) - fprintf(fo, "http://"); - fprintf(fo, "%s", lp->df_Host); + VSB_cat(os, "http://"); + VSB_cat(os, lp->df_Host); } - fprintf(fo, "%s", lp->df_U); - fprintf(fo, "%s ", lp->df_q ? lp->df_q : ""); - fprintf(fo, "%s", lp->df_H); + VSB_cat(os, lp->df_U); + VSB_cat(os, lp->df_q ? lp->df_q : ""); + VSB_putc(os, ' '); + VSB_cat(os, lp->df_H); break; case 's': /* %s */ - fprintf(fo, "%s", lp->df_s ? lp->df_s : ""); + VSB_cat(os, lp->df_s ? lp->df_s : ""); break; case 't': /* %t */ strftime(tbuf, sizeof tbuf, "[%d/%b/%Y:%T %z]", &lp->df_t); - fprintf(fo, "%s", tbuf); + VSB_cat(os, tbuf); break; case 'U': - fprintf(fo, "%s", lp->df_U); + VSB_cat(os, lp->df_U); break; case 'u': @@ -616,49 +619,45 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, q = strchr(rubuf, ':'); if (q != NULL) *q = '\0'; - fprintf(fo, "%s", rubuf); + VSB_cat(os, rubuf); free(rubuf); } else { - fprintf(fo, "-"); + VSB_putc(os, '-'); } break; case '{': if (strncmp(p, "{Referer}i", 10) == 0) { - fprintf(fo, "%s", - lp->df_Referer ? lp->df_Referer : "-"); + VSB_cat(os, lp->df_Referer ? lp->df_Referer : "-"); p += 9; break; } else if (strncmp(p, "{Host}i", 7) == 0) { - fprintf(fo, "%s", - lp->df_Host ? lp->df_Host : "-"); + VSB_cat(os, lp->df_Host ? lp->df_Host : "-"); p += 6; break; } else if (strncmp(p, "{X-Forwarded-For}i", 18) == 0) { /* %{Referer}i */ - fprintf(fo, "%s", - lp->df_X_Forwarded_For ? lp->df_X_Forwarded_For : "-"); + VSB_cat(os, lp->df_X_Forwarded_For ? lp->df_X_Forwarded_For : "-"); p += 17; break; } else if (strncmp(p, "{User-agent}i", 13) == 0) { /* %{User-agent}i */ - fprintf(fo, "%s", - lp->df_User_agent ? lp->df_User_agent : "-"); + VSB_cat(os, lp->df_User_agent ? lp->df_User_agent : "-"); p += 12; break; } else if (strncmp(p, "{Varnish:", 9) == 0) { /* Scan for what we're looking for */ const char *what = p+9; if (strncmp(what, "time_firstbyte}x", 16) == 0) { - fprintf(fo, "%s", lp->df_ttfb); + VSB_cat(os, lp->df_ttfb); p += 9+15; break; } else if (strncmp(what, "hitmiss}x", 9) == 0) { - fprintf(fo, "%s", (lp->df_hitmiss ? lp->df_hitmiss : "-")); + VSB_cat(os, (lp->df_hitmiss ? lp->df_hitmiss : "-")); p += 9+8; break; } else if (strncmp(what, "handling}x", 10) == 0) { - fprintf(fo, "%s", (lp->df_handling ? lp->df_handling : "-")); + VSB_cat(os, (lp->df_handling ? lp->df_handling : "-")); p += 9+9; break; } @@ -670,14 +669,16 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, exit(1); } } - fprintf(fo, "\n"); + VSB_putc(os, '\n'); /* flush the stream */ + VSB_finish(os); + fprintf(fo, "%s", VSB_data(os)); fflush(fo); /* clean up */ clean_logline(lp); - + VSB_delete(os); return (reopen); } From tfheen at varnish-cache.org Fri Jul 15 08:57:21 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Fri, 15 Jul 2011 10:57:21 +0200 Subject: [master] cbd2874 Handle errors in varnishncsa formats slightly better Message-ID: commit cbd2874256f2ce749e1cf8cbda989bb424bb6c39 Author: Tollef Fog Heen Date: Fri Jul 15 09:03:46 2011 +0200 Handle errors in varnishncsa formats slightly better Print out the rest of the format, changing the error from "Unknown format character: {" to: "Unknown format starting at: %{asdf}x" diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index 934fdf3..9178168 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -665,7 +665,7 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, /* Fall through if we haven't handled something */ /* FALLTHROUGH*/ default: - fprintf(stderr, "Unknown format character: %c\n", *p); + fprintf(stderr, "Unknown format starting at: %s\n", --p); exit(1); } } From tfheen at varnish-cache.org Fri Jul 15 08:57:21 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Fri, 15 Jul 2011 10:57:21 +0200 Subject: [master] 3e86cd8 Make it possible to log arbitrary headers in varnishncsa Message-ID: commit 3e86cd8d1e160613c1bcd5def787f4ba8196a9e3 Author: Tollef Fog Heen Date: Fri Jul 15 10:57:16 2011 +0200 Make it possible to log arbitrary headers in varnishncsa diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index 9178168..94c81ef 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -54,8 +54,7 @@ * %q Query string * %H Protocol version * - * TODO: - Make it possible to grab any request header - * - Maybe rotate/compress log + * TODO: - Maybe rotate/compress log */ #include "config.h" @@ -72,6 +71,7 @@ #include "vsb.h" #include "vpf.h" +#include "vqueue.h" #include "libvarnish.h" #include "vsl.h" @@ -81,14 +81,16 @@ static volatile sig_atomic_t reopen; +struct hdr { + char *key; + char *value; + VTAILQ_ENTRY(hdr) list; +}; + static struct logline { char *df_H; /* %H, Protocol version */ - char *df_Host; /* %{Host}i */ - char *df_Referer; /* %{Referer}i */ char *df_U; /* %U, URL path */ char *df_q; /* %q, query string */ - char *df_User_agent; /* %{User-agent}i */ - char *df_X_Forwarded_For; /* %{X-Forwarded-For}i */ char *df_b; /* %b, Bytes */ char *df_h; /* %h (host name / IP adress)*/ char *df_m; /* %m, Request method*/ @@ -101,6 +103,7 @@ static struct logline { int active; /* Is log line in an active trans */ int complete; /* Is log line complete */ uint64_t bitmap; /* Bitmap for regex matches */ + VTAILQ_HEAD(, hdr) headers; } **ll; struct VSM_data *vd; @@ -186,23 +189,39 @@ trimline(const char *str, const char *end) return (p); } +static char * +get_header(struct logline *l, const char *name) +{ + struct hdr *h; + VTAILQ_FOREACH(h, &l->headers, list) { + if (strcasecmp(h->key, name) == 0) { + return h->value; + break; + } + } + return NULL; +} + static void clean_logline(struct logline *lp) { + struct hdr *h, *h2; #define freez(x) do { if (x) free(x); x = NULL; } while (0); freez(lp->df_H); - freez(lp->df_Host); - freez(lp->df_Referer); freez(lp->df_U); freez(lp->df_q); - freez(lp->df_User_agent); - freez(lp->df_X_Forwarded_For); freez(lp->df_b); freez(lp->df_h); freez(lp->df_m); freez(lp->df_s); freez(lp->df_u); freez(lp->df_ttfb); + VTAILQ_FOREACH_SAFE(h, &lp->headers, list, h2) { + VTAILQ_REMOVE(&lp->headers, h, list); + freez(h->key); + freez(h->value); + freez(h); + } #undef freez memset(lp, 0, sizeof *lp); } @@ -293,17 +312,22 @@ collect_backend(struct logline *lp, enum VSL_tag_e tag, unsigned spec, case SLT_TxHeader: if (!lp->active) break; - if (isprefix(ptr, "user-agent:", end, &next)) - lp->df_User_agent = trimline(next, end); - else if (isprefix(ptr, "referer:", end, &next)) - lp->df_Referer = trimline(next, end); - else if (isprefix(ptr, "authorization:", end, &next) && - isprefix(next, "basic", end, &next)) + if (isprefix(ptr, "authorization:", end, &next) && + isprefix(next, "basic", end, &next)) { lp->df_u = trimline(next, end); - else if (isprefix(ptr, "x-forwarded-for:", end, &next)) - lp->df_X_Forwarded_For = trimline(next, end); - else if (isprefix(ptr, "host:", end, &next)) - lp->df_Host = trimline(next, end); + } else { + struct hdr *h; + const char *split; + size_t l; + h = malloc(sizeof(struct hdr)); + AN(h); + split = strchr(ptr, ':'); + AN(split); + l = strlen(split); + h->key = trimline(ptr, split-1); + h->value = trimline(split+1, split+l-1); + VTAILQ_INSERT_HEAD(&lp->headers, h, list); + } break; case SLT_BackendReuse: @@ -394,22 +418,20 @@ collect_client(struct logline *lp, enum VSL_tag_e tag, unsigned spec, case SLT_RxHeader: if (!lp->active) break; - if (isprefix(ptr, "user-agent:", end, &next)) { - free(lp->df_User_agent); - lp->df_User_agent = trimline(next, end); - } else if (isprefix(ptr, "referer:", end, &next)) { - free(lp->df_Referer); - lp->df_Referer = trimline(next, end); - } else if (isprefix(ptr, "authorization:", end, &next) && - isprefix(next, "basic", end, &next)) { + if (isprefix(ptr, "authorization:", end, &next) && + isprefix(next, "basic", end, &next)) { free(lp->df_u); lp->df_u = trimline(next, end); - } else if (isprefix(ptr, "x-forwarded-for:", end, &next)) { - free(lp->df_X_Forwarded_For); - lp->df_X_Forwarded_For = trimline(next, end); - } else if (isprefix(ptr, "host:", end, &next)) { - free(lp->df_Host); - lp->df_Host = trimline(next, end); + } else { + struct hdr *h; + const char *split; + h = malloc(sizeof(struct hdr)); + AN(h); + split = strchr(ptr, ':'); + AN(split); + h->key = trimline(ptr, split); + h->value = trimline(split+1, end); + VTAILQ_INSERT_HEAD(&lp->headers, h, list); } break; @@ -579,10 +601,10 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, */ VSB_cat(os, lp->df_m); VSB_putc(os, ' '); - if (lp->df_Host) { - if (strncmp(lp->df_Host, "http://", 7) != 0) + if (get_header(lp, "Host")) { + if (strncmp(get_header(lp, "Host"), "http://", 7) != 0) VSB_cat(os, "http://"); - VSB_cat(os, lp->df_Host); + VSB_cat(os, get_header(lp, "Host")); } VSB_cat(os, lp->df_U); VSB_cat(os, lp->df_q ? lp->df_q : ""); @@ -626,42 +648,44 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, } break; - case '{': - if (strncmp(p, "{Referer}i", 10) == 0) { - VSB_cat(os, lp->df_Referer ? lp->df_Referer : "-"); - p += 9; - break; - } else if (strncmp(p, "{Host}i", 7) == 0) { - VSB_cat(os, lp->df_Host ? lp->df_Host : "-"); - p += 6; - break; - } else if (strncmp(p, "{X-Forwarded-For}i", 18) == 0) { - /* %{Referer}i */ - VSB_cat(os, lp->df_X_Forwarded_For ? lp->df_X_Forwarded_For : "-"); - p += 17; - break; - } else if (strncmp(p, "{User-agent}i", 13) == 0) { - /* %{User-agent}i */ - VSB_cat(os, lp->df_User_agent ? lp->df_User_agent : "-"); - p += 12; + case '{': { + const char *h, *tmp; + char fname[100], type; + tmp = p; + type = 0; + while (*tmp != '\0' && *tmp != '}') + tmp++; + if (*tmp == '}') { + tmp++; + type = *tmp; + memcpy(fname, p+1, tmp-p-2); + } + + switch (type) { + case 'i': + h = get_header(lp, fname); + VSB_cat(os, h ? h : "-"); + p = tmp; break; - } else if (strncmp(p, "{Varnish:", 9) == 0) { - /* Scan for what we're looking for */ - const char *what = p+9; - if (strncmp(what, "time_firstbyte}x", 16) == 0) { + case 'x': + if (strcmp(fname, "Varnish:time_firstbyte") == 0) { VSB_cat(os, lp->df_ttfb); - p += 9+15; - break; - } else if (strncmp(what, "hitmiss}x", 9) == 0) { + p = tmp; + } else if (strcmp(fname, "Varnish:hitmiss") == 0) { VSB_cat(os, (lp->df_hitmiss ? lp->df_hitmiss : "-")); - p += 9+8; + p = tmp; break; - } else if (strncmp(what, "handling}x", 10) == 0) { + } else if (strcmp(fname, "handling") == 0) { VSB_cat(os, (lp->df_handling ? lp->df_handling : "-")); - p += 9+9; + p = tmp; break; } + default: + fprintf(stderr, "Unknown format starting at: %s\n", --p); + exit(1); } + break; + } /* Fall through if we haven't handled something */ /* FALLTHROUGH*/ default: diff --git a/doc/sphinx/reference/varnishncsa.rst b/doc/sphinx/reference/varnishncsa.rst index 414e07e..48befed 100644 --- a/doc/sphinx/reference/varnishncsa.rst +++ b/doc/sphinx/reference/varnishncsa.rst @@ -68,8 +68,7 @@ The following options are available: Remote host %{X}i - The contents of header line X. Supported headers are - *Referer*, *Host*, *X-Forwarded-For* and *User-agent*. + The contents of header line X. %l Remote logname (always '-') From tfheen at varnish-cache.org Fri Jul 15 09:56:15 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Fri, 15 Jul 2011 11:56:15 +0200 Subject: [master] 041b457 Add support for logging response headers in varnishncsa Message-ID: commit 041b4574b85b3f6b2ec9940d311258b9cbb15357 Author: Tollef Fog Heen Date: Fri Jul 15 11:38:03 2011 +0200 Add support for logging response headers in varnishncsa diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index 94c81ef..6aea3d8 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -103,7 +103,8 @@ static struct logline { int active; /* Is log line in an active trans */ int complete; /* Is log line complete */ uint64_t bitmap; /* Bitmap for regex matches */ - VTAILQ_HEAD(, hdr) headers; + VTAILQ_HEAD(, hdr) req_headers; /* Request headers */ + VTAILQ_HEAD(, hdr) resp_headers; /* Response headers */ } **ll; struct VSM_data *vd; @@ -190,10 +191,23 @@ trimline(const char *str, const char *end) } static char * -get_header(struct logline *l, const char *name) +req_header(struct logline *l, const char *name) { struct hdr *h; - VTAILQ_FOREACH(h, &l->headers, list) { + VTAILQ_FOREACH(h, &l->req_headers, list) { + if (strcasecmp(h->key, name) == 0) { + return h->value; + break; + } + } + return NULL; +} + +static char * +resp_header(struct logline *l, const char *name) +{ + struct hdr *h; + VTAILQ_FOREACH(h, &l->resp_headers, list) { if (strcasecmp(h->key, name) == 0) { return h->value; break; @@ -216,8 +230,14 @@ clean_logline(struct logline *lp) freez(lp->df_s); freez(lp->df_u); freez(lp->df_ttfb); - VTAILQ_FOREACH_SAFE(h, &lp->headers, list, h2) { - VTAILQ_REMOVE(&lp->headers, h, list); + VTAILQ_FOREACH_SAFE(h, &lp->req_headers, list, h2) { + VTAILQ_REMOVE(&lp->req_headers, h, list); + freez(h->key); + freez(h->value); + freez(h); + } + VTAILQ_FOREACH_SAFE(h, &lp->resp_headers, list, h2) { + VTAILQ_REMOVE(&lp->resp_headers, h, list); freez(h->key); freez(h->value); freez(h); @@ -326,7 +346,7 @@ collect_backend(struct logline *lp, enum VSL_tag_e tag, unsigned spec, l = strlen(split); h->key = trimline(ptr, split-1); h->value = trimline(split+1, split+l-1); - VTAILQ_INSERT_HEAD(&lp->headers, h, list); + VTAILQ_INSERT_HEAD(&lp->req_headers, h, list); } break; @@ -415,10 +435,12 @@ collect_client(struct logline *lp, enum VSL_tag_e tag, unsigned spec, lp->df_s = trimline(ptr, end); break; + case SLT_TxHeader: case SLT_RxHeader: if (!lp->active) break; - if (isprefix(ptr, "authorization:", end, &next) && + if (tag == SLT_RxHeader && + isprefix(ptr, "authorization:", end, &next) && isprefix(next, "basic", end, &next)) { free(lp->df_u); lp->df_u = trimline(next, end); @@ -431,7 +453,10 @@ collect_client(struct logline *lp, enum VSL_tag_e tag, unsigned spec, AN(split); h->key = trimline(ptr, split); h->value = trimline(split+1, end); - VTAILQ_INSERT_HEAD(&lp->headers, h, list); + if (tag == SLT_RxHeader) + VTAILQ_INSERT_HEAD(&lp->req_headers, h, list); + else + VTAILQ_INSERT_HEAD(&lp->resp_headers, h, list); } break; @@ -601,10 +626,10 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, */ VSB_cat(os, lp->df_m); VSB_putc(os, ' '); - if (get_header(lp, "Host")) { - if (strncmp(get_header(lp, "Host"), "http://", 7) != 0) + if (req_header(lp, "Host")) { + if (strncmp(req_header(lp, "Host"), "http://", 7) != 0) VSB_cat(os, "http://"); - VSB_cat(os, get_header(lp, "Host")); + VSB_cat(os, req_header(lp, "Host")); } VSB_cat(os, lp->df_U); VSB_cat(os, lp->df_q ? lp->df_q : ""); @@ -659,11 +684,17 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, tmp++; type = *tmp; memcpy(fname, p+1, tmp-p-2); + fname[tmp-p-2] = 0; } switch (type) { case 'i': - h = get_header(lp, fname); + h = req_header(lp, fname); + VSB_cat(os, h ? h : "-"); + p = tmp; + break; + case 'o': + h = resp_header(lp, fname); VSB_cat(os, h ? h : "-"); p = tmp; break; diff --git a/doc/sphinx/reference/varnishncsa.rst b/doc/sphinx/reference/varnishncsa.rst index 48befed..9ddd26e 100644 --- a/doc/sphinx/reference/varnishncsa.rst +++ b/doc/sphinx/reference/varnishncsa.rst @@ -79,6 +79,9 @@ The following options are available: %q The query string, if no query string exists, an empty string. + %{X}o + The contents of response header line X. + %r The first line of the request From tfheen at varnish-cache.org Fri Jul 15 09:56:15 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Fri, 15 Jul 2011 11:56:15 +0200 Subject: [master] 8d88729 Minor clarification about %{X}i Message-ID: commit 8d8872929bd01dc2b54a07a2e699aa6da017c25a Author: Tollef Fog Heen Date: Fri Jul 15 11:38:15 2011 +0200 Minor clarification about %{X}i diff --git a/doc/sphinx/reference/varnishncsa.rst b/doc/sphinx/reference/varnishncsa.rst index 9ddd26e..65f08dd 100644 --- a/doc/sphinx/reference/varnishncsa.rst +++ b/doc/sphinx/reference/varnishncsa.rst @@ -68,7 +68,7 @@ The following options are available: Remote host %{X}i - The contents of header line X. + The contents of request header line X. %l Remote logname (always '-') From tfheen at varnish-cache.org Fri Jul 15 09:56:15 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Fri, 15 Jul 2011 11:56:15 +0200 Subject: [master] 61b0dcf Revert "Print 0, not - for zero-byte replies" Message-ID: commit 61b0dcfb45c972c9319a7208c1aa4a308710568b Author: Tollef Fog Heen Date: Fri Jul 15 11:50:06 2011 +0200 Revert "Print 0, not - for zero-byte replies" "-" is correct according to the Apache LogFormat documentation on http://httpd.apache.org/docs/current/mod/mod_log_config.html This reverts commit fe7e315cb98ffdc2e4f510e43c7b54bc1af840c1. See #949 diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index 6aea3d8..ce58fdc 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -594,7 +594,7 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, case 'b': /* %b */ - VSB_cat(os, lp->df_b ? lp->df_b : "0"); + VSB_cat(os, lp->df_b ? lp->df_b : "-"); break; case 'H': From tfheen at varnish-cache.org Fri Jul 15 10:21:27 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Fri, 15 Jul 2011 12:21:27 +0200 Subject: [master] 39249ec Fall back to using current time if urandom is not available Message-ID: commit 39249ecefaa8ed19bc261b6c6ae27997cf0a1a63 Author: Tollef Fog Heen Date: Fri Jul 15 12:14:08 2011 +0200 Fall back to using current time if urandom is not available diff --git a/lib/libvarnish/vtmpfile.c b/lib/libvarnish/vtmpfile.c index 60a9c21..327790a 100644 --- a/lib/libvarnish/vtmpfile.c +++ b/lib/libvarnish/vtmpfile.c @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -47,8 +48,12 @@ seed_random(void) unsigned seed; fd = open("/dev/urandom", O_RDONLY); - if (fd == -1) - return (1); + if (fd == -1) { + /* urandom not available, fall back to something + * weaker */ + srandom(time(NULL)); + return (0); + } if (read(fd, &seed, sizeof seed) != sizeof seed) return (1); (void)close(fd); From tfheen at varnish-cache.org Fri Jul 15 10:21:31 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Fri, 15 Jul 2011 12:21:31 +0200 Subject: [master] 2061b6e Adjust paths in spec file for trunk builds Message-ID: commit 2061b6e21ee799aeed9091d80c9f8397fece1b81 Author: Tollef Fog Heen Date: Fri Jul 15 12:14:16 2011 +0200 Adjust paths in spec file for trunk builds Switch back from beta2 to trunk meaning RPMs can be built directly from the tarballs again. Fixes: #955 diff --git a/redhat/varnish.spec b/redhat/varnish.spec index 7fc5a7a..d8b6fbb 100644 --- a/redhat/varnish.spec +++ b/redhat/varnish.spec @@ -1,12 +1,12 @@ Summary: High-performance HTTP accelerator Name: varnish Version: 3.0.0 -Release: 0.beta2%{?dist} +Release: 0.20110715%{?dist} License: BSD Group: System Environment/Daemons URL: http://www.varnish-cache.org/ #Source0: http://repo.varnish-cache.org/source/%{name}-%{version}.tar.gz -Source0: %{name}-3.0.0-beta2.tar.gz +Source0: %{name}-trunk.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) # To build from git, start with a make dist, see redhat/README.redhat # You will need at least automake autoconf libtool python-docutils @@ -72,7 +72,7 @@ Documentation files for %name %prep #%setup -q -%setup -q -n varnish-3.0.0-beta2 +%setup -q -n varnish-trunk mkdir examples cp bin/varnishd/default.vcl etc/zope-plone.vcl examples From tfheen at varnish-cache.org Fri Jul 15 10:24:55 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Fri, 15 Jul 2011 12:24:55 +0200 Subject: [master] d7c7c39 Increase http_resp_hdr_len and http_req_hdr_len Message-ID: commit d7c7c39abd8c56a7bce04991c7a8c35b58940dca Author: Tollef Fog Heen Date: Fri Jul 15 12:23:46 2011 +0200 Increase http_resp_hdr_len and http_req_hdr_len We're seeing at least up to 4k in the wild, so increase the limit somewhat. See: #939 diff --git a/bin/varnishd/mgt_param.c b/bin/varnishd/mgt_param.c index 26fcb31..3126744 100644 --- a/bin/varnishd/mgt_param.c +++ b/bin/varnishd/mgt_param.c @@ -522,7 +522,7 @@ static const struct parspec input_parspec[] = { "Maximum length of any HTTP client request header we will " "allow. The limit is inclusive its continuation lines.\n", 0, - "2048", "bytes" }, + "4096", "bytes" }, { "http_req_size", tweak_uint, &master.http_req_size, 256, UINT_MAX, "Maximum number of bytes of HTTP client request we will deal " @@ -538,7 +538,7 @@ static const struct parspec input_parspec[] = { "Maximum length of any HTTP backend response header we will " "allow. The limit is inclusive its continuation lines.\n", 0, - "2048", "bytes" }, + "4096", "bytes" }, { "http_resp_size", tweak_uint, &master.http_resp_size, 256, UINT_MAX, "Maximum number of bytes of HTTP backend resonse we will deal " From phk at varnish-cache.org Mon Jul 18 10:33:14 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 18 Jul 2011 12:33:14 +0200 Subject: [master] 0c5337e Change the response code on overly long request lines from 400 to 413 as per discussions in httpbis WG Message-ID: commit 0c5337e2732a94c68cb4161c47f9aaf63d4e6e3c Author: Poul-Henning Kamp Date: Mon Jul 18 10:32:45 2011 +0000 Change the response code on overly long request lines from 400 to 413 as per discussions in httpbis WG diff --git a/bin/varnishd/cache_http.c b/bin/varnishd/cache_http.c index 5d8050a..15d1b52 100644 --- a/bin/varnishd/cache_http.c +++ b/bin/varnishd/cache_http.c @@ -522,7 +522,7 @@ http_dissect_hdrs(struct worker *w, struct http *hp, int fd, char *p, if (q - p > htc->maxhdr) { VSC_C_main->losthdr++; WSL(w, SLT_LostHeader, fd, "%.*s", q - p, p); - return (400); + return (413); } /* Empty header = end of headers */ @@ -547,7 +547,7 @@ http_dissect_hdrs(struct worker *w, struct http *hp, int fd, char *p, } else { VSC_C_main->losthdr++; WSL(w, SLT_LostHeader, fd, "%.*s", q - p, p); - return (400); + return (413); } } return (0); @@ -598,7 +598,7 @@ http_splitline(struct worker *w, int fd, struct http *hp, hp->hd[h2].e = p; if (!Tlen(hp->hd[h2])) - return (400); + return (413); /* Skip SP */ for (; vct_issp(*p); p++) { diff --git a/bin/varnishtest/tests/c00039.vtc b/bin/varnishtest/tests/c00039.vtc index f8bba06..9339b59 100644 --- a/bin/varnishtest/tests/c00039.vtc +++ b/bin/varnishtest/tests/c00039.vtc @@ -23,7 +23,7 @@ client c1 { expect resp.status == 200 txreq -url "/1" -hdr "1...5....0....5....0....5....0....5....0." rxresp - expect resp.status == 400 + expect resp.status == 413 } -run client c1 { @@ -32,7 +32,7 @@ client c1 { expect resp.status == 200 txreq -url "/2" -hdr "1...5....0....5\n ..0....5....0....5....0." rxresp - expect resp.status == 400 + expect resp.status == 413 } -run client c1 { From phk at varnish-cache.org Mon Jul 18 14:25:32 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 18 Jul 2011 16:25:32 +0200 Subject: [master] 4172f98 Fix a bug in the entity-replacement code in the ESI-parser. Message-ID: commit 4172f9888077d42d8c0148a353d6940764d46154 Author: Poul-Henning Kamp Date: Mon Jul 18 14:25:00 2011 +0000 Fix a bug in the entity-replacement code in the ESI-parser. Patch by: scoof Fixes #961 diff --git a/bin/varnishd/cache_esi_parse.c b/bin/varnishd/cache_esi_parse.c index 411db43..afef1fb 100644 --- a/bin/varnishd/cache_esi_parse.c +++ b/bin/varnishd/cache_esi_parse.c @@ -518,7 +518,7 @@ vep_do_include(struct vep_state *vep, enum dowhat what) #define R(w,f,r) \ if (q + w <= p + l && !memcmp(q, f, w)) { \ VSB_printf(vep->vsb, "%c", r); \ - q += l; \ + q += w; \ continue; \ } R(6, "'", '\''); diff --git a/bin/varnishtest/tests/r00961.vtc b/bin/varnishtest/tests/r00961.vtc new file mode 100644 index 0000000..b162379 --- /dev/null +++ b/bin/varnishtest/tests/r00961.vtc @@ -0,0 +1,49 @@ +varnishtest "Test XML 1.0 entity references" + +server s1 { + rxreq + expect req.url == "/" + txresp -body { + + + + + + } + + rxreq + expect req.url == "/t&t" + txresp -body "1" + + rxreq + expect req.url == "/tt" + txresp -body "333" + + rxreq + expect req.url == {/t't} + txresp -body "4444" + + rxreq + expect req.url == {/t"t} + txresp -body "55555" +} -start + +varnish v1 -vcl+backend { + sub vcl_recv { + return (pass); + } + sub vcl_fetch { + set beresp.do_esi = true; + } +} -start + +client c1 { + txreq + rxresp + expect resp.status == 200 + expect resp.bodylen == 32 +} -run