Internally, here's what apache is doing when mod_rewrite makes a per-dir subsutiton. This might explain a little better the sequence is
Receive a request for /foo Merge <location/<locationmatch config sections for registered modules Map URL to file Merge <directory/<files/etc ... Check access control mod_rewrite in directory context maps it to a new URL, /bar mod_rewrite internally redirects the current request to a new request w/ the substituted URL Receive a request for /bar Merge location/location/match config sections for registered modules Map URL to file Merge directory/fies/etc ... Check access control mod_rewrite doesn't make a substitution this time handler (mod_php, mod_proxy_fcgi, etc) runs and starts to write output headers get committed by the core of apache mod_expires and mod_headers get notified when the headers are being committed and consult their configuration Not much is retained between the initial request and the "internal redirect". One thing that is retained is the environment variables, but differentiated by the REDIRECT_ prefix. If you are on 2.4, you could set an environment variable and check for the REDIRECT_ version and then use <if> instead of <location> to configure the expires/headers. mod_headers also directly supports expressions or env= but mod_expires does not.