title: Why the beresp.ttl is set to 0 when a Cookie is added to the request in Varnish?
body: <p>Ok, so I'm trying to make Varnish works properly and I've a weird behavior I can't explain (may be due by a lack of understanding).</p>
  
  <p>Here is what I'm trying to do:</p>
  
  <pre><code>GET http://scm.dev:6081/articles
  If-None-Match: "50a0794aaca51fce202e86da428b7dca9b4bbff93"
  </code></pre>
  
  <p>And I get:</p>
  
  <pre><code>HTTP/1.1 200 OK
  Age: 3                                    // Correctly using a cached result
  Content-Length: 3878
  Content-Type: application/json
  Date: Fri, 14 Dec 2012 10:59:34 GMT
  Via: 1.1 varnish
  X-Cacheable: YES                          // It is correct
  Cache-Control: max-age=10, public, s-maxage=20
  Etag: "50a0794aca51fce202e86da428b7dca9b4bbff93"
  Vary: Accept,Accept-Encoding
  </code></pre>
  
  <p>Now, if I add a Cookie to my request:</p>
  
  <pre><code>GET http://scm.dev:6081/articles
  If-None-Match: "50a0794aaca51fce202e86da428b7dca9b4bbff93"
  Cookie: foo=bar
  </code></pre>
  
  <p>I get a non cached response and a non cacheable warning:</p>
  
  <pre><code>HTTP/1.1 200 OK
  Age: 0                                    // Always set to 0
  Content-Length: 3878
  Content-Type: application/json
  Date: Fri, 14 Dec 2012 10:59:34 GMT
  Via: 1.1 varnish
  X-Cacheable: NO:Not Cacheable             // It is not correct
  Cache-Control: max-age=10, public, s-maxage=20
  Etag: "50a0794aca51fce202e86da428b7dca9b4bbff93"
  Vary: Accept,Accept-Encoding
  </code></pre>
  
  <p>If you check the later vcl configuration, the <code>X-Cacheable: NO:Not Cacheable</code> header is set if the beresp.ttl is less than or equal to 0. </p>
  
  <p>Why?</p>
  
  <p>I also assume that a Request with a <code>Cookie</code> which returns a <code>Cache-Control: public</code> should be cached as far as the backend assume the responsibility to correctly set the <code>public</code> parameter when it should be.</p>
  
  <p>I would have assumed that the <code>X-Cacheable: NO:Got Session</code> would have been set when making a Request with a Cookie, but it even does not go further.</p>
  
  <p>The command line to start varnish daemon:</p>
  
  <p><code>/usr/sbin/varnishd -P /var/run/varnishd.pid -a :6081 -T 192.168.1.100:6082 -f /etc/varnish/custom.vcl -S /etc/varnish/secret -s malloc,256m</code></p>
  
  <p>Here is my <code>custom.vcl</code></p>
  
  <pre><code>backend scm {
  .host = "scm.dev";
  .port = "80";
  }
  
  sub vcl_recv {
      set req.http.Surrogate-Capability = "abc=ESI/1.0";
  }
  
  sub vcl_fetch {
      if (beresp.http.Surrogate-Control ~ "ESI/1.0") {
          unset beresp.http.Surrogate-Control;
          set beresp.do_esi = true;
      }
  
      # Varnish determined the object was not cacheable
      if (beresp.ttl &lt;= 0s) {
          set beresp.http.X-Cacheable = "NO:Not Cacheable";
  
      # You don't wish to cache content for logged in users
      } elsif (req.http.Cookie ~ "(foo)") {
          set beresp.http.X-Cacheable = "NO:Got Session";
  
          return(hit_for_pass);
      # You are respecting the Cache-Control=private header from the backend
      } elsif (beresp.http.Cache-Control ~ "private") {
          set beresp.http.X-Cacheable = "NO:Cache-Control=private";
  
          return(hit_for_pass);
      # Varnish determined the object was cacheable
      } else {
          set beresp.http.X-Cacheable = "YES";
      }
  
      return(deliver);
  }
  
  sub vcl_hit {
      if (req.request == "PURGE") {
          set obj.ttl = 0s;
          error 200 "Purged";
      }
  }
  
  sub vcl_miss {
      if (req.request == "PURGE") {
          error 404 "Not purged";
      }
  }
  </code></pre>