title: HTTP caching confusion
body: <p>I'm not sure whether this is a server issue, or whether I'm failing to understand how HTTP caching really works.</p>
  
  <p>I have an ASP MVC application running on IIS7. There's a lot of static content as part of the site including lots of CSS, Javascript and image files.</p>
  
  <p>For these files I want the browser to cache them for at least a day - our .css, .js, .gif and .png files rarely change.</p>
  
  <p>My web.config goes like this:</p>
  
  <pre><code>&lt;system.webServer&gt;
      &lt;staticContent&gt;
          &lt;clientCache cacheControlMode="UseMaxAge" 
                       cacheControlMaxAge="1.00:00:00" /&gt;
      &lt;/staticContent&gt;
  &lt;/system.webServer&gt;
  </code></pre>
  
  <p>The problem I'm getting is that the browser (tested Chrome, IE8 and FX) doesn't seem to be caching the files as I'd expect. I've got the default settings (check for newer pages automatically in IE).</p>
  
  <p>On first visit the content downloads as expected</p>
  
  <pre><code>HTTP/1.1 200 OK
  Cache-Control: max-age=86400
  Content-Type: image/gif
  Last-Modified: Fri, 07 Aug 2009 09:55:15 GMT
  Accept-Ranges: bytes
  ETag: "3efeb2294517ca1:0"
  Server: Microsoft-IIS/7.0
  X-Powered-By: ASP.NET
  Date: Mon, 07 Jun 2010 14:29:16 GMT
  Content-Length: 918
  
  &lt;content&gt;
  </code></pre>
  
  <p>I think that the <code>Cache-Control: max-age=86400</code> should tell the browser not to request the page again for a day.</p>
  
  <p>Ok, so now the page is reloaded and the browser requests the image again. This time it gets an empty response with these headers:</p>
  
  <pre><code>HTTP/1.1 304 Not Modified
  Cache-Control: max-age=86400
  Last-Modified: Fri, 07 Aug 2009 09:55:15 GMT
  Accept-Ranges: bytes
  ETag: "3efeb2294517ca1:0"
  Server: Microsoft-IIS/7.0
  X-Powered-By: ASP.NET
  Date: Mon, 07 Jun 2010 14:30:32 GMT
  </code></pre>
  
  <p>So it looks like the browser has sent the <code>ETag</code> back (as a unique id for the resource), and the server's come back with a <em>304 Not Modified</em> - telling the browser that it can use the previously downloaded file.</p>
  
  <p>It seems to me that would be correct for many caching situations, but here I don't want the extra round trip. I don't care if the image gets out of date when the file on the server changes.</p>
  
  <p>There are a lot of these files (even with sprite-maps and the like) and many of our clients have very slow networks. Each round trip to ping for that <em>304</em> status is taking about a 10th to a 5th of a second. Many also have IE6 which only has 2 HTTP connections at a time. The net result is that our application appears to be very slow for these clients with every page taking an extra couple of seconds to check that the static content hasn't changed.</p>
  
  <p>What response header am I missing that would cause the browser to aggressively cache the files?</p>
  
  <p>How would I set this in a .Net web.config for IIS7?</p>
  
  <p>Am I misunderstanding how HTTP caching works in the first place?</p>