Cache control static assets with query strings in htaccess - apache

Do the cache control directives need to specify if a query string is present in the http request for proper matching?
Currently using query strings for static asset versioning, and disabled Etags for those - but the directives are not taking effect whatsoever. Looking at the headers, Etags are still used and there is no cache-control defined. Gmatrix and Lighthouse both state that static assets have no cache control set.
Example file requested: app.js?v=1.3.5
Here is the .htaccess file, followed by the troubleshooting steps
<IfModule mod_headers.c>
# One month for media files and icons
<FilesMatch "\.(ogg|mp3|ico|jpg|jpeg|png|svg|webp|webmanifest|xml)\?.*$">
Header set Cache-Control "max-age=2592000, public"
Header unset ETag
FileETag None
</FilesMatch>
# One week for CSS/JS files except service worker file
<FilesMatch "^(?!sw).+\.(css|json|js)\?.*$">
Header set Cache-Control "max-age=604800, public"
Header unset ETag
FileETag None
</FilesMatch>
# No cache for HTML files (checks with server for changes else serves cache)
<FilesMatch "\.(html)$">
Header set Cache-Control "no-cache, must-revalidate"
</FilesMatch>
<FilesMatch "^(sw\.js)$">
Header set Cache-Control "no-cache, no-store, must-revalidate"
</FilesMatch>
</IfModule>
Troubleshooting steps
Directives don't seem to affect html pages either so assuming this may be a config or syntax issue.
Check syntax with validator: https://www.lyxx.com/freestuff/002.html
Ensure AllowOverride is set to All in /etc/apache2/sites-available/mysite.conf
Try setting AllowOverride to All in /etc/apache2/apache2.conf for /var/www/
Try adding the directives directly in /etc/apache2/sites-available/mysite.conf
Restart apache after changes: service apache2 restart

The mod_headers module was not activated!
Use apachectl -M to check for active modules (Debian/Ubuntu).
If headers module not listed:
Use a2enmod headers to activate the headers module.
Restart apache2 with service apache2 restart to implement changes.
At this point was able to test whether the query string needs to be added in the FilesMatch expression.
Turns out the query string needs to be omitted from the expression.
Use: \.(js)$
Don't use: \.(js)\?.*$

Related

Zip files being open as files by APACHE server instead of downloading

The error that I get is from PHP because APACHE is tryng to pass the .zip file through the PHP interpreter.
But this post is not regarding any PHP script, or setting up headers from PHP to make the file download. It is about preventing APACHE from passing the file through PHP and generate a download instead.
I have found a few answers that involve adding File Exceptions on the .htaccess but still without success and I get the follwing Parse error message:
Parse error: in /home/user/public_html/downloads/files/1/test-file-132110.zip on line 431
These are the .htaccess instructions that I found that work:
<Location "/downloads/files/">
<Files *.*>
ForceType application/octet-stream
Header set Content-Disposition attachment
</Files>
</Location>
The previous example is not so great because I want to chose specific extensions, lile doc, zip, etc. So I tried these instead:
<Location "/downloads/files/">
<FilesMatch ".(?i:doc|docx|xls|xlsx|ppt|pptx|zip|rar)$">
ForceType application/octet-stream
Header set Content-Disposition attachment
</FilesMatch>
</Location>
or this, without specifying a location:
<FilesMatch "\.(doc|docx|xls|xlsx|ppt|pptx|zip|rar)$">
ForceType application/octet-stream
Header set Content-Disposition attachment
</FilesMatch>

Setting cache control headers for Apache proxy on Elastic Beanstalk

I have an elastic beanstalk server running an Apache proxy on Amazon Linux 2. I want to set the cache-control header on my index.html file to public, max-age=0.
In order to update my Apache config I understand I can add a config file to .platform/httpd/conf.d. In my first attempt I created this file:
<FilesMatch "index\.html">
Header set Cache-Control "public, max-age=0"
</FilesMatch>
This did not work. Looking around I think this is because the directives I have used are intended for Apache's htaccess file or within a <VirtualHost> section of the conf file.
Any ideas how I can get this working? Note I found this answer had some useful information.
EDIT: I also tried this in a conf file (it didn't set any cache-control headers).
<IfModule mod_expires.c>
# Turn on the module.
ExpiresActive on
# Set the default expiry times.
ExpiresDefault "access plus 2 days"
ExpiresByType text/html "access plus 600 seconds"
</IfModule>
EDIT: I also tried switching to nginx. I added a file .platform/nginx/conf.d/cache.conf, with the following contents
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 2d;
add_header Cache-Control "public, no-transform";
}
After deployment and a server restart, no cache-control headers were set on the files specified.

Apache mod_headers cannot unset header on a path

I am trying to set a header using mod_headers in Apache in all cases EXCEPT a certain path. I've tried each of the three variations below to do so, but none of them seem to work properly to exclude the path. In ALL cases I get the header for all requests, including those that match the example path, e.g.: http://example.com/charts/24_hour_commodity/450/300
<VirtualHost *:8200>
...
SetEnvIfNoCase Request_URI "^/charts/.*" frameallow
Header set X-Frame-Options SAMEORIGIN env=!frameallow
...
</VirtualHost>
Or:
<VirtualHost *:8200>
...
Header always set X-Frame-Options SAMEORIGIN
<LocationMatch "^/charts">
Header always unset X-Frame-Options
</LocationMatch>
...
</VirtualHost>
Or
<VirtualHost *:8200>
...
Header always set X-Frame-Options SAMEORIGIN
<Directory "/full/path/to/charts">
Header always unset X-Frame-Options
</Directory>
...
</VirtualHost>
#tried both with and without the 'always' in all configs
Can anyone help me figure out why the header is set in the first example or not unset in the following two? Any one working solution would be enough...
UPDATE:
After reading about order of processing on the Apache site, I tried using conditional blocks instead. Neither of those work either:
<If "%{REQUEST_URI} =~ m#^/charts#">
Header unset X-Frame-Options
</If>
Or
SetEnvIfNoCase Request_URI "^/charts" frameallow
<If "reqenv('frameallow') == 1">
Header unset X-Frame-Options
</If>
So, still broken. Must be something about the Header statements not firing after a certain point in processing. Or the ones int he conditional somehow firing before the main one and being overridden. Cannot find a way to debug it down to the root cause though.
Responses header with expression
Header always set Access-Control-Allow-Origin * "expr=%{REQUEST_URI} =~ m#^/specialPath$#"
this may add header wen the expr = true
http://httpd.apache.org/docs/current/mod/mod_headers.html
at the bottom of the section Header Directive

CORS Access-Control-Allow-Origin Error on Drupal 7 with Cloudflare

We have been having the problem where we get errors of the format.
Font from origin 'https://example.com' has been blocked from loading by
Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin'
header is present on the requested resource. Origin
'https://www.example.com' is therefore not allowed access.
We also get a "Redirect at origin" error.
We are using Drupal 7 and Cloudflare.
we have attempted to edit .htaccess to include
Header set Access-Control-Allow-Origin "https://example.com"
Header set Access-Control-Allow-Origin "https://www.example.com"
Tried quite a lot;
have purged cloudflare
restarted apache
tried wildcard "*"
Drupal CORS module
So far no joy.
As this approach is not working, I am wondering if something is being missed or if there is an alternate approach, such as why we are getting origin 'https://example.com' being in the request via Drupal and not 'https://www.example.com'.
Last note it that when I review some resources I see two distinct patterns.
If a resource has status of "301 Moved Permanently" in the request headers there is
Host www.example.com
Referer https://example.com/
Where the status is "304 Not Modified"
Host example.com
Referer https://example.com/
It's odd that there is any www at all; htaccess should be redirecting and it is absent from base_url.
I have experienced a very similar issue.
Be ensured that module headers is enabled
1 - To enable mod headers on Apache2 (httpd) you need to run this command:
sudo a2enmod headers
Then restart Apache
sudo service apache2 restart
2 - To allow Access-Control-Allow-Origin (CORS) authorization for specific origin domains for all files, add this in your .htaccess
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin https://example.org
Header set Access-Control-Allow-Origin https://example.com
Header set Access-Control-Allow-Origin https://example.eu
## SECURITY WARNING : never add following line when site is in production
## Header set Access-Control-Allow-Origin "*"
</IfModule>
2 - To allow Access-Control-Allow-Origin (CORS) authorization for specific origin domains and for fonts only in our example, use FilesMatch like in the following section in your .htaccess
<FilesMatch "\.(ttf|otf|eot|woff|woff2)$">
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin https://example.org
Header set Access-Control-Allow-Origin https://example.com
Header set Access-Control-Allow-Origin https://example.eu
</IfModule>
</FilesMatch>
After making changes in .htaccess file, no need to restart your apache webserver

Apache caching with .htaccess problem (incorrect Date header?)

I am using .htaccess to cache the js / css / etc files on the website. Everything works fine, but for some reason my pages get cached, too. I looked into the headers, and it works like this:
Browser requests a page http://poko.lt/up
Server responds with 301 to http://poko.lt/up/ (with Date and Last Modified headers equal to current time)
Browser requests http://poko.lt/up/
Server responds with the page, and with Date and Last Modified headers equal to my last forced refresh (like, yesterday), but Cache-control header is fine (max-age=0)
I get the old version of the page :/
My .htaccess looks like this:
# Turn on Expires and set default to 0
ExpiresActive On
ExpiresDefault A0
# 1 YEAR
<FilesMatch "\.(jpg|jpeg|png|gif|svg|eot|ttc|ttf|otf)$">
ExpiresDefault A29030400
Header append Cache-Control "public"
Header unset Last-Modified
Header unset ETag
FileETag None
</FilesMatch>
# 2 WEEKS
<FilesMatch "\.(css|js|swf)$">
ExpiresDefault A1209600
Header append Cache-Control "proxy-revalidate"
Header unset Last-Modified
Header unset ETag
FileETag None
</FilesMatch>
# NO CACHE
<FilesMatch "\/$">
ExpiresDefault A0
Header append Cache-Control "proxy-revalidate"
Header unset Last-Modified
Header unset ETag
FileETag None
</FilesMatch>
And, one can test it with the website http://poko.lt (the three red icons in the top middle of the page are the ones causing the problems). I am using FF4, and checking headers with Firebug.