Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add expiry headers using Apache for paths which don't exist in the filesystem

For the purposes of CDN invalidation I need to add a prefix to the path element of a site's URL. This is changed whenever a new version of the asset is released.

The URL is then rewritten using mod_rewrite from: http://example.com/cdn/20111030/images/image.jpg to http://example.com/images/image.jpg which is where the asset actually resides.

I would like to add long expiry headers (at least 3 months) to the response (for the first URL which doesn't actually exist in the filesystem). Does anyone know how to do this?

like image 338
Benedict Dodd Avatar asked Oct 30 '11 21:10

Benedict Dodd


2 Answers

It appears that if you add the RewriteEngine/Rule in the Apache configuration for your own solution, the Location is picked up correctly and serves the Expires/Cache-Control on /cdn calls and doesn't serve them for non-cdn calls, with a minor changee:

    # in apache config
    RewriteEngine On
    RewriteRule ^/cdn/[^/]*/(.*) /$1 [L]

    <Location "/cdn">
      Header unset ETag
      FileETag None
      ExpiresActive on
      ExpiresDefault "access plus 1 year"
    </Location>

I can't see a reason this should be a problem in the Apache config.

like image 102
Andy Avatar answered Sep 19 '22 10:09

Andy


From http://drupal.org/node/974350#comment-5305368
These rules are for 480 weeks but you can adjust the time accordingly.

<IfModule mod_rewrite.c>
  RewriteEngine on
  <IfModule mod_headers.c>
    # Transform /cdn/***/ to /
    RewriteCond %{REQUEST_URI} ^/cdn/([0-9a-zA-Z])*/(.+)$
    RewriteRule .* /%2 [L,E=CDN:1]
    # Apache will change CDN to REDIRECT_CDN.

    # Set a far future Cache-Control header (480 weeks), which prevents
    # intermediate caches from transforming the data and allows any
    # intermediate cache to cache it, since it's marked as a public resource.
    Header set Cache-Control "max-age=290304000, no-transform, public" env=REDIRECT_CDN

    # Set a far future Expires header. The maximum UNIX timestamp is somewhere
    # in 2038. Set it to a date in 2037, just to be safe.
    Header set Expires "Tue, 20 Jan 2037 04:20:42 GMT" env=REDIRECT_CDN

    # Pretend the file was last modified a long time ago in the past, this will
    # prevent browsers that don't support Cache-Control nor Expires headers to
    # still request a new version too soon (these browsers calculate a
    # heuristic to determine when to request a new version, based on the last
    # time the resource has been modified).
    # Also see http://code.google.com/speed/page-speed/docs/caching.html.
    Header set Last-Modified "Wed, 20 Jan 1988 04:20:42 GMT" env=REDIRECT_CDN

    # Do not use etags for cache validation.
    Header unset ETag env=REDIRECT_CDN
  </IfModule>
</IfModule>

Also see the AdvAgg rules as these handle servers that do not have mod_headers or mod_expires installed. It uses a FilesMatch directive; advagg files have a fairly unique filename, thus I can do this. The AdvAgg fallbacks wont work in this case because mod_expires can't use environmental variables; neither can FileETag. From what I can see, mod_headers is the desired way to set far future times in apache.

like image 28
mikeytown2 Avatar answered Sep 20 '22 10:09

mikeytown2