title: HTTP Headers: Controlling Cache and History Mechanism
body: <p>I'm trying to figure out the best HTTP headers to send for four use cases. I'm hoping to come up with headers that do not depend on user agent / protocol version sniffing but I'll accept that if nothing else fits. All URLs are fetched through fully custom handler so I can select all headers as I like, <em>this is all about intermediate proxies and user agents</em>. If possible, this should be compatible with both HTTP/1.0 and HTTP/1.1 clients. If multiple solutions exists, the best one will be the shortest one when sent over the wire.</p>
  
  <p><strong>Static public content</strong></p>
  
  <p>All "Static public content" is stuff that HTTP is really all about: if the URL is the same, the content is the same. I can do this easily: for example, I put user profile icon into <a href="http://domain.com/profiles/xyz/icon/1234abcd" rel="noreferrer">http://domain.com/profiles/xyz/icon/1234abcd</a> where "1234abcd" is the SHA-1 of the file contents of the icon. If I change to icon in the future, I'll create a new URL and and modify all existing referrers that should use the new icon. What are the best headers to declare that this may be cached forever and may be shared? I'm currently thinking something along the lines:</p>
  
  <pre><code>Date: &lt;current time&gt;
  Expires: &lt;current time + one year&gt;
  </code></pre>
  
  <p>Is this enough to allow caching by user agents and proxies? Do I need <code>Last-Modified</code> or <code>Pragma</code>?</p>
  
  <p><strong>Static non-public content</strong></p>
  
  <p>All "Static non-public content" is stuff that is static but may not be available to everybody. In fact, this content will be available only to selected logged in users (session is kept with session cookie holding session UUID). If the URL is the same, the content is the same. However, the response is not public. An use case could be an image shared to selected friends in a social network service. I'm currently thinking something along the lines:</p>
  
  <pre><code>Date: &lt;current time&gt;
  Expires: &lt;current time&gt;
  Cache-Control: private, max-age=&lt;huge number&gt;, s-maxage=0
  </code></pre>
  
  <p>Is this enough to allow caching by user agents and and disable proxies? Do I need <code>Pragma</code>?</p>
  
  <p><strong>Volatile public content</strong></p>
  
  <p>All "Volatile public content" is stuff that is volatile and available to everybody. Something like frontpage of <a href="http://slashdot.org/" rel="noreferrer">http://slashdot.org/</a> when not logged in. The intent is to allow rapidly updating content in a non-changing URL. <em>Note that I do NOT want to break the user agent history mechanism</em> (that is, clicking something from a volatile page and then hitting the back button should not result in fetching the volatile page from the server -- however, clicking a link that goes to front page should fetch the resource from the server). I'm currently thinking something along the lines:</p>
  
  <pre><code>Date: &lt;current time&gt;
  Expires: &lt;current time&gt;
  Cache-Control: public, max-age=0, s-maxage=0
  </code></pre>
  
  <p>Is this enough to prevent caching but to allow history mechanism (back button)? I know that if I send <code>Cache-Control: no-store, must-revalidate</code> I can force reloading but this is not what I want because that will break the back button, too. Do I need <code>Last-Modified</code> or <code>Pragma</code>?</p>
  
  <p>Even though this is public, it probably does not make sense to allow intermediate proxies to cache this because it's volatile.</p>
  
  <p><strong>Volatile non-public content</strong></p>
  
  <p>All "Volatile non-public content" is stuff that is volatile and not available to everybody (private). Something like frontpage of <a href="http://slashdot.org/" rel="noreferrer">http://slashdot.org/</a> when you are logged in. The intent is to allow rapidly updating content in a non-changing URL. <em>Note that I do NOT want to break the user agent history mechanism</em> (that is, clicking something from a volatile page and then hitting the back button should not result in fetching the volatile page from the server -- however, clicking a link that goes to front page should fetch the resource from the server). I'm currently thinking something along the lines:</p>
  
  <pre><code>Date: &lt;current time&gt;
  Expires: &lt;current time&gt;
  Cache-Control: private, max-age=0, s-maxage=0
  </code></pre>
  
  <p>Is this enough to prevent caching but to allow history mechanism (back button)? Do I need <code>Pragma</code>?</p>
  
  <hr>
  
  <p>Things that still need testing with my suggested headers:</p>
  
  <ul>
  <li>Verify that private content will not be leaked through HTTP/1.0 proxies.</li>
  <li>Verify that caching works correctly in proxies.</li>
  <li>Verify that caching works correctly in user agents.</li>
  <li>Verify that user agent history mechanism works in user agents (all cases).</li>
  <li>Verify that following a link to a volatile page fetches fresh content from the server.</li>
  <li>Verify all the results when using HTTPS instead of HTTP.</li>
  </ul>