Rewriting Apache URLs to use only paths and set response headers
- by jabley
I have apache httpd in front of an application running in Tomcat.
The application exposes URLs of the form:
/path/to/images?id={an-image-id}
The entities returned by such URLs are images (even though URIs are opaque, I find human-friendly ones are easier to work with!).
The application does not set caching directives on the image response, so I've added that via Apache.
# LocationMatch to set caching directives on image responses
<LocationMatch "^/path/to/images$">
# Can't have Set-Cookie on response, otherwise the downstream caching proxy
# won't cache!
Header unset Set-Cookie
# Mark the response as cacheable.
Header append Cache-Control "max-age=8640000"
</LocationMatch>
Note that I can't use ExpiresByType since not all images served by the app have versioned URIs. I know that ones served by the /path/to/images resource handler are versioned URIs though, which don't perform any sort of content negotiation, and thus are ripe for Far Future Expires management.
This is working well for us.
Now a requirement has come up to put something else in front of the app (in this case, Amazon CloudFront) to further distribute and cache some of the content. Amazon CloudFront will not pass query string parameters through to my origin server.
I thought I would be able to work around this, by changing my apache config appropriately:
# Rewrite to map new Amazon CloudFront friendly URIs to the application resources
RewriteRule ^/new/path/to/images/([0-9]+) /path/to/images?id=$1 [PT]
# LocationMatch to set caching directives on image responses
<LocationMatch "^/path/to/images$">
# Can't have Set-Cookie on response, otherwise the downstream caching proxy
# won't cache!
Header unset Set-Cookie
# Mark the response as cacheable.
Header append Cache-Control "max-age=8640000"
</LocationMatch>
This works fine in terms of serving the content, but there are no longer caching directives with the response.
I've tried playing around with [PT], [P] for the RewriteRule, and adding a new LocationMatch directive:
# Rewrite to map new Amazon CloudFront friendly URIs to the application resources
# /new/path/to/images/12345 -> /path/to/images?id=12345
RewriteRule ^/new/path/to/images/([0-9]+) /path/to/images?id=$1 [PT]
# LocationMatch to set caching directives on image responses
<LocationMatch "^/path/to/images$">
# Can't have Set-Cookie on response, otherwise the downstream caching proxy
# won't cache!
Header unset Set-Cookie
# Mark the response as cacheable.
Header append Cache-Control "max-age=8640000"
</LocationMatch>
<LocationMatch "^/new/path/to/images/">
# Can't have Set-Cookie on response, otherwise the downstream caching proxy
# won't cache!
Header unset Set-Cookie
# Mark the response as cacheable.
Header append Cache-Control "max-age=8640000"
</LocationMatch>
Unfortunately, I'm still unable to get the Cache-Control header added to the response with the new URL format. Please point out what I'm missing to get /new/path/to/images/12345 returning a 200 response with a Cache-Control: max-age=8640000 header.
Pointers as to how to debug apache like this would be appreciated as well!