I'm already aware of caching files with Apache. I'm writing unit tests for a library and I have one PHP file that prints the current microtime. I use it to verify if the file has changed between two requests.
My problem : the returned content is always different, even if I force caching in .htaccess with :
ExpiresActive on
ExpiresDefault "access plus 1 year"
Header append Cache-Control "public"
When I watch the response headers in the developer tools, everything seems fine :
Cache-Control:max-age=31536000, public
Connection:Keep-Alive
Content-Length:14
Content-Type:text/html
Date:Thu, 06 Nov 2014 09:21:30 GMT
Expires:Fri, 06 Nov 2015 09:21:30 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.4.7 (Win32) PHP/5.5.8
X-Powered-By:PHP/5.5.8
Related
I'm trying to apply a no cache header to the style.css file in the child theme of my WordPress site, using the .htaccess file. I want to avoid having to clear my browser cache every time I make CSS styling changes to the site, in order to see the changes. Currently my cache control looks like this -
<Files ~ https://my-domain.org.au/wp-content/themes/church-suite_child_theme/style.css>
FileEtag None
<ifModule mod_headers.c>
Header Unset ETag
Header Set Cache-Control "max-age=0, no-store, no-cache, must-revalidate"
Header Set Pragma "no-cache"
Header Set Expires "Thu, 30 June 2022 00:00:00 GMT"
</ifModule>
</Files>
It doesn't appear to be working. I'm using the Network Inspector in Chrome Dev Tools to view the network requests. The following is returned when I refresh the page and inspect the request -
RESPONSE HEADERS,
cache-control: max-age=31536000
content-encoding: br
content-type: text/css
date: Fri, 12 Nov 2021 01:41:45 GMT
etag: W/"6188f369-73b"
expires: Sat, 12 Nov 2022 01:41:45 GMT
host-header: 8441280b0c35cbc1147f8ba998a563a7
last-modified: Mon, 08 Nov 2021 09:52:41 GMT
server: nginx
vary: Accept-Encoding
x-proxy-cache-info: DT:1
I have a problem setting the cache expire date on my website. This is the code I use in .htaccess file:
<FilesMatch "\.(xml|txt|css|js)$">
Header set Cache-Control "max-age=7200, proxy-revalidate"
</FilesMatch>
The file types I mentioned should have an expire date of 2 hours, but after hard refresh I see that all these files have an expiration date of one week. As an example, I select the .css file in Chrome inspect page and I see this information:
Accept-Ranges:bytes
Cache-Control:max-age=8000, proxy-revalidate
Connection:close
Content-Encoding:gzip
Content-Length:20229
Content-Type:text/css
Date:Wed, 26 Jul 2017 09:02:31 GMT
ETag:"1c8c1-55513528cb363-gzip"
Expires:Wed, 02 Aug 2017 09:02:31 GMT
Last-Modified:Mon, 24 Jul 2017 17:12:41 GMT
Server:Apache
Vary:Accept-Encoding
The cache control max age is working, but why is the file's expire date only one week after? Is this some kind of server cache or I am doing something wrong?
Just found out that cache-control:max-age always overwrites the expires tag so everything is ok.
i am using Apache as backend server and nginx as frontend server. I need to make PDF files downloadable (at this moment they are opening in a browser window).
Here's a link:
link
Here's what i have tried so far in my .htaccess file:
<FilesMatch "\.(pdf)$">
ForceType application/octet-stream
Header set Content-Disposition attachment
</FilesMatch>
Didn't work, just opens the file in a browser.
AddType application/force-download pdf
Didn't work.
AddType application/octet-stream .pdf
Didn't work.
UPDATE
Tried: wget --server-response -O /dev/null http://domain.com/files/teltomat.pdf
And got response:
HTTP request sent, awaiting response...
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 24 Sep 2014 17:40:54 GMT
Content-Type: application/pdf
Content-Length: 3116445
Last-Modified: Wed, 24 Sep 2014 13:28:07 GMT
Connection: keep-alive
Keep-Alive: timeout=60
ETag: "5422c6e7-2f8d9d"
Expires: Thu, 31 Dec 2037 23:55:55 GMT
Cache-Control: max-age=315360000
Accept-Ranges: bytes
Length: 3116445 (3,0M) [application/pdf]
Saving to: ‘/dev/null’
You could try the HTML5 solution of adding a "download" instead of "target":
link
As it looks like the server's end is doing the right thing (by making the disposition "attachment") but maybe the browser is deciding on its own that it can handle PDF's inline and opens a new window instead.
I'm using LAMP (Linux, Apache, MySQL, PHP) server.
Currently the server sends the response with next Headers list. I want to eliminate Keep-Alive entry for security reasons, to have Headers list without it. Is it possible to prevent sending the Keep-Alive entry in the Headers list?
Current Response Headers:
Cache-Control private, no-cache, no-store, must-revalidate, post-check=0, pre-check=0
Connection Keep-Alive
Content-Encoding gzip
Content-Type text/html; charset=UTF-8
Date Thu, 13 Mar 2014 01:43:49 GMT
Expires Thu, 13 Mar 2014 01:43:49 GMT
Keep-Alive timeout=5, max=200
Last-Modified Thu, 13 Mar 2014 01:43:49 GMT
Pragma no-cache
Server Apache
Transfer-Encoding chunked
Vary Accept-Encoding
X-DNS-Prefetch-Control off
X-Frame-Options sameorigin
Response Headers I Would Like Instead:
Cache-Control private, no-cache, no-store, must-revalidate, post-check=0, pre-check=0
Connection Keep-Alive
Content-Encoding gzip
Content-Type text/html; charset=UTF-8
Date Thu, 13 Mar 2014 01:43:49 GMT
Expires Thu, 13 Mar 2014 01:43:49 GMT
Last-Modified Thu, 13 Mar 2014 01:43:49 GMT
Pragma no-cache
Server Apache
Transfer-Encoding chunked
Vary Accept-Encoding
X-DNS-Prefetch-Control off
X-Frame-Options sameorigin
Is it possible to prevent sending the Keep-Alive entry in the Headers list?
To my knowledge, no. The whole purpose of the Keep-Alive header is to communicate the need for a persistent connection to the client. So getting rid of the headers gets rid of the main form of communication between the client & the server.
That said, you might be able to get it unset by using unset in your Apache config or .htaccess as explained here. I emphasize might since I have had header directives not behave as expected in some versions of Apache. But assuming good faith, first be sure the headers module is enabled. In Ubuntu 12.04 you would do this:
sudo a2enmod headers
And then add this to your Apache config or .htaccess:
<IfModule mod_headers.c>
Header unset Keep-Alive
</IfModule>
Now restart Apache:
sudo service apache2 restart
More details on the header directive are here.
There are a few ways to this in apache:
Server-wide using the KeepAlive directive ( KeepAlive ). However you can not have this in per-directory configuration files, so setting KeepAlive Off will turn off keep alive for the entire server.
Using SetEnv or SetEnvIf with mod_env, and set the nokeepalive environmental variable. This will turn off keepalive for the location where the environmental is set, or the rule that is matched by SetEnvIf (depending with you use). e.g.
can be in HTACCESS
SetEnv nokeepalive 1
Using mod_rewrite to again set the environmental for a specific rule, e.g.
RewriteRule some-file.html - [E=nokeepalive:1]
Using PHP (or any other server site language) and sending the header Connection: close. This will cause Apache to omit the Keep-Alive header, since the connection is no longer keepalive. e.g.
php
header('Connection: close');
Use mod_headers to set the connection header to close again, e.g.
Header set Connection "close"
I personally have not tested the last one, but it should work.
KeepAlive behavior (availability and timeouts) is directly configurable:
http://httpd.apache.org/docs/2.4/mod/core.html#keepalive
Changing this is primarily an aspect of performance rather than security, but you're free to test the implications in your own environment.
If I do this:
<IfModule mod_expires.c>
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf|mp3|mp4|css|js|php)$">
ExpiresActive On
ExpiresDefault "access plus 30 days"
</FilesMatch>
</IfModule>
It doesn't set properly the Expire header, whereas if I "force" it by hand like this:
<IfModule mod_expires.c>
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf|mp3|mp4|css|js|php)$">
ExpiresActive On
Header set Expires "Thu, 18 Jan 2012 20:00:00 GMT"
</FilesMatch>
</IfModule>
It works. This implies 2 things:
mod_expire is installed (IfModule mod_expires.c is true)
the Expire header is not modified after this rule is applied.
What am I missing?
By the way: if you have any solution to make it work I'm your man!
Ok I've got it from the official documentation here:
Note that if you use a modification date based setting, the Expires
header will not be added to content that does not come from a file on
disk. This is due to the fact that there is no modification time for
such content.
So it works only for static files, and not for all the other ones: they're not static.
This one got me stumped as well because AFAIK, it should work so I tried it on a test VM varying the N days and refreshing. Works fine for me. My Apache version is
Server version: Apache/2.2.14 (Ubuntu)
Server built: Nov 18 2010 21:17:19
Any the headers for a test file (using chrome developer tools) (with N=15) show:
Date:Mon, 09 Jan 2012 01:48:43 GMT
ETag:"7574-5-4b60e88a820a1"
Expires:Tue, 24 Jan 2012 01:48:43 GMT
My thought is that any ExpiresDefault can be overridden by a Header set Expires. Have you grepped the .htaccess hierarchy to make sure that your ExpiresDefault isn't being overridden at a lower level.
If you don't want htaccess files doing this you need to disable them in your http config.