From nils.goroll at uplex.de Wed Oct 1 13:15:05 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 1 Oct 2025 13:15:05 +0000 (UTC) Subject: [master] 2fb567256 sess_close: generalize the description of errors Message-ID: <20251001131505.BC42964FF8@lists.varnish-cache.org> commit 2fb56725654b3cea00b585aca0a6dcda1417408d Author: Asad Sajjad Ahmed Date: Thu May 22 10:10:13 2025 +0200 sess_close: generalize the description of errors We use these errors for both sessions and fetches. Therefore, avoid making the description too client centric. Signed-off-by: Asad Sajjad Ahmed diff --git a/include/tbl/sess_close.h b/include/tbl/sess_close.h index 1fc5b648e..009b5b20b 100644 --- a/include/tbl/sess_close.h +++ b/include/tbl/sess_close.h @@ -32,8 +32,8 @@ /*lint -save -e525 -e539 */ // stream_close_t sc_* stat is_err Description -SESS_CLOSE(REM_CLOSE, rem_close, 0, "Client Closed") -SESS_CLOSE(REQ_CLOSE, req_close, 0, "Client requested close") +SESS_CLOSE(REM_CLOSE, rem_close, 0, "Peer Closed") +SESS_CLOSE(REQ_CLOSE, req_close, 0, "Peer requested close") SESS_CLOSE(REQ_HTTP10, req_http10, 1, "Proto < HTTP/1.1") SESS_CLOSE(RX_BAD, rx_bad, 1, "Received bad req/resp") SESS_CLOSE(RX_BODY, rx_body, 1, "Failure receiving body") From walid.boudebouda at gmail.com Wed Oct 1 14:48:11 2025 From: walid.boudebouda at gmail.com (Walid Boudebouda) Date: Wed, 1 Oct 2025 14:48:11 +0000 (UTC) Subject: [master] 42fd02d0d vtc: White space cleanup in t02027 Message-ID: <20251001144811.950C31039C2@lists.varnish-cache.org> commit 42fd02d0d9222c7c82f6aaebe8b2beebf81d9378 Author: Dridi Boukelmoune Date: Thu Jul 17 18:53:26 2025 +0200 vtc: White space cleanup in t02027 No diff with the --ignore-all-space option. diff --git a/bin/varnishtest/tests/t02027.vtc b/bin/varnishtest/tests/t02027.vtc index 5bc7b4816..a27976f3b 100644 --- a/bin/varnishtest/tests/t02027.vtc +++ b/bin/varnishtest/tests/t02027.vtc @@ -22,11 +22,11 @@ logexpect l0 -v v1 -g vxid -q "Begin ~ sess" { client c0 { txpri shutdown -write - stream 0 { + stream 0 { rxsettings - rxgoaway - expect goaway.laststream == 0 - expect goaway.err == NO_ERROR + rxgoaway + expect goaway.laststream == 0 + expect goaway.err == NO_ERROR } -run } -run @@ -46,10 +46,10 @@ client c1 { txreq -nohdrend } -run shutdown -write - stream 0 { - rxgoaway - expect goaway.laststream == 1 - expect goaway.err == NO_ERROR + stream 0 { + rxgoaway + expect goaway.laststream == 1 + expect goaway.err == NO_ERROR } -run } -run @@ -69,10 +69,10 @@ client c2 { txreq -nostrend } -run shutdown -write - stream 0 { - rxgoaway - expect goaway.laststream == 1 - expect goaway.err == NO_ERROR + stream 0 { + rxgoaway + expect goaway.laststream == 1 + expect goaway.err == NO_ERROR } -run } -run @@ -89,10 +89,10 @@ logexpect l3 -v v1 -g vxid -q "Begin ~ sess" { # middle of frame client c3 { stream 1 { - # +- 01 END_STREAM + # +- 01 END_STREAM # +- 04 END_HEADERS - # | - # len ty fl strmid + # | + # len ty fl strmid sendhex { 000024 01 05 00000001 00053a70617468012f00073a6d6574686f640347455400073a736368656d6504687474 @@ -101,10 +101,10 @@ client c3 { # 00053a70617468012f00073a6d6574686f640347455400073a736368656d650468747470 } -run shutdown -write - stream 0 { - rxgoaway - expect goaway.laststream == 0 - expect goaway.err == NO_ERROR + stream 0 { + rxgoaway + expect goaway.laststream == 0 + expect goaway.err == NO_ERROR } -run } -run From walid.boudebouda at gmail.com Wed Oct 1 14:48:11 2025 From: walid.boudebouda at gmail.com (Walid Boudebouda) Date: Wed, 1 Oct 2025 14:48:11 +0000 (UTC) Subject: [master] edeac06d9 vtc: Stabilize r2387 Message-ID: <20251001144811.ADCA31039C5@lists.varnish-cache.org> commit edeac06d91979b659d0389fba0d3d1db8e5dd7d5 Author: Dridi Boukelmoune Date: Fri Jul 18 10:49:09 2025 +0200 vtc: Stabilize r2387 The connection may be closed before either stream 1 or 3 is done sending a CONTINUATION frame. diff --git a/bin/varnishtest/tests/r02387.vtc b/bin/varnishtest/tests/r02387.vtc index d2c9796e7..3d9dab7f4 100644 --- a/bin/varnishtest/tests/r02387.vtc +++ b/bin/varnishtest/tests/r02387.vtc @@ -11,8 +11,8 @@ varnish v1 -cliok "param.set feature +http2" varnish v1 -cliok "param.set debug +syncvsl" -barrier b1 cond 2 -barrier b2 cond 2 +barrier b1 cond 3 +barrier b2 cond 3 client c1 { stream 1 { @@ -27,7 +27,16 @@ client c1 { barrier b1 sync txcont -hdr "bar" "foo" - } -run + } -start + + barrier b2 sync + non_fatal + barrier b1 sync + + stream 1 -wait + stream 3 -wait + fatal + stream 0 { rxgoaway expect goaway.laststream == "1" From nils.goroll at uplex.de Fri Oct 3 10:39:04 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Fri, 3 Oct 2025 10:39:04 +0000 (UTC) Subject: [master] e13349b27 m49.vtc: Test filter-controlled chunked bereq body Message-ID: <20251003103904.D603611308C@lists.varnish-cache.org> commit e13349b272bddbc6da978c1fa0f7c8206b4f76c7 Author: Nils Goroll Date: Fri Oct 3 12:37:31 2025 +0200 m49.vtc: Test filter-controlled chunked bereq body diff --git a/bin/varnishtest/tests/m00049.vtc b/bin/varnishtest/tests/m00049.vtc index db6d607e6..14e693bdf 100644 --- a/bin/varnishtest/tests/m00049.vtc +++ b/bin/varnishtest/tests/m00049.vtc @@ -4,6 +4,8 @@ varnishtest "VMOD vfp & vdp - request bodies" server s1 { rxreq + expect req.http.Content-Length == "28" + expect req.http.Transfer-Encoding == expect req.body == "Cbagb Snpgb, Pnrfne Genafvg!" txresp } -start @@ -22,6 +24,34 @@ client c1 { expect resp.status == 200 } -run +server s1 -wait + +# --- + +server s1 { + rxreq + expect req.http.Content-Length == + expect req.http.Transfer-Encoding == "chunked" + expect req.body == "Cbagb Snpgb, Pnrfne Genafvg!" + txresp +} -start + +varnish v1 -vcl+backend { + import debug; + + sub vcl_backend_fetch { + set bereq.filters = "rot13 debug.pedantic debug.chunked"; + } +} + +client c1 { + txreq -req POST -body "Ponto Facto, Caesar Transit!" + rxresp + expect resp.status == 200 +} -run + +# --- + varnish v1 -vsl_catchup varnish v1 -vcl+backend { From nils.goroll at uplex.de Fri Oct 3 11:49:04 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Fri, 3 Oct 2025 11:49:04 +0000 (UTC) Subject: [master] c12fa309e vmod_debug: support long vcl names Message-ID: <20251003114904.C9077115CA8@lists.varnish-cache.org> commit c12fa309e587ca03b38246d7c44aa1b21c2cc9ba Author: Nils Goroll Date: Fri Oct 3 13:48:01 2025 +0200 vmod_debug: support long vcl names diff --git a/vmod/vmod_debug.c b/vmod/vmod_debug.c index bdf11deaf..4860da47e 100644 --- a/vmod/vmod_debug.c +++ b/vmod/vmod_debug.c @@ -395,7 +395,7 @@ static int event_warm(VRT_CTX, const struct vmod_priv *priv) { struct priv_vcl *priv_vcl; - char buf[32]; + char buf[512]; const char *vcl_name = VCL_Name(ctx->vcl); // Using VSLs for coverage From phk at FreeBSD.org Sat Oct 4 08:22:05 2025 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Sat, 4 Oct 2025 08:22:05 +0000 (UTC) Subject: [master] 6ecfea981 Refresh the VJSN test code. Message-ID: <20251004082205.9108B118992@lists.varnish-cache.org> commit 6ecfea98124f04a96dc0dec4e1eb66d19fde6b16 Author: Poul-Henning Kamp Date: Sat Oct 4 06:38:20 2025 +0000 Refresh the VJSN test code. diff --git a/lib/libvarnish/vjsn.c b/lib/libvarnish/vjsn.c index 0ea056f18..e0764e4e6 100644 --- a/lib/libvarnish/vjsn.c +++ b/lib/libvarnish/vjsn.c @@ -556,41 +556,36 @@ VJSN_TYPES * * And run this python in test_parsing: - import glob - - skip = {} - - def emit(fin): - if fin in skip: - return - x = bytearray(open(fin, 'rb').read()) - if 0 in x: - return - if len(x) > 1000: - return - t = '\t"' - for i in x: - t += "\\x%02x" % i - if len(t) > 64: - print(t + '"') - t = '\t"' - print(t + '",') - - print("static const char *good[] = {") - l = list(glob.glob("y_*")) - l.sort() - for f in l: - emit(f) - print("\tNULL") - print("};\n") - - print("static const char *bad[] = {") - l = list(glob.glob("n_*")) - l.sort() - for f in l: - emit(f) - print("\tNULL") - print("};") +import glob + +def emit(fin): + x = bytearray(open(fin, 'rb').read()) + if 0 in x: + print("\t// SKIP: NUL in", fin) + return + if len(x) > 1000: + print("\t// SKIP: LONG ", fin) + return + t = '\t"' + for i in x: + t += "\\x%02x" % i + if len(t) > 64: + print(t + '"') + t = '\t"' + print(t + '",') + +print("static const char *good[] = {") +for f in sorted(glob.glob("y_*")): + emit(f) +print("\tNULL") +print("};\n") + +print("static const char *bad[] = {") +for f in sorted(glob.glob("n_*")): + emit(f) +print("\tNULL") +print("};") + */ static const char *good[] = { @@ -759,6 +754,7 @@ static const char *bad[] = { "\x5b\x66\x61\x6c\x73\x5d", "\x5b\x6e\x75\x6c\x5d", "\x5b\x74\x72\x75\x5d", + // SKIP: NUL in n_multidigit_number_then_00.json "\x5b\x2b\x2b\x31\x32\x33\x34\x5d", "\x5b\x2b\x31\x5d", "\x5b\x2b\x49\x6e\x66\x5d", @@ -848,6 +844,7 @@ static const char *bad[] = { "\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x75\x31\x22\x5d", "\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x75\x31\x78\x22\x5d", "\x5b\xc3\xa9\x5d", + // SKIP: NUL in n_string_backslash_00.json "\x5b\x22\x5c\x78\x30\x30\x22\x5d", "\x5b\x22\x5c\x5c\x5c\x22\x5d", "\x5b\x22\x5c\x09\x22\x5d", @@ -868,10 +865,12 @@ static const char *bad[] = { "", "\x61\x62\x63", "\x5b\x22\x5c", + // SKIP: NUL in n_string_unescaped_ctrl_char.json "\x5b\x22\x6e\x65\x77\x0a\x6c\x69\x6e\x65\x22\x5d", "\x5b\x22\x09\x22\x5d", "\x22\x5c\x55\x41\x36\x36\x44\x22", "\x22\x22\x78", + // SKIP: LONG n_structure_100000_opening_arrays.json "\x5b\xe2\x81\xa0\x5d", "\xef\xbb\xbf", "\x3c\x2e\x3e", @@ -889,6 +888,7 @@ static const char *bad[] = { "\xe5", "\x5b", "", + // SKIP: NUL in n_structure_null-byte-outside-string.json "\x32\x40", "\x7b\x7d\x7d", "\x7b\x22\x22\x3a", @@ -897,6 +897,7 @@ static const char *bad[] = { "\x7b\x22\x61\x22\x3a\x20\x74\x72\x75\x65\x7d\x20\x22\x78\x22", "\x5b\x27", "\x5b\x2c", + // SKIP: LONG n_structure_open_array_object.json "\x5b\x7b", "\x5b\x22\x61", "\x5b\x22\x61\x22", From nils.goroll at uplex.de Tue Oct 7 06:48:05 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 7 Oct 2025 06:48:05 +0000 (UTC) Subject: [master] 720b939c2 vcc_acl: Update and improve error reporting Message-ID: <20251007064805.3949A107CBB@lists.varnish-cache.org> commit 720b939c2e1fa4f0e9cdd98ded16791e14ffdf80 Author: Nils Goroll Date: Tue Oct 7 08:36:02 2025 +0200 vcc_acl: Update and improve error reporting diff --git a/bin/varnishtest/tests/v00017.vtc b/bin/varnishtest/tests/v00017.vtc index 6ed35abc6..8df16c012 100644 --- a/bin/varnishtest/tests/v00017.vtc +++ b/bin/varnishtest/tests/v00017.vtc @@ -109,7 +109,7 @@ varnish v1 -errvcl {Expected a flag at:} { sub vcl_recv { if (client.ip ~ a) { return(pass); } } } -varnish v1 -errvcl {Unknown ACL flag:} { +varnish v1 -errvcl {Unknown ACL flag.} { backend b { .host = "${localhost}"; } acl a +foobar { "10.0.1.0/22" / 22; diff --git a/lib/libvcc/vcc_acl.c b/lib/libvcc/vcc_acl.c index df2bce46a..356c77072 100644 --- a/lib/libvcc/vcc_acl.c +++ b/lib/libvcc/vcc_acl.c @@ -823,11 +823,12 @@ vcc_ParseAcl(struct vcc *tl) ERRCHK(tl); AN(sym); +#define FLAGS_MSG "Valid ACL flags are `log`, `fold`, `pedantic` and `table`:\n" + while (1) { sign = vcc_IsFlag(tl); if (tl->err) { - VSB_cat(tl->sb, - "Valid ACL flags are `log` and `table`:\n"); + VSB_cat(tl->sb, FLAGS_MSG); return; } if (sign < 0) @@ -845,12 +846,14 @@ vcc_ParseAcl(struct vcc *tl) acl->flag_table = sign; vcc_NextToken(tl); } else { - VSB_cat(tl->sb, "Unknown ACL flag:\n"); + VSB_cat(tl->sb, "Unknown ACL flag. " FLAGS_MSG); vcc_ErrWhere(tl, tl->t); return; } } +#undef FLAGS_MSG + SkipToken(tl, '{'); while (tl->t->tok != '}') { From nils.goroll at uplex.de Tue Oct 7 10:41:05 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 7 Oct 2025 10:41:05 +0000 (UTC) Subject: [master] 65e405518 Start NEXT section in changes.rst Message-ID: <20251007104106.03687112CF7@lists.varnish-cache.org> commit 65e405518668266a398a9f8cf83fe8a2fe5468f4 Author: Nils Goroll Date: Mon May 19 11:47:15 2025 +0200 Start NEXT section in changes.rst to anchor patches diff --git a/doc/changes.rst b/doc/changes.rst index 70cb0cc58..6f8eb2529 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -34,13 +34,16 @@ http://varnish-cache.org/docs/trunk/whats-new/index.html and via individual releases. These documents are updated as part of the release process. -================================ -Varnish-Cache 8.0.0 (2025-09-15) -================================ +============================= +Vinyl-Cache NEXT (2026-03-15) +============================= .. PLEASE keep this roughly in commit order as shown by git-log / tig (new to old) +================================ +Varnish-Cache 8.0.0 (2025-09-15) +================================ .. _4388: https://github.com/varnishcache/varnish-cache/pull/4388 From nils.goroll at uplex.de Tue Oct 7 10:41:06 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 7 Oct 2025 10:41:06 +0000 (UTC) Subject: [master] 9f02342b4 vcl: rename req.ttl to req.max_age, keep req.ttl as an alias Message-ID: <20251007104106.1C44E112CFA@lists.varnish-cache.org> commit 9f02342b455469349e24a88e49550f23c262baaf Author: Nils Goroll Date: Tue Oct 7 12:27:24 2025 +0200 vcl: rename req.ttl to req.max_age, keep req.ttl as an alias ... and document as deprecated, but do not emit a warning (yet). Closes #4389 diff --git a/bin/varnishd/cache/cache_expire.c b/bin/varnishd/cache/cache_expire.c index 75a45bc5a..cd604f1d0 100644 --- a/bin/varnishd/cache/cache_expire.c +++ b/bin/varnishd/cache/cache_expire.c @@ -60,9 +60,9 @@ struct exp_priv { static struct exp_priv *exphdl; static int exp_shutdown = 0; -/*-------------------------------------------------------------------- - * Calculate an object's effective ttl time, taking req.ttl into account - * if it is available. +/*--------------------------------------------------------------------- + * Calculate the point in time when an object will become stale, taking + * req.max_age into account, if available */ vtim_real diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c index a72abd8cc..06afcd78a 100644 --- a/bin/varnishd/cache/cache_hash.c +++ b/bin/varnishd/cache/cache_hash.c @@ -577,7 +577,7 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp) break; } - if (EXP_Ttl(NULL, oc) <= req->t_req && /* ignore req.ttl */ + if (EXP_Ttl(NULL, oc) <= req->t_req && /* ignore req.max_age */ oc->t_origin > exp_t_origin) { /* record the newest object */ exp_oc = oc; diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index fc3861a33..4cdff3685 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -598,13 +598,18 @@ VRT_u_req_##nm(VRT_CTX) \ REQ_VAR_R(backend_hint, director_hint, VCL_BACKEND) -REQ_VAR_L(ttl, d_ttl, VCL_DURATION, if (!(arg>0.0)) arg = 0;) -REQ_VAR_R(ttl, d_ttl, VCL_DURATION) -REQ_VAR_U(ttl, d_ttl, -1) +REQ_VAR_L(max_age, d_ttl, VCL_DURATION, if (!(arg>0.0)) arg = 0;) +REQ_VAR_R(max_age, d_ttl, VCL_DURATION) +REQ_VAR_U(max_age, d_ttl, -1) REQ_VAR_L(grace, d_grace, VCL_DURATION, if (!(arg>0.0)) arg = 0;) REQ_VAR_R(grace, d_grace, VCL_DURATION) REQ_VAR_U(grace, d_grace, -1) +// deprecated, to be removed +VCL_VOID VRT_l_req_ttl(VRT_CTX, VCL_DURATION arg) { VRT_l_req_max_age(ctx, arg); } +VCL_DURATION VRT_r_req_ttl(VRT_CTX) { return (VRT_r_req_max_age(ctx)); } +VCL_VOID VRT_u_req_ttl(VRT_CTX) { return (VRT_u_req_max_age(ctx)); } + VCL_VOID VRT_l_req_backend_hint(VRT_CTX, VCL_BACKEND be) { diff --git a/bin/varnishtest/tests/c00009.vtc b/bin/varnishtest/tests/c00009.vtc index b71ce59fc..601b9403a 100644 --- a/bin/varnishtest/tests/c00009.vtc +++ b/bin/varnishtest/tests/c00009.vtc @@ -20,7 +20,7 @@ varnish v1 -syntax 4.0 -arg "-smysteve=malloc,1m" -vcl+backend { set req.proto = "HTTP/1.2"; set req.http.preserveme = "1"; set req.storage = storage.mysteve; - set req.ttl = 42m; + set req.max_age = 42m; set req.esi = false; set req.backend_hint = s2; set req.hash_ignore_busy = true; @@ -53,7 +53,7 @@ varnish v1 -syntax 4.0 -arg "-smysteve=malloc,1m" -vcl+backend { set resp.http.preserveme = req.http.preserveme; set resp.http.restarts = req.restarts; set resp.http.storage = req.storage; - set resp.http.ttl = req.ttl; + set resp.http.ttl = req.max_age; set resp.http.esi = req.esi; set resp.http.backend_hint = req.backend_hint; set resp.http.hash-ignore-busy = req.hash_ignore_busy; diff --git a/bin/varnishtest/tests/r02422.vtc b/bin/varnishtest/tests/r02422.vtc index 7a51689d2..1dfcfaf3c 100644 --- a/bin/varnishtest/tests/r02422.vtc +++ b/bin/varnishtest/tests/r02422.vtc @@ -1,4 +1,4 @@ -varnishtest "long polling and low latency using req.ttl" +varnishtest "long polling and low latency using req.max_age" # synchronizes the setup of all clients barrier b1 cond 2 @@ -25,7 +25,7 @@ varnish v1 -cliok "param.set default_grace 0" varnish v1 -vcl+backend { sub vcl_recv { if (req.restarts > 0) { - set req.ttl = 1ms; + set req.max_age = 1ms; } } diff --git a/bin/varnishtest/tests/v00000.vtc b/bin/varnishtest/tests/v00000.vtc index 10f3892ff..54a971613 100644 --- a/bin/varnishtest/tests/v00000.vtc +++ b/bin/varnishtest/tests/v00000.vtc @@ -1,4 +1,4 @@ -varnishtest "VCL/VRT: req.ttl / beresp.ttl / beresp.grace" +varnishtest "VCL/VRT: req.max_age / beresp.ttl / beresp.grace" server s1 { @@ -10,7 +10,7 @@ server s1 -start varnish v1 -vcl+backend { sub vcl_recv { - set req.ttl += 1 s; + set req.max_age += 1 s; } sub vcl_backend_response { set beresp.ttl += 1 m; diff --git a/bin/varnishtest/tests/v00020.vtc b/bin/varnishtest/tests/v00020.vtc index 86268bd80..239ecc991 100644 --- a/bin/varnishtest/tests/v00020.vtc +++ b/bin/varnishtest/tests/v00020.vtc @@ -77,7 +77,7 @@ varnish v1 -errvcl {Operator * not possible on type STRING.} { varnish v1 -errvcl {DURATION + INT not possible.} { sub vcl_backend_response { - set req.ttl = req.ttl + beresp.status; + set req.max_age = req.max_age + beresp.status; } } @@ -90,7 +90,7 @@ varnish v1 -errvcl {BOOL + BOOL not possible.} { varnish v1 -errvcl {Operator % only possible on INT} { sub vcl_recv { - if (req.ttl % 1000) { + if (req.max_age % 1000) { } } } @@ -143,22 +143,22 @@ varnish v1 -vcl { set req.http.foo = req.http.foo + "bar" ~ "bar"; set req.http.foo = req.http.foo + "bar" !~ "bar"; - set req.http.foo = "foo" + req.ttl; + set req.http.foo = "foo" + req.max_age; set req.http.foo = client.ip + ", " + server.ip; - set req.ttl = -1s; - set req.ttl = 1s; - set req.ttl *= 1.5; - set req.ttl = 1.5 s * 2.5; - set req.ttl = 1.5 s / 2.5; - set req.ttl = 1.5h + 1.5s; - set req.ttl = 1.5h - 1.5s; + set req.max_age = -1s; + set req.max_age = 1s; + set req.max_age *= 1.5; + set req.max_age = 1.5 s * 2.5; + set req.max_age = 1.5 s / 2.5; + set req.max_age = 1.5h + 1.5s; + set req.max_age = 1.5h - 1.5s; - if (req.ttl) { } - if (!req.ttl) { } - if (req.ttl > 1d) { } - if (req.ttl < 1d) { } + if (req.max_age) { } + if (!req.max_age) { } + if (req.max_age > 1d) { } + if (req.max_age < 1d) { } if (1) { } if (2 == 3) { } @@ -197,13 +197,13 @@ varnish v1 -errvcl {STRING - STRING not possible.} { varnish v1 -errvcl {TIME + STRING not possible.} { sub vcl_recv { - set req.ttl = now + "foo"; + set req.max_age = now + "foo"; } } varnish v1 -errvcl {TIME + TIME not possible.} { sub vcl_recv { - set req.ttl = now + now; + set req.max_age = now + now; } } @@ -221,25 +221,25 @@ varnish v1 -errvcl {INT + TIME not possible.} { varnish v1 -errvcl {DURATION + INT not possible.} { sub vcl_recv { - set req.ttl = 1s + 1; + set req.max_age = 1s + 1; } } varnish v1 -errvcl {DURATION + TIME not possible.} { sub vcl_recv { - set req.ttl = 1s + now; + set req.max_age = 1s + now; } } varnish v1 -errvcl {DURATION + STRING not possible.} { sub vcl_recv { - set req.ttl = 1s + "foo"; + set req.max_age = 1s + "foo"; } } varnish v1 -errvcl {IP + IP not possible.} { sub vcl_recv { - set req.ttl = client.ip + server.ip; + set req.max_age = client.ip + server.ip; } } diff --git a/bin/varnishtest/tests/v00025.vtc b/bin/varnishtest/tests/v00025.vtc index c6cdadd8f..5d40ff683 100644 --- a/bin/varnishtest/tests/v00025.vtc +++ b/bin/varnishtest/tests/v00025.vtc @@ -43,8 +43,8 @@ varnish v1 -syntax 4.0 -vcl+backend { sub vcl_deliver { set resp.http.server_port = std.port(server.ip); set resp.http.server_port_foo = std.port(server.ip) + "_foo"; - set resp.http.ttl1 = (req.ttl + 10s); - set resp.http.ttl2 = req.ttl + 10s; + set resp.http.ttl1 = (req.max_age + 10s); + set resp.http.ttl2 = req.max_age + 10s; set resp.http.id = server.identity; set resp.http.esi = req.esi; set resp.http.be = req.backend_hint; diff --git a/doc/changes.rst b/doc/changes.rst index 6f8eb2529..0ced70596 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -41,6 +41,12 @@ Vinyl-Cache NEXT (2026-03-15) .. PLEASE keep this roughly in commit order as shown by git-log / tig (new to old) +.. _4389: https://github.com/varnishcache/varnish-cache/issues/4389 + +* ``req.ttl`` has been renamed to ``req.max_age`` for clarity, with ``req.ttl`` + being retained as an alias. ``req.ttl`` is now deprecated, but no warning is + emitted yet. It will be removed in a future version of Vinyl-Cache. (`4389`_) + ================================ Varnish-Cache 8.0.0 (2025-09-15) ================================ diff --git a/doc/sphinx/reference/vcl_var.rst b/doc/sphinx/reference/vcl_var.rst index 627caa15f..52cff63da 100644 --- a/doc/sphinx/reference/vcl_var.rst +++ b/doc/sphinx/reference/vcl_var.rst @@ -529,6 +529,24 @@ req.transport The transport protocol which brought this request. +.. _req.max_age: + +req.max_age + + Type: DURATION + + Readable from: client + + Writable from: client + + Unsettable from: client + + + Upper limit on the object age for cache lookups to return hit. Matches + ``Cache-Control: max-age`` request header semantics. + + When reading the unset value, it is returned as -1. + .. _req.ttl: req.ttl @@ -539,12 +557,11 @@ req.ttl Writable from: client - Unsettable from: client - + Unsettable from: client - Upper limit on the object age for cache lookups to return hit. - When reading the unset value, it is returned as -1. + Deprecated alias of ``req.max-age``, which will be removed in a future + version of Vinyl-Cache. .. _req.url: From nils.goroll at uplex.de Wed Oct 15 08:01:03 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 15 Oct 2025 08:01:03 +0000 (UTC) Subject: [master] 8b41c8c01 condfetch: Demote to fetch for dying stale_oc Message-ID: <20251015080103.69F3910E000@lists.varnish-cache.org> commit 8b41c8c016d06be65f3b88365efb277e2d6def62 Author: Dridi Boukelmoune Date: Tue Mar 12 18:12:33 2024 +0100 condfetch: Demote to fetch for dying stale_oc When it is time to decide between making a bereq for a regular or conditional fetch, we need to ensure that the stale object is still valid. There is a window between the lookup and the begining of a fetch task during which the object could have been invalidated, in particular if the fetch task was queued. Catching it early allows to proceed with a regular fetch. Comitter edit: Minor wording change above, because the mkbereq step is not entered for retries. Ref #4399 diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 55374cf09..e6fb30cc2 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -272,7 +272,7 @@ vbf_stp_mkbereq(struct worker *wrk, struct busyobj *bo) } http_ForceField(bo->bereq0, HTTP_HDR_PROTO, "HTTP/1.1"); - if (bo->stale_oc != NULL && + if (bo->stale_oc != NULL && !(bo->stale_oc->flags & OC_F_DYING) && ObjCheckFlag(bo->wrk, bo->stale_oc, OF_IMSCAND) && (bo->stale_oc->boc != NULL || ObjGetLen(wrk, bo->stale_oc) != 0)) { AZ(bo->stale_oc->flags & (OC_F_HFM|OC_F_PRIVATE)); diff --git a/bin/varnishtest/tests/c00130.vtc b/bin/varnishtest/tests/c00130.vtc new file mode 100644 index 000000000..c75f24621 --- /dev/null +++ b/bin/varnishtest/tests/c00130.vtc @@ -0,0 +1,59 @@ +varnishtest "Demote condfetch to fetch on invalidated stale object" + +barrier b1 sock 2 +barrier b2 sock 2 + +server s1 { + rxreq + txresp -hdr {ETag: "foo"} -body corrupted + + rxreq + expect req.http.If-None-Match == + txresp -hdr {ETag: "foo"} -body valid +} -start + +varnish v1 -vcl+backend { + import vtc; + sub vcl_recv { + if (req.method == "PURGE") { + return (purge); + } + } + sub vcl_miss { + if (req.http.sync) { + vtc.barrier_sync("${b1_sock}"); + vtc.barrier_sync("${b2_sock}"); + } + } + sub vcl_backend_response { + set beresp.ttl = 1ms; + set beresp.grace = 0s; + set beresp.keep = 10s; + } + sub vcl_deliver { + set resp.http.obj-hits = obj.hits; + } +} -start + +client c1 { + txreq + rxresp + expect resp.body == corrupted + expect resp.http.obj-hits == 0 + + delay 0.1 + + txreq -hdr "sync: true" + rxresp + expect resp.body == valid + expect resp.http.obj-hits == 0 +} -start + +barrier b1 sync +client c2 { + txreq -req PURGE + rxresp +} -run +barrier b2 sync + +client c1 -wait From nils.goroll at uplex.de Wed Oct 15 08:01:03 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 15 Oct 2025 08:01:03 +0000 (UTC) Subject: [master] f084558ea fetch: No conditional GET if our stale object is dying Message-ID: <20251015080103.7D3CD10E003@lists.varnish-cache.org> commit f084558ea5e678053a37afc191a87fcac6b28128 Author: Nils Goroll Date: Wed Sep 24 15:11:04 2025 +0200 fetch: No conditional GET if our stale object is dying Similar to the previous commit, but we also need to re-check the condition for each backend request because we might have re-tried. Ref #4399 diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index e6fb30cc2..da85a129f 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -388,6 +388,14 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo) oc = bo->fetch_objcore; CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); + // this complements the stale_oc handling in vbf_stp_mkbereq(): + // Conditions might have changed since we made the bereq (retry) + if (! bo->uncacheable && bo->stale_oc != NULL && + bo->stale_oc->flags & OC_F_DYING) { + http_Unset(bo->bereq, H_If_Modified_Since); + http_Unset(bo->bereq, H_If_None_Match); + } + AZ(bo->storage); bo->storage = bo->uncacheable ? stv_transient : STV_next(); From nils.goroll at uplex.de Wed Oct 15 08:01:03 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 15 Oct 2025 08:01:03 +0000 (UTC) Subject: [master] 8802338e9 builtin.vcl: Explain backend refresh errros better Message-ID: <20251015080103.998AC10E007@lists.varnish-cache.org> commit 8802338e950cc6b5edf26a979fc662c7e29af735 Author: Nils Goroll Date: Wed Sep 24 15:30:04 2025 +0200 builtin.vcl: Explain backend refresh errros better We now use a specific reason for the cases of a late fail of a 304 response and also explain how the "wrong status" case can happen and, if intentional, what needs to be done to make it work. diff --git a/bin/varnishd/builtin.vcl b/bin/varnishd/builtin.vcl index c21b5374c..65fc37fa1 100644 --- a/bin/varnishd/builtin.vcl +++ b/bin/varnishd/builtin.vcl @@ -230,7 +230,10 @@ sub vcl_refresh_conditions { # We currently only revalidate 200 responses sub vcl_refresh_status { if (obj_stale.status != 200) { - return (error(503, "Invalid object for refresh")); + # Can happen if VCL adds If-Modified-Since / If-None-Match + # for non-200 status objects. If deliberate, this sub can + # be overridden with sub vcl_refresh_status { return; } + return (error(503, "Invalid object for refresh (status)")); } } diff --git a/bin/varnishtest/tests/b00094.vtc b/bin/varnishtest/tests/b00094.vtc index 65c54c53d..9058c19a6 100644 --- a/bin/varnishtest/tests/b00094.vtc +++ b/bin/varnishtest/tests/b00094.vtc @@ -24,7 +24,7 @@ server s1 { varnish v1 -vcl+backend { sub vcl_backend_response { - set beresp.ttl = 0.01s; + set beresp.ttl = 1ms; set beresp.grace = 0s; set beresp.keep = 10m; set beresp.http.was-304 = beresp.was_304; @@ -216,5 +216,48 @@ client c8 { txreq -url /2 rxresp expect resp.status == 503 - expect resp.reason == "Invalid object for refresh" + expect resp.reason == "Invalid object for refresh (status)" +} -run + +################################################################### +# overriding the status check, allowing 304 on non-200 + +server s1 { + rxreq + txresp -status 404 -body "precious" + rxreq + txresp -status 304 +} -start + +varnish v1 -vcl+backend { + + sub vcl_backend_response { + set beresp.ttl = 0.01s; + set beresp.grace = 0s; + set beresp.keep = 10m; + set beresp.http.was-304 = beresp.was_304; + } + + sub vcl_backend_fetch { + set bereq.http.if-none-match = "abcd"; + } + + sub vcl_refresh_status { + return; + } +} + +# Receiving 304 for non-200 objects, but accepting it +# (violating http) +client c8 { + txreq -url /3 + rxresp + expect resp.status == 404 + expect resp.body == "precious" + delay 0.01 + txreq -url /3 + rxresp + expect resp.status == 404 + expect resp.http.was-304 == true + expect resp.body == "precious" } -run From nils.goroll at uplex.de Wed Oct 15 08:01:03 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 15 Oct 2025 08:01:03 +0000 (UTC) Subject: [master] 671b93b74 condfetch: Test retrying a bereq on a dying stale object Message-ID: <20251015080103.B149210E00C@lists.varnish-cache.org> commit 671b93b74b2bbf1af4e668b8a6215b40fa1292af Author: Dridi Boukelmoune Date: Tue Mar 12 17:41:54 2024 +0100 condfetch: Test retrying a bereq on a dying stale object The built-in vcl_refresh_valid returns a 503 error if the stale object used for revalidation gets invalidated while the backend fetch is in progress. One alternative is to not dismiss the stale object, but that can lead to invalidated objects being re-instantiated through concurrent refreshes (#4082). This test case covers the other alternative, which is to retry the fetch. We could use sub vcl_refresh_valid { if (!obj_stale.is_valid) { # core code removes conditional headers INM/IMS return (retry); } } but more realisticly, real world VCL will retry in v_b_e, so we take that route and keep the built-in vcl_refresh_valid {} The plain retry works because core code detects the invalidated stale object and removes the conditional headers. Committer edit: Removed code change from original commit, edited test case and, rewrote commit message. See https://github.com/varnishcache/varnish-cache/pull/4400#discussion_r2379454734 diff --git a/bin/varnishtest/tests/c00129.vtc b/bin/varnishtest/tests/c00129.vtc new file mode 100644 index 000000000..073e8a469 --- /dev/null +++ b/bin/varnishtest/tests/c00129.vtc @@ -0,0 +1,68 @@ +varnishtest "304 on invalidated stale object" + +barrier b1 cond 2 +barrier b2 cond 2 + +server s1 { + rxreq + txresp -hdr {ETag: "foo"} -body corrupted + + rxreq + expect req.http.If-None-Match == {"foo"} + barrier b1 sync + barrier b2 sync + txresp -status 304 -hdr {ETag: "foo"} + + close + accept + + rxreq + expect req.http.If-None-Match == + txresp -hdr {ETag: "foo"} -body valid +} -start + +varnish v1 -vcl+backend { + sub vcl_recv { + if (req.method == "PURGE") { + return (purge); + } + } + sub vcl_backend_response { + set beresp.ttl = 1ms; + set beresp.grace = 0s; + set beresp.keep = 10s; + } + # rather than modifying vcl_refresh_valid, we retry in v_b_e, which is + # more generic and likely to be found in real-world configs. + sub vcl_backend_error { + if (bereq.retries == 0) { + return (retry); + } + } + sub vcl_deliver { + set resp.http.obj-hits = obj.hits; + } +} -start + +client c1 { + txreq + rxresp + expect resp.body == corrupted + expect resp.http.obj-hits == 0 + + delay 0.1 + + txreq + rxresp + expect resp.body == valid + expect resp.http.obj-hits == 0 +} -start + +barrier b1 sync +client c2 { + txreq -req PURGE + rxresp +} -run +barrier b2 sync + +client c1 -wait From nils.goroll at uplex.de Wed Oct 15 08:01:03 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 15 Oct 2025 08:01:03 +0000 (UTC) Subject: [master] bb1259f1b doc: Explain vcl_refresh_* better Message-ID: <20251015080103.CEBF010E010@lists.varnish-cache.org> commit bb1259f1b25af80444df3da8feafd85251405f84 Author: Nils Goroll Date: Wed Oct 15 09:58:57 2025 +0200 doc: Explain vcl_refresh_* better as suggested by Dridi here: https://github.com/varnishcache/varnish-cache/pull/4400#discussion_r2379618149 diff --git a/doc/sphinx/reference/vcl_step.rst b/doc/sphinx/reference/vcl_step.rst index 580cd8c5d..b5b608c33 100644 --- a/doc/sphinx/reference/vcl_step.rst +++ b/doc/sphinx/reference/vcl_step.rst @@ -345,6 +345,8 @@ the stale ones. The returned value only affects response headers, the body that is delivered is always the one from the stale object. +See :ref:`vcl-built-in-refresh` for additional explanations. + | | ``merge`` | Merge the headers we got from the backend response with diff --git a/doc/sphinx/users-guide/vcl-built-in-code.rst b/doc/sphinx/users-guide/vcl-built-in-code.rst index 59383e4ef..8e458d98c 100644 --- a/doc/sphinx/users-guide/vcl-built-in-code.rst +++ b/doc/sphinx/users-guide/vcl-built-in-code.rst @@ -70,6 +70,107 @@ This granularity, and the general goal of the built-in subroutines split is to allow to circumvent a specific aspect of the default rules without giving the entire logic up. +Specific split built-in subroutines +----------------------------------- + +Some split subroutines in the built-in VCL deserve additional explanations: + +.. _vcl-built-in-refresh: + +vcl_refresh_* +~~~~~~~~~~~~~ + +These subroutines handle edge cases of backend refreshes. The precondition for +these to be entered implicitly or explicitly via ``vcl_backend_refresh`` is that +the current backend request can potentially create a cache object (that is, it +is not for a private object as created by a pass or hit-for-pass) and that a +stale object was found in cache which is not already invalidated. If this is the +case, core code constructs a conditional ``GET`` request with the +``If-Modified-Since`` and/or ``If-None-Match`` headers set before +``vcl_backend_fetch`` is entered. If the VCL code does not remove the headers, +the backend might respond with a ``304 Not Modified`` status, in which case +``vcl_backend_refresh`` is called on the response to decide what do do (see +:ref:`vcl_backend_refresh` for reference) and, if the built-in VCL is reached, +the subs documented below will be called via ``vcl_builtin_backend_refresh``. + +vcl_refresh_valid +~~~~~~~~~~~~~~~~~ + +``vcl_refresh_valid`` handles the case where the stale object to be revalidated +by the 304 response got explicitly removed from the cache by a ban or purge +while the backend request was in progress:: + + sub vcl_refresh_valid { + if (!obj_stale.is_valid) { + return (error(503, "Invalid object for refresh")); + } + } + +The error is generated because alternative actions might require additional +consideration. There are basically two options: + +We can ignore the fact that the now successfully revalidated object was *just* +invalidated by not falling through to the built-in VCL with this subroutine in +the user VCL:: + + sub vcl_refresh_valid { + return; + } + +This avoids the error but can potentially result in invalidations being +ineffective. + +The other option is to retry the backend request without the conditional request +headers. This option is implicitly active whenever the user VCL results in a +``return(retry)`` from ``vcl_backend_error``, because core code removes the +conditional request headers if the stale object is found to be invalidated. + +A variant of this option is an explicit retry for the case at hand:: + + sub vcl_refresh_valid { + return (retry); + } + +To summarize, refreshes should work fine as long as there is at least one retry +from ``vcl_backend_error`` for 503 errors. Additionally, VCL allows for +customization if needed. + +vcl_refresh_conditions +~~~~~~~~~~~~~~~~~~~~~~ + +This sub safeguards against invalid 304 responses getting unnoticed:: + + sub vcl_refresh_conditions { + if (!bereq.http.if-modified-since && + !bereq.http.if-none-match) { + return (error(503, "Unexpected 304")); + } + } + +A backend should not respond with a 304 if neither of the conditional request +headers were present in the backend request. + +vcl_refresh_status +~~~~~~~~~~~~~~~~~~ + +This sub safeguards against accidental 304 responses if the stale object does +not have a 200 status:: + + sub vcl_refresh_status { + if (obj_stale.status != 200) { + return (error(503, "Invalid object for refresh (status)")); + } + } + +The background here is that the HTTP standards only allow refreshes of status +200 objects, but Vinyl Cache core code allows to deliberately violate this. In +such cases, the status check needs to be neutered by not running the built-in +code using:: + + sub vcl_refresh_status { + return; + } + Built-in VCL reference ---------------------- From dridi.boukelmoune at gmail.com Mon Oct 27 14:09:05 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 27 Oct 2025 14:09:05 +0000 (UTC) Subject: [master] 27167c1f8 obj: Return BOC state reached from ObjWaitState() Message-ID: <20251027140905.D467511DEA2@lists.varnish-cache.org> commit 27167c1f809ab7af50d334dfa441a7dfef040f61 Author: Dridi Boukelmoune Date: Wed Oct 1 12:54:10 2025 +0200 obj: Return BOC state reached from ObjWaitState() This will allow safe checks related to BOC states that are not guarded by the BOC lock. diff --git a/bin/varnishd/cache/cache_obj.c b/bin/varnishd/cache/cache_obj.c index 804c226aa..6cf110300 100644 --- a/bin/varnishd/cache/cache_obj.c +++ b/bin/varnishd/cache/cache_obj.c @@ -524,9 +524,10 @@ ObjSetState(struct worker *wrk, struct objcore *oc, enum boc_state_e next, /*==================================================================== */ -void +enum boc_state_e ObjWaitState(const struct objcore *oc, enum boc_state_e want) { + enum boc_state_e got; CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); CHECK_OBJ_NOTNULL(oc->boc, BOC_MAGIC); @@ -540,7 +541,10 @@ ObjWaitState(const struct objcore *oc, enum boc_state_e want) break; (void)Lck_CondWait(&oc->boc->cond, &oc->boc->mtx); } + got = oc->boc->state; Lck_Unlock(&oc->boc->mtx); + + return (got); } /*==================================================================== diff --git a/bin/varnishd/cache/cache_varnishd.h b/bin/varnishd/cache/cache_varnishd.h index 56ce1c14b..a2edf2083 100644 --- a/bin/varnishd/cache/cache_varnishd.h +++ b/bin/varnishd/cache/cache_varnishd.h @@ -346,7 +346,7 @@ uint64_t ObjWaitExtend(const struct worker *, const struct objcore *, uint64_t l, enum boc_state_e *statep); void ObjSetState(struct worker *, struct objcore *, enum boc_state_e next, unsigned broadcast); -void ObjWaitState(const struct objcore *, enum boc_state_e want); +enum boc_state_e ObjWaitState(const struct objcore *, enum boc_state_e want); void ObjTouch(struct worker *, struct objcore *, vtim_real now); void ObjFreeObj(struct worker *, struct objcore *); void ObjSlim(struct worker *, struct objcore *); From dridi.boukelmoune at gmail.com Mon Oct 27 14:09:05 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 27 Oct 2025 14:09:05 +0000 (UTC) Subject: [master] 5a5d457cf cocci: Inspect BOC state from ObjWaitState() Message-ID: <20251027140905.EBD9F11DEA5@lists.varnish-cache.org> commit 5a5d457cffa16ed5eabb015977ec23afc23a4c64 Author: Dridi Boukelmoune Date: Wed Oct 1 13:51:00 2025 +0200 cocci: Inspect BOC state from ObjWaitState() After returning from ObjWaitState(), replace any access of oc->boc->state with the one that was captured by the wait loop. diff --git a/tools/coccinelle/obj_wait_state_check.cocci b/tools/coccinelle/obj_wait_state_check.cocci new file mode 100644 index 000000000..085a6182c --- /dev/null +++ b/tools/coccinelle/obj_wait_state_check.cocci @@ -0,0 +1,39 @@ +/* + * Inspect the state returned by ObjWaitState(). + */ + + at capture_state@ +identifier func; +expression oc; +@@ + + func(...) + { + ... +-ObjWaitState(oc, ++state = ObjWaitState(oc, + ...); + ... +-oc->boc->state ++state + ... + } + + at declare_state@ +identifier capture_state.func; +@@ + + func(...) + { ++enum boc_state_e state; + ... + } + + at ignore_state@ +statement stmt; +@@ + +<...stmt...> +-ObjWaitState( ++(void)ObjWaitState( + ...); From dridi.boukelmoune at gmail.com Mon Oct 27 14:09:06 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 27 Oct 2025 14:09:06 +0000 (UTC) Subject: [master] 3ebb00033 varnishd: Apply obj_wait_state_check.cocci Message-ID: <20251027140906.12E7011DEA9@lists.varnish-cache.org> commit 3ebb00033d94f65a6ba4705c3de2eab4bbd0176a Author: Dridi Boukelmoune Date: Fri Oct 3 10:23:55 2025 +0200 varnishd: Apply obj_wait_state_check.cocci diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index ccb44d32d..06daeb958 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -911,7 +911,7 @@ ved_deliver(struct req *req, int wantbody) /* OA_GZIPBITS are not valid until BOS_FINISHED */ if (req->boc != NULL) - ObjWaitState(req->objcore, BOS_FINISHED); + (void)ObjWaitState(req->objcore, BOS_FINISHED); if (req->objcore->flags & OC_F_FAILED) { /* No way of signalling errors in the middle of diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index da85a129f..d59f9e47c 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -894,7 +894,7 @@ vbf_stp_condfetch(struct worker *wrk, struct busyobj *bo) VSLb(bo->vsl, SLT_Notice, "vsl: Conditional fetch wait for streaming object"); /* XXX: We should have a VCL controlled timeout here */ - ObjWaitState(stale_oc, BOS_FINISHED); + (void)ObjWaitState(stale_oc, BOS_FINISHED); stale_state = stale_boc->state; HSH_DerefBoc(bo->wrk, stale_oc); stale_boc = NULL; @@ -1180,6 +1180,7 @@ void VBF_Fetch(struct worker *wrk, struct req *req, struct objcore *oc, struct objcore *oldoc, enum vbf_fetch_mode_e mode) { + enum boc_state_e state; struct boc *boc; struct busyobj *bo; enum task_prio prio; @@ -1265,12 +1266,12 @@ VBF_Fetch(struct worker *wrk, struct req *req, struct objcore *oc, THR_SetBusyobj(NULL); bo = NULL; /* ref transferred to fetch thread */ if (mode == VBF_BACKGROUND) { - ObjWaitState(oc, BOS_REQ_DONE); + (void)ObjWaitState(oc, BOS_REQ_DONE); (void)VRB_Ignore(req); } else { - ObjWaitState(oc, BOS_STREAM); + state = ObjWaitState(oc, BOS_STREAM); AZ(oc->flags & OC_F_BUSY); - if (oc->boc->state == BOS_FAILED) + if (state == BOS_FAILED) AN(oc->flags & OC_F_FAILED); } } diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c index 06afcd78a..23303a60e 100644 --- a/bin/varnishd/cache/cache_hash.c +++ b/bin/varnishd/cache/cache_hash.c @@ -990,7 +990,7 @@ HSH_Cancel(struct worker *wrk, struct objcore *oc, struct boc *boc) if (boc != NULL) { hsh_cancel(oc); - ObjWaitState(oc, BOS_FINISHED); + (void)ObjWaitState(oc, BOS_FINISHED); } if (bocref != NULL) diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 9dc0db092..f4d3810a2 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -448,7 +448,7 @@ cnt_transmit(struct worker *wrk, struct req *req) /* Grab a ref to the bo if there is one (=streaming) */ req->boc = HSH_RefBoc(req->objcore); if (req->boc && req->boc->state < BOS_STREAM) - ObjWaitState(req->objcore, BOS_STREAM); + (void)ObjWaitState(req->objcore, BOS_STREAM); clval = http_GetContentLength(req->resp); /* RFC 7230, 3.3.3 */ status = http_GetStatus(req->resp); From dridi.boukelmoune at gmail.com Mon Oct 27 14:09:06 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 27 Oct 2025 14:09:06 +0000 (UTC) Subject: [master] f03919325 fetch: Atomically capture stale_oc state Message-ID: <20251027140906.2DD5E11DEB8@lists.varnish-cache.org> commit f03919325dc75d3cae8c80d66209d4f174469381 Author: Dridi Boukelmoune Date: Fri Oct 3 10:28:35 2025 +0200 fetch: Atomically capture stale_oc state It should be safe as it was because there shouldn't be a transition from BOS_FINISHED to BOS_FAILED, but now that it can be atomic, it should not only be safe but also future-proof. It originally matched ignore_state from the coccinelle patch because of the separate boc variable, and had to be manually edited. diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index d59f9e47c..0bfd34637 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -894,8 +894,7 @@ vbf_stp_condfetch(struct worker *wrk, struct busyobj *bo) VSLb(bo->vsl, SLT_Notice, "vsl: Conditional fetch wait for streaming object"); /* XXX: We should have a VCL controlled timeout here */ - (void)ObjWaitState(stale_oc, BOS_FINISHED); - stale_state = stale_boc->state; + stale_state = ObjWaitState(stale_oc, BOS_FINISHED); HSH_DerefBoc(bo->wrk, stale_oc); stale_boc = NULL; if (stale_state != BOS_FINISHED) { From nils.goroll at uplex.de Wed Oct 29 18:51:05 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 29 Oct 2025 18:51:05 +0000 (UTC) Subject: [master] 0ec2ab17c vcc_token: refactor out check for scientific notation Message-ID: <20251029185105.0E8ED118938@lists.varnish-cache.org> commit 0ec2ab17c3be935c366185ca9fbbbce8851f8e4f Author: Nils Goroll Date: Wed Oct 29 19:42:55 2025 +0100 vcc_token: refactor out check for scientific notation diff --git a/lib/libvcc/vcc_token.c b/lib/libvcc/vcc_token.c index 4aeaee991..e494eefb6 100644 --- a/lib/libvcc/vcc_token.c +++ b/lib/libvcc/vcc_token.c @@ -473,6 +473,18 @@ vcc_delim_token(struct vcc *tl, struct source *sp, const char *p, * We enforce the RFC8941 restrictions on number of digits here. */ +static int +vcc_lex_number_token_valid(struct vcc *tl) +{ + if (*tl->t->e == 'e' || *tl->t->e == 'E') { + VSB_printf(tl->sb, "Unexpected character '%c'.\n", *tl->t->e); + tl->t->e++; + vcc_ErrWhere(tl, tl->t); + return (0); + } + return (1); +} + static const char * vcc_lex_number(struct vcc *tl, struct source *sp, const char *p) { @@ -503,12 +515,8 @@ vcc_lex_number(struct vcc *tl, struct source *sp, const char *p) vcc_ErrWhere(tl, tl->t); return (NULL); } - if (*tl->t->e == 'e' || *tl->t->e == 'E') { - VSB_printf(tl->sb, "Unexpected character '%c'.\n", *tl->t->e); - tl->t->e++; - vcc_ErrWhere(tl, tl->t); + if (! vcc_lex_number_token_valid(tl)) return (NULL); - } tl->t->num = strtod(p, &s); assert(s == tl->t->e); return (r); From nils.goroll at uplex.de Wed Oct 29 18:51:05 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 29 Oct 2025 18:51:05 +0000 (UTC) Subject: [master] 7e9b65c62 vcc: Add missing check for scientific notation Message-ID: <20251029185105.249AF11893B@lists.varnish-cache.org> commit 7e9b65c62cc14ca13576de8bee530e748bcf7836 Author: Nils Goroll Date: Wed Oct 29 19:44:16 2025 +0100 vcc: Add missing check for scientific notation Fixes another instance of #3971: The added test would trigger an assertion failure: **** v1 CLI RX|Message from VCC-compiler: **** v1 CLI RX|Assert error in vcc_lex_number(), vcc_token.c line 505: **** v1 CLI RX| Condition(s == tl->t->e) not true. **** v1 CLI RX|Running VCC-compiler failed, signal 6 **** v1 CLI RX|VCL compilation failed diff --git a/bin/varnishtest/tests/i00001.vtc b/bin/varnishtest/tests/i00001.vtc index c29ae5b34..89386490c 100644 --- a/bin/varnishtest/tests/i00001.vtc +++ b/bin/varnishtest/tests/i00001.vtc @@ -20,6 +20,11 @@ varnish v1 -errvcl {Unexpected character 'e'.} { sub vcl_recv { set req.http.foo = 42.42e42; } } +varnish v1 -errvcl {Unexpected character 'e'.} { + import std; + sub vcl_synth { set resp.http.foo = std.integer(real=1e10); } +} + server s1 { rxreq txresp diff --git a/lib/libvcc/vcc_token.c b/lib/libvcc/vcc_token.c index e494eefb6..96ece50e3 100644 --- a/lib/libvcc/vcc_token.c +++ b/lib/libvcc/vcc_token.c @@ -501,6 +501,8 @@ vcc_lex_number(struct vcc *tl, struct source *sp, const char *p) vcc_ErrWhere(tl, tl->t); return (NULL); } + if (! vcc_lex_number_token_valid(tl)) + return (NULL); tl->t->num = strtod(p, &s); assert(s == tl->t->e); return (q);