Friday, January 28, 2011

How can I configure apache so that it prevents proxy servers to cache a specific URL on my website ?

I've got a clickonce repository hosted on a Apache server ; for obvious reasons*, I don't want this repository to be cached by a proxy server.

I know there's no way to prevent a proxy to cache something if it wants to, but I'm looking for a way of either hinting the proxy not to cache my URL, or providing it with an "obsolescence date".

Is there a way to do that with Apache? If not, is it possible to do that with another webserver (IIS?)

If there are some options working only with some specific proxy vendors, I'm interested in those too.


** If the repository is cached, the software checks its version against an obsolete copy of the "latest version" (hold by the proxy) instead of checking itself against the "real" latest version, which is on my server.

  • You could either set the "Expires" meta tag on your HTML pages or setw one/several headers via the Apache/whatever server. Here's some really good information on the subject.

    Here's how to do it using ASP on IIS.

    Using headers, basically you could set the max-age to 1 secs for example, and the no-cache, no-store, and must-revalidate headers, for good measure, because there are some misbehaving/buggy proxies, and this way you make sure to cover all bases.

    Zoredache : I would like to point out that using the meta expires tag in your html doesn't do anything for you if you are using squid (http://www.squid-cache.org/mail-archive/squid-users/199810/0425.html). Meta tags are ignored by many proxies, it is better set your expires and cache control within http.
    From Ivan
  • With Apache, you'll want to examine mod_expires. Most proxies respect the Expires HTTP header along with max-age, etc.

  • This is pretty easy to do with apache, for example to specific that nothing coming from your server should ever be cached, try this

    <Location / >
       ExpiresActive On
       ExpiresDefault "now"
    </Location>
    

    You probably don't want to do this exactly, so look at the documentation for mod_expires and customise this for your needs.

    Also, remember that in this scenario a browser and a proxy are treated the same. By sending expires headers with your responses that disable caching, you will be adding significant load and cost to running your site, not to mention slowing access your visitors.

    Brann : @Dave : thanks, it works ! Is there a way to answer "Cache-Control: no-cache, no-store, max-age=0, must-revalidate" instead of "Expires: Thu, 05 Jun 2009 15:15:35 GMT" ?
    Brann : @Dave (other than hardcoding it using the Header module, as I've posted it in another answer)
    Dave Cheney : @Brann, not with apache. Nginx's mod expires has an Expires epoch option which applies a few more headers. IMHO your headers are probably overkill, remember they are only a _suggestion_ to the client that it _should_ (ok the RFC says must, but you don't control the other end) request a fresh copy of the resource every time.
  • If you're talking about a Cache Engine of some sort, like a WAN Accelerator, and the device in question attaches a distinctive UserAgent to the request, then you're in luck. In this case, you can have rules like the following, where SomeString is the string that will match the User Agent of the Cache Engine:

    BrowserMatch SomeString no-cache-headers
    Header set Cache-Control "no-cache, must-revalidate"    env=no-cache-headers
    Header set Pragma        "no-cache"                     env=no-cache-headers
    Header set Expires       "Sat, 1 Jan 2000 00:00:00 GMT" env=no-cache-headers
    

    Here, I set the "Expires" header to an arbitrary date in the past.

    If you're talking about a proxy that just forwards the request and doesn't make the request by itself, then the most you can do is to prevent all caching of these objects, or (a little better) set a short lifetime for these objects. You could do that with something like this:

    ExpiresActive On
    ExpiresDefault "access plus 1 hour"
    

    where you can pick the time you want. Or you can just give "access" as the expires default, meaning the next request should get a new object. But here, as others point out, you're also penalizing browsers.

    From Eddie

0 comments:

Post a Comment