Client-side caching of static files not working (Apache) - apache

I'm trying to use mod_expires and mod_headers to enable browser caching for my site. I have this in my VirtualHost:
<FilesMatch ".(gif|jpg|jpeg|png|ico|swf|js|css|pdf)$">
ExpiresActive On
ExpiresDefault "access plus 1 week"
Header set Cache-Control "public"
Header unset Last-Modified
</FilesMatch>
The Expires and Cache-Control headers are set correctly in my responses:
HTTP/1.1 200 OK
Date: Tue, 28 Jun 2016 16:09:26 GMT
Server: Apache/2.4.7 (Ubuntu)
ETag: "8f44-526a1625962b5-gzip"
Accept-Ranges: bytes
Vary: Accept-Encoding
Content-Encoding: gzip
Cache-Control: public
Expires: Tue, 05 Jul 2016 16:09:26 GMT
Content-Length: 8504
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
Content-Type: application/javascript
Unfortunately, my browser (Chrome) is still requesting all these static files every time I load my page. I see these requests in my access.log and browser console. What am I doing wrong?
EDIT:
I do have caching enabled in the developer toolbar:

Check if client-side caching is disabled. Google Chrome may disable client-side caching when the DevTools window is open (F12).

Related

Images ignoring Cache-Control in .htaccess

In my images folder, I have an .htaccess file with the following:
<IfModule mod_headers.c>
# Browsers may cache images for 24 hours, including disk cache for SSL
Header set Cache-Control "max-age=2628000, public, must-revalidate"
</IfModule>
When I curl an image in that folder, I get the following (Notice Cache-Control missing "public" and "must-revalidate"):
HTTP/1.1 200 OK
Server: nginx/1.11.8
Date: Fri, 14 Dec 2018 17:57:00 GMT
Content-Type: image/jpeg
Content-Length: 46563
Last-Modified: Fri, 29 Sep 2017 03:16:20 GMT
Connection: keep-alive
ETag: "59cdbb04-b5e3"
Expires: Fri, 21 Dec 2018 17:57:00 GMT
Cache-Control: max-age=604800
Strict-Transport-Security: max-age=31536000
Accept-Ranges: bytes
It does not matter what I put in the .htaccess file, I always get the above response.
If I create a new image in that folder, I also get the same above response.
If I change the extension on an image in that folder (.bak) I get the expected response (Cache-Control is correct):
HTTP/1.1 200 OK
Server: nginx/1.11.8
Date: Fri, 14 Dec 2018 17:59:35 GMT
Content-Type: image/gif
Content-Length: 19164
Connection: keep-alive
Last-Modified: Fri, 14 Dec 2018 16:07:12 GMT
ETag: "183ca-4adc-57cfd9fbbac00"
Accept-Ranges: bytes
Cache-Control: max-age=2628000, public, must-revalidate
Strict-Transport-Security: max-age=31536000
Any ideas what is going on here? I looked at all parent .htaccess files and apache config, I can not find anything!
Please help!!!
For anyone else experiencing this issue, the Apache .htaccess directive was being overridden by the following Nginx config:
location ~* ^(.+?)(?:\.\d+)?\.(jpe?g|gif|png|svg|ico|bmp|js|css|ttf|eot|woff2?)$ {
root /var/www;
try_files $1.$2 #apache;
expires 7d;
}
Replacing "expires 7d;" with the following did the trick:
add_header Cache-Control "max-age=2628000, public, must-revalidate";

Setting cache-control max-age using Apache not working

I'm trying to setup HTTP Caching for my website. Following is my configuration settings
# 1 YEAR
<FilesMatch "\.(ico|svg|woff|eot|ttf)$">
Header set Cache-Control "max-age=31536000, public"
</FilesMatch>
# 1 WEEK
<FilesMatch "\.(jpg|png|gif|css|js)$">
Header set Cache-Control "max-age=604800, public"
</FilesMatch>
Does it make a difference if I place this in my <VirtualHost> settings or outside it? I've placed it inside the <VirtualHost>.
I tried checking the HTTP response for one of the png image using redbot.org and this is what it returned.
HTTP/1.1 200 OK
Date: Fri, 12 Sep 2014 09:28:33 GMT
Server: Apache/2.4.7 (Ubuntu)
Last-Modified: Tue, 26 Aug 2014 05:43:32 GMT
ETag: 1409031812.69
Content-Length: 23907
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: image/png
Why is there no Cache-Control max-age header tag?
I also checked using the Google PageSpeed Insights and it still says expiration not specified for all the files.
Did I miss something?
The .htaccess file was not being taken into account due to some missing configuration settings in my apache2.conf file. Making the required changes in the conf file solved the issue.

CORS Headers Not Being Set

I'm trying to download a static file from another domain. In my .htaccess file, which is in the root directory:
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers "Accept, If-Modified-Since, Origin"
Header set Access-Control-Allow-Methods "GET, OPTIONS"
And here's the request-response cycle where a browser downloads the resource twice:
GET /file HTTP/1.1
Host: www.example.com
Accept: application/json
Origin: http://www.mydomain.com
HTTP/1.1 200 OK
Date: Sat, 07 Sep 2013 21:01:35 GMT
Server: Apache
Last-Modified: Sat, 07 Sep 2013 20:14:45 GMT
Content-Length: 2
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, If-Modified-Since, Origin
Access-Control-Allow-Methods: GET, OPTIONS
Content-Type: application/json
[]
GET /file HTTP/1.1
Host: www.example.com
Cache-Control: max-age=0
Accept: application/json
Origin: http://www.mydomain.com
If-Modified-Since: Sat, 07 Sep 2013 20:14:45 GMT
HTTP/1.1 304 Not Modified
Date: Sat, 07 Sep 2013 21:01:40 GMT
Server: Apache
The second time you can see that since the file hasn't been modified, the server responds with a 304 Not Modified. Why are the CORS headers not being set for the second response?
It's an apache bug, see below
https://issues.apache.org/bugzilla/show_bug.cgi?id=51223
You can recompile Apache with the patch if you're feeling brave....

Missing 'WWW-Authenticate' header for 401

I have a project which is protected by std AuthUserFile-directive in .htaccess.
Everything is quite simple and has already been fine on another server. Here is the content of my .htaccess:
The .htaccess:
AuthName "Adminbereich"
AuthType Basic
AuthUserFile /srv/www/passwords/.htpasswd-office
<Files *.php>
require valid-user
</Files>
The .htpasswd-office gets accessed. If I call http://user:pass#host/ I get in. If I just call http://host/ I get this message immediately ...
Authorization Required
This server could not verify that you are authorized to access the document requested. Either you supplied the wrong credentials (e.g., bad password), or your browser doesn't understand how to supply the credentials required.
... without any login-box showing. What could be the cause of this?
This is a example-header from here: http://www.pagetutor.com/keeper/mystash/secretstuff.html
HTTP/1.1 401 Authorization Required
Date: Thu, 01 Nov 2012 21:38:27 GMT
Server: Apache/2.2.22 (Unix) mod_ssl/2.2.22 OpenSSL/0.9.8e-fips-rhel5 mod_bwlimited/1.4
WWW-Authenticate: Basic realm="My Secret Area"
Accept-Ranges: bytes
Content-Length: 343
Content-Type: text/html
And this is my header:
HTTP/1.1 401 Authorization Required
Date: Thu, 01 Nov 2012 21:36:41 GMT
Server: Apache/2.2.20 (Ubuntu)
Vary: Accept-Encoding
Content-Type: text/html; charset=iso-8859-1
The magic WWW-Authenticate: Basic realm="..." is missing and I have no idea why...
I use the standard ubuntu (11.10) apache (2.2.20) without any modifications...

Set-Cookie and Expires headers differ

I'm trying to enable Expires headers for images as recommended by YSlow. I'm sure I had this working before but now when I check YSlow it says they are not being cached.
For my .htaccess, I have tried:
ExpiresActive on
ExpiresDefault A0
<FilesMatch "\.(gif|ico|jpg|png)$">
ExpiresDefault A29030400
Header append Cache-Control "public"
</FilesMatch>
and
ExpiresActive on
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 month"
http://www.seoconsultants.com/tools/headers.asp outputs the following for one of my images:
HTTP Status Code: HTTP/1.1 200 OK
Date: Mon, 05 Oct 2009 20:12:04 GMT
Server: Apache/2.0.63 (Unix) mod_ssl/2.0.63 OpenSSL/0.9.8e-fips-rhel5 mod_bwlimited/1.4 PHP/5.2.8
X-Powered-By: PHP/5.2.8
Set-Cookie: PHPSESSID=5d11f4d8aa37ceee6605786e59ff4f0f; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: lastlogin=1254773024; expires=Mon, 02-Nov-2009 20:12:04 GMT
Connection: close
Content-Type: image/jpeg
The Set-Cookie part looks correct but the Expires header is not. How do I set Expires correctly and why do they differ? I have double checked that mod_expires and mod_headers are enabled.
From the Set-Cookie header, it looks like this is part of a PHP session. PHP automatically disables caching after a session_start().
You can modify this behavior by changing session.cache_limiter in your php.ini. See the PHP manual page for the various settings.
Alternatively, you could try using set instead of append to override the headers in your .htaccess.