diff --git a/vmod/tests/std_b00015.vtc b/vmod/tests/std_b00015.vtc new file mode 100644 index 0000000000..d2004e1011 --- /dev/null +++ b/vmod/tests/std_b00015.vtc @@ -0,0 +1,87 @@ +varnishtest "std.rfc_ttl()" + +server s1 { + rxreq + txresp -status 202 -hdr "Cache-Control: public, s-maxage=4711" + + rxreq + expect req.url == "/200" + txresp -status 200 \ + -hdr "Cache-Control: public, s-maxage=0, stale-while-revalidate=99" \ + -hdr {Etag: "foo"} \ + -bodylen 64 + + rxreq + expect req.url == "/200" + expect req.http.If-None-Match == {"foo"} + txresp -status 304 -hdr "Cache-Control: s-maxage=11, stale-while-revalidate=77" +} -start + +varnish v1 -vcl+backend { + import std; + + sub vcl_backend_refresh { + set beresp.http.Cache-Control = "s-maxage=10, stale-while-revalidate=42"; + std.rfc_ttl(); + } + + sub vcl_backend_response { + if (beresp.status == 202) { + set beresp.status = 200; + std.rfc_ttl(); + set beresp.status = 202; + } + # avoid zero ttl which is uncacheable + set beresp.ttl += 0.001s; + } +} -start + +logexpect l1 -v v1 -g vxid -q "vxid == 1002" { + fail add * Error + fail add * VCL_Error + fail add * End + expect * 1002 TTL {^RFC -1 } + expect 1 = BerespStatus {^200} + expect 1 = TTL {^RFC 4711 } + fail clear +} -start + +logexpect l2 -v v1 -g vxid -q "vxid == 1004" { + fail add * Error + fail add * VCL_Error + fail add * End + expect * 1004 BereqURL {^/200} + expect * = BerespStatus {^200} + expect * = TTL {^RFC 0 99 } + fail clear +} -start + +logexpect l3 -v v1 -g vxid -q "vxid == 1006" { + fail add * Error + fail add * VCL_Error + fail add * End + expect * 1006 BereqURL {^/200} + expect * = BerespStatus {^304} + expect * = TTL {^RFC 11 77 } + expect * = TTL {^RFC 10 42 } + fail clear +} -start + + +client c1 { + txreq + rxresp + expect resp.status == 202 + + txreq -url "/200" + rxresp + expect resp.status == 200 + + txreq -url "/200" + rxresp + expect resp.status == 200 +} -run + +logexpect l1 -wait +logexpect l2 -wait +logexpect l3 -wait diff --git a/vmod/vmod_std.c b/vmod/vmod_std.c index b2c9566b7b..fc0f4d62cd 100644 --- a/vmod/vmod_std.c +++ b/vmod/vmod_std.c @@ -385,3 +385,23 @@ vmod_timed_call(VRT_CTX, VCL_SUB sub) VRT_call(ctx, sub); return (VTIM_mono() - b); } + +VCL_VOID v_matchproto_(td_std_rfc_ttl) +vmod_rfc_ttl(VRT_CTX) +{ + struct busyobj *bo; + struct objcore *oc; + + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + // $Restrict guarantees + bo = ctx->bo; + CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + oc = bo->fetch_objcore; + CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); + + RFC2616_Ttl(bo, ctx->now, + &oc->t_origin, + &oc->ttl, + &oc->grace, + &oc->keep); +} diff --git a/vmod/vmod_std.vcc b/vmod/vmod_std.vcc index 87978f6158..25593c9bbb 100644 --- a/vmod/vmod_std.vcc +++ b/vmod/vmod_std.vcc @@ -696,6 +696,19 @@ $Function DURATION timed_call(SUB) Call the given SUB and return a high precision measurement of the execution time. +$Function VOID rfc_ttl() + +$Restrict vcl_backend_response vcl_backend_refresh + +Re-calculate the object timers (``beresp.ttl``, ``beresp.grace`` and +``beresp.keep``) based on the current state of ``beresp`` as if it had been +processed by core code before ``vcl_backend_response`` was called. This does not +change ``beresp.uncacheable``. + +This is useful to get the default ttl calculations after modifications of +relevant properties like ``beresp.status``, ``beresp.http.Date``, +``beresp.http.Age`` or ``beresp.http.Cache-Control``. + SEE ALSO ========