I am attempting to add an expires header for a specific file. It doesn't seem to be working and keeps setting it to one week. I'm not sure if it's a syntax error or the way I am trying to target the file.
Here is the code I am using in my HT Access.
<FilesMatch "^(vendor.min.js)$">
ExpiresByType text/javascript "access plus 4 weeks"
</FilesMatch>
In what context are your other Expires directives set? There are some counter-intuitive rules of how sections are merged, for example Location has higher precedence (evaluated later) than Directory/Files/FilesMatch.
I'd suggest changing the context of wherever your "1 week" rules are today.
https://httpd.apache.org/docs/2.2/sections.html
Related
I have configured ETags (using ACS Commons ETag support) on my AEM server and disabled ETag on Apache. But once the file gets cached on the Dispatcher, Apache always returns 200 with response body instead of 304 Not modified. I have validated that the ETag value stored in the ".h" file and in the response is the same as the value of the "If-None-Match" header of the request.
If I remove the cached files from the dispatcher and resend the request then AEM correctly returns 304.
I have also disabled mod_deflate as I have found at some places that the deflate's "-gzip" suffix could cause issues with ETag matching.
Also, instead of ETag, I have tried a similar thing with Last-Modified and If-Modified-Since headers. But no luck with that as well. I have noticed that we generally have Last-Modified headers in place in most cases and I have never seen 304. So, it seems like it is not a version-specific issue. I couldn't find any configuration documentation related to this. Could someone please guide me where am I going wrong?
Check this https://issues.apache.org/bugzilla/show_bug.cgi?id=45023
I have enabled deflate
RequestHeader edit "If-None-Match" "^\"(.*)-gzip\"$" "\"$1\""
Header edit "ETag" "^\"(.*[^g][^z][^i][^p])\"$" "\"$1-gzip\""
We don't use Etags since it is diffcult to sync them across a cluster and Last Modified works fine.
# turn off Etags completely, since they will differ across the cluster
FileETag None
# FileETag None is not enough for every server.
Header unset ETag
# instead we use Expires and Cache-Control headers
ExpiresActive On
# set Expires default to 15 minutes, so browser caches for a visit
ExpiresDefault "access plus 15 minutes"
# but a maybe few types are exempt from this
ExpiresByType text/cache-manifest "access plus 0 seconds"
ExpiresByType text/html "access plus 0 seconds"
ExpiresByType text/xml "access plus 0 seconds"
ExpiresByType application/xml "access plus 0 seconds"
ExpiresByType application/json "access plus 0 seconds"
# set CacheControl public header
# so content is cached in Firefox, even over https
# "public" keyword MUST be the first value in the header, or it will not work in FF
Header onsuccess edit Cache-Control "^(.*)$" "public, $1"
You can adjust the timeouts accordingly, depending on your content.
If I add only these 2 lines to the .htacces file, will all the files on the website be kept in the cache for 1 day?
ExpiresActive On
ExpiresDefault "access plus 1 day"
Is it enough and it works?
ExpiresActive On
ExpiresDefault "access plus 1 day"
If you have no other overriding directives then these directives do indeed instruct the browser to cache the response for 1 day, by sending back the appropriate Expires and Cache-Control: max-age HTTP response headers. (Expires is required for old browsers. All modern browsers will use the Cache-Control header instead.)
Is it enough and it works?
Whether it is "enough" is entirely dependent on the nature of your site. Depending on your site, some responses perhaps shouldn't be cached at all, whilst other static resources should be cached for much longer.
And it's entirely possible you have other directives or even a front-end proxy or CDN that overrides these response headers.
[i]ExpiresActive On
ExpiresByType image/gif A2592000
ExpiresByType image/jpeg A2592000
ExpiresByType image/png A2592000
BrowserMatch "MSIE" brokenvary=1
BrowserMatch "Mozilla/4.[0-9]{2}" brokenvary=1
BrowserMatch "Opera" !brokenvary
SetEnvIf brokenvary 1 force-no-vary[/i]
saw this code in a sample .htaccess recently.
Presumably ExpiresByType sets an expiry time on images - is that related to the visitors browser cache? and what does A2592000 translate to?
and what does the "brokenvary=1" imply? I gather it's looking for a UserAgent, but then what?
thanks!
Presumably ExpiresByType sets an expiry time on images - is that related to the visitors browser cache?
Yes. mod_expires allows an easy setup of expiration rules based on the type.
But the expiration time specifies only the freshness time of a certain response. This does not necessarily mean that the response is cacheable. But in general, any successful response is cacheable unless there are restrictions:
Unless specifically constrained by a cache-control (section 14.9) directive, a caching system MAY always store a successful response (see section 13.8) as a cache entry, MAY return it without validation if it is fresh, and MAY return it after successful validation.
So unless you specify the response not to be stored at all (i.e. using no-store), the response may be stored by both public caches (shared caches) and private caches (local caches).
And what does A2592000 translate to?
The freshness time of a response can be expressed using either an absolute time value (e.g “2010-10-09”) or a relative time value (e.g. “tomorrow”). The date format A2592000 uses a latter time value as A denotes access time and 2592000 is the number of seconds that are added. So A2592000 means “2592000 seconds from the time of access on”.
And what does the "brokenvary=1" imply? I gather it's looking for a UserAgent, but then what?
Apache has some special purpose environment variables where force-no-vary is one of them:
This causes any Vary fields to be removed from the response header before it is sent back to the client. Some clients don't interpret this field correctly; setting this variable can work around this problem. Setting this variable also implies force-response-1.0.
Now the Vary header field is used to specify a list of header field names the server used to select the response among multiple representations:
A server SHOULD use the Vary header field to inform a cache of what request-header fields were used to select among multiple representations of a cacheable response subject to server-driven negotiation.
So if you’re using content negotiation and a requested generic URL like /document.html is requested and there are multiple representations of that resource (e.g. in English and German) and your server selects the German variant as Accept-Language states the value de, the server would include a Vary field containing Accept-Language to let the caches know that the selection was based on the value of Accept-Language.
But some user agents don’t get this right. And in that cases the Vary header field should not be sent that can be done by setting the special purpose environment variable force-no-vary.
ExpiresByType is an Apache Directive of the mod_expires module that generates 'Expires' and 'Cache-control' http response headers. These headers tell a browser that it is allowed to cache the resource for a specific amount of time.
From the documententation ( http://httpd.apache.org/docs/2.0/mod/mod_expires.html ) :
'A' means the client's access time should be used.
An example from the same page might explain things:
# enable expirations
ExpiresActive On
# expire GIF images after a month in the client's cache
ExpiresByType image/gif A2592000
# HTML documents are good for a week from the
# time they were changed
ExpiresByType text/html M604800
I want to give different expiry headers to different images on my site. they are contained in different folders right now, what I want to do is give then different expires headers with one main .htaccess file. I know this can be done with multiple .htaccess files in those folders but I dont want it to be implemented that way, It will clearly be tough to manage.
Try using FilesMatch directive in your .htaccess file.
Eg:
# cache most product images at client side
ExpiresActive on
<FilesMatch "^images/products/[^\.]*\.(gif|jpe?g|png)$">
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
Header append Cache-Control "public"
</FilesMatch>
EDIT: This seems to be wrong! FilesMatch is said to match only files, so you cannot match directories as well. Sorry for bad post.
I have Apache HTTPD configured to add a cache header to requests for most static content:
ExpiresActive On
ExpiresDefault "access plus 1 year"
# Force JNLP and BSH files to expire immediately so updates are checked for
# and seen (We need this so we see changes in the dynamic content in both)
ExpiresByType application/x-java-jnlp-file "now"
ExpiresByType application/x-bsh "now"
How can I disable this caching for any request where the UserAgent contains the string JNLP? When the request comes from the User Agent JNLP (for example "User-Agent: JNLP/6.0 javaws/1.6.0_12 (b04) Java/1.6.0_12") I don't want any Cache-Control or other cache-related headers on the HTTP response.
I can find configuration examples for several things based on user agent, but I cannot figure out how to configure caching depending on the user agent.
Your ExpiresByType directive looks like a good idea... if that's not enough, then try using BrowserMatch:
BrowserMatch JNLP ua_is_jnlp
This sets the environment variable ua_is_jnlp to some value for any request whose user agent header contains the string JNLP (there is also a case-insensitive variant, BrowserMatchNoCase). Then you can clear any caching headers with
Header unset Cache-Control env=ua_in_jnlp
Header unset Expires env=ua_in_jnlp
although if you want to disable caching entirely, you'd be better off setting
Header set Cache-Control no-cache env=ua_in_jnlp
Header set Expires 0 env=ua_in_jnlp