<div dir="ltr"><div>Hi Mark,</div><div><br></div><div>You are correct: <a href="https://github.com/varnishcache/varnish-cache/blob/varnish-7.3.0/bin/varnishd/cache/cache_fetch.c#L699-L703">https://github.com/varnishcache/varnish-cache/blob/varnish-7.3.0/bin/varnishd/cache/cache_fetch.c#L699-L703</a></div><div><br></div><div>We only set the OF_IMSCAND flag (that we use to say that we can conditional download) if:<br></div><div>- the object is not a Hit-For-Miss (HFM)<br></div><div>- if the status is 200</div><div>- we either have a convincing Last-modified, or an Etag header</div><div><br></div><div>You can also test it with this VTC:</div><div>varnishtest "conditional requests"<br><br><div style="margin-left:40px"><span style="font-family:monospace">server s1 {<br> rxreq<br> txresp -status 200 -hdr "ETag: 1234" -hdr "Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT" -body "dad"<br><br> rxreq<br> expect req.http.if-none-match == "1234"<br> expect req.http.if-modified-since == "Wed, 21 Oct 2015 07:28:00 GMT"<br> txresp<br>} -start<br><br>varnish v1 -vcl+backend {<br> sub vcl_backend_response {<br> set beresp.ttl = 0.1s;<br> set beresp.grace = 0s;<br> set beresp.keep = 1y;<br> return (deliver);<br> }<br>} -start<br><br>client c1 {<br> txreq<br> rxresp<br><br> delay 0.2<br><br> txreq<br> rxresp<br>} -run</span></div></div><div><br></div><div>Change the 200 to a 404 and the test will now fail.<br></div><div><br></div><div>I quickly skimmed the HTTP spec and see no reason for us to actually check the status, but I'm sure somebody closer to the code will pop up to provide some light on the topic.</div><div><br></div><div>Cheers,<br></div><div><br></div><div><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div>-- <br></div><div>Guillaume Quintard<br></div></div></div></div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Jul 14, 2023 at 7:30 AM Mark Slater <<a href="mailto:mark.slater@mail.com">mark.slater@mail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div dir="ltr">Hi,<div><br></div><div>I'm running Varnish in front of a back end that has to do some work to determine whether a request should receive a 404 response. However, it can cheaply determine whether a previous 404 is still valid.</div><div><br></div><div>I see Varnish issuing conditional requests for cached 200 responses, but I haven't managed to achieve the same for cached 404 responses.</div><div><br></div><div>Here's my sample VCL:</div><div><br></div><div><br></div><div><font face="monospace">vcl 4.1;<br><br>backend default {<br> .host = "localhost";<br> .port = "8081";<br>}<br><br>sub vcl_backend_response {<br> set beresp.keep = 5m;<br>}<br></font></div><div><br></div><div><br></div><div>I'm testing with canned responses on port 8081 For the working 200 case, I return:</div><div><br></div><div><br></div><div><font face="monospace">HTTP/1.1 200 OK<br>cache-control: max-age=5<br>etag: "foo"<br>content-length: 13<br>connection: close<br><br>Hello, World!<br></font></div><div><br></div><div><br></div><div>When I make requests to Varnish, I see, as expected, a first request to the back end, followed by five seconds of nothing to the back end, because Varnish is responding with its cached copy, followed by a conditional request to the back end:</div><div><br></div><div><br></div><div><font face="monospace">GET / HTTP/1.1<br>Host: localhost:8080<br>User-Agent: curl/7.68.0<br>Accept: */*<br>X-Forwarded-For: 127.0.0.1<br>Accept-Encoding: gzip<br>X-Varnish: 3<br><br>GET / HTTP/1.1<br>Host: localhost:8080<br>User-Agent: curl/7.68.0<br>Accept: */*<br>X-Forwarded-For: 127.0.0.1<br>Accept-Encoding: gzip<br>If-None-Match: "foo"<br>X-Varnish: 32773<br></font></div><div><br></div><div><br></div><div>For the failing 404 case, my canned back end responds:</div><div><br></div><div><br></div><div><font face="monospace">HTTP/1.1 404 Not Found<br>cache-control: max-age=5<br>etag: "foo"<br>content-length: 13<br>connection: close<br><br>Hello, World!<br></font></div><div><br></div><div><br></div><div>Now when I make requests to Varnish, I get a cached response for five seconds as before, but when the response goes stale, rather than issuing a conditional request to revalidate it, Varnish is issuing unconditional requests:<br></div><div><br></div><div><br></div><div><font face="monospace">GET / HTTP/1.1<br>Host: localhost:8080<br>User-Agent: curl/7.68.0<br>Accept: */*<br>X-Forwarded-For: 127.0.0.1<br>Accept-Encoding: gzip<br>X-Varnish: 3<br><br>GET / HTTP/1.1<br>Host: localhost:8080<br>User-Agent: curl/7.68.0<br>Accept: */*<br>X-Forwarded-For: 127.0.0.1<br>Accept-Encoding: gzip<br>X-Varnish: 32771<br></font></div><div><br></div><div><br></div><div>Is that something I can adjust with configuration? If it's relevant, I'm running:</div><div><br></div><div>Debug: Version: varnish-6.2.1 revision 9f8588e4ab785244e06c3446fe09bf9db5dd8753<br>Debug: Platform: Linux,5.4.0-153-generic,x86_64,-jnone,-sdefault,-sdefault,-hcritbit<br></div><div><br></div><div>Incidentally, 200 responses with content-length 0 also seem to exhibit this behaviour.</div><div><br></div><div>Thanks in advance,</div><div><br></div><div>Mark</div><div><br></div><div><br></div><div><br></div><div><br></div></div>
</div></div>
_______________________________________________<br>
varnish-misc mailing list<br>
<a href="mailto:varnish-misc@varnish-cache.org" target="_blank">varnish-misc@varnish-cache.org</a><br>
<a href="https://www.varnish-cache.org/lists/mailman/listinfo/varnish-misc" rel="noreferrer" target="_blank">https://www.varnish-cache.org/lists/mailman/listinfo/varnish-misc</a><br>
</blockquote></div>