Apache: mod_disk_cache setup for specific url pattern with LocationMatch - apache

i'm trying to setup mod_disk_cache for a url pattern. Server runs Apache/2.2.22
Wanted:
All requests to 'domain.com/location/anyHtmlFile' should be served from cache.
Config:
CacheEnable disk /
CacheIgnoreCacheControl On
SetEnv no-cache
I want this to work:
"if url starts with "/location" do 'UnsetEnv no-cache'
In the apache vhost I tried
<LocationMatch "^/location/.+\.html$">
<LocationMatch "/location/">
and desperately
<LocationMatch "location">
UnsetEnv no-cache
</LocationMatch>
<Location /location/>
UnsetEnv no-cache
</Location>
didn't work, too.
An html file in /location/ has following caching-relevant header attributes (Firefox):
Cache-Control: max-age=14400, public
Date Wed, 05 Jun 2013 11:17:00 GMT
Expires Wed, 05 Jun 2013 15:17:00 GMT
I have just recognized that the requestheader for the same file in chrome says
Cache-Control:public
Cache-Control:no-cache, must-revalidate
I'm setting Cache-Control to 'public' explicitely in the expires.conf.
I commented the global
#SetEnv no-cache
out in my vhost config, but there are still both Cache-Controls in the header. But this shouldn't be the problem as I have 'CacheIgnoreCacheControl On', should it?
Any help?

Related

Apache returning null for environment variables in header

I am trying to troubleshoot my apache test site right now. I need to have the mod_rewrite variables returned in the header so that I can see what is going on. However, when I try to set them in the header, I get null
Server version: Apache/2.4.51 (Fedora)
config
<VirtualHost mysite.local:80>
ServerName mysite
DocumentRoot /var/www/html/mysite
Header always set TestHeader "%{SERVER_NAME}e"
output from curl
curl -I http://mysite.local/index.html
HTTP/1.1 200 OK
Date: Tue, 01 Feb 2022 02:05:42 GMT
Server: Apache/2.4.51 (Fedora)
TestHeader: (null)
Last-Modified: Tue, 25 Jan 2022 19:37:28 GMT
ETag: "15-5d66d372009de"
Accept-Ranges: bytes
Content-Length: 21
Content-Type: text/html; charset=UTF-8
Also, mod_headers and mod_rewrite are enabled
$ grep -R 'mod_rewrite' conf.modules.d/
conf.modules.d/00-base.conf:LoadModule rewrite_module modules/mod_rewrite.so
$ grep -R 'mod_headers' conf.modules.d/
conf.modules.d/00-base.conf:LoadModule headers_module modules/mod_headers.so
Am I missing some setting or configuration?
Try adding PassEnv SERVER_NAME before the Header set.
See PassEnv - mod_env - Apache HTTP Server Version 2.4 Documentation for more info

flask behind gunicorn and apache returning http

I wanted to make my app (finally) accessible through a reserved proxy:
Request --> Apache --> gunicorn --> flask
After reading tons of thread and spending hours on this my actual apache config is:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName app.%my domain name%.com
ProxyPreserveHost On
SSLProxyEngine On
ProxyPass / http://flask-server:8000/
ProxyPassReverse / http://flask-server:8000/
SSLCertificateFile /etc/letsencrypt/live/app.%my domain name%.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/app.%my domain name%.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
I am using flask fixproxy, as it should have fixed the issue. But it didn't:
[...]
from werkzeug.contrib.fixers import ProxyFix
login = LoginManager()
login.login_view = 'auth.login'
login.login_message = _l('Please log in to access this page.')
mail = Mail()
bootstrap = Bootstrap()
def create_app(config_class=Config):
app = Flask(__name__)
app.wsgi_app = ProxyFix(app.wsgi_app)
app.config.from_object(config_class)
[...]
I added to all url_for _external=True, _scheme='https' which is working fine, but the app is still forwarding me to http at some places where I cannot add this properties (for example when I am not logged in).
I made two checks:
1)
curl -Ik https://app.%my domain name%.com
HTTP/1.1 302 FOUND
Date: Thu, 19 Apr 2018 22:07:31 GMT
Server: gunicorn/19.7.1
Content-Type: text/html; charset=utf-8
Content-Length: 247
Location: http://app.%my domain name%.com/auth/login?next=%2F
Set-Cookie: session=...
HttpOnly; Path=/
2)
curl -Ik -H "X-Forwarded-Proto: https" https://app.%my domain name%.com
HTTP/1.1 302 FOUND
Date: Thu, 19 Apr 2018 22:07:22 GMT
Server: gunicorn/19.7.1
Content-Type: text/html; charset=utf-8
Content-Length: 247
Location: https://app.%my domain name%.com/auth/login?next=%2F
Set-Cookie: session=...
HttpOnly; Path=/
Seems like its more a apache problem. Where is my mistake?
Thanks to the curl output I figured out what the problem is:
RequestHeader set X-Forwarded-Proto "https"
inside the apache config will solve it.
Don't forget to enable it (like I did):
a2enmod headers

Apache (not the browser) is caching my file

The browser is not caching it. It gets the response headers:
Accept-Ranges:bytes
Cache-Control:max-age=0, no-cache, no-store, must-revalidate
Connection:Keep-Alive
Content-Length:425169
Content-Type:application/javascript
Date:Thu, 09 Mar 2017 20:06:53 GMT
Expires:Wed, 11 Jan 1984 05:00:00 GMT
Keep-Alive:timeout=5, max=100
Last-Modified:Thu, 09 Mar 2017 20:06:49 GMT
Pragma:no-cache
Server:Apache/2.4.6 (CentOS) OpenSSL/1.0.1e-fips PHP/5.4.16
My settings in Apache:
<VirtualHost *:80>
<Directory "/webapps/apps/devsite">
Allow from all
AllowOverride All
Order allow,deny
</Directory>
DocumentRoot /webapps/apps/devsite
ServerName testing.devsite.com
SSLEngine off
</VirtualHost>
My .htaccess:
<FilesMatch "\.(html|htm|js|css)$">
FileETag None
<IfModule mod_headers.c>
Header unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</IfModule>
</FilesMatch>
The following loads a new, non-cached version:
on the server run: rm -f /webapps/apps/devsite/scripts/script.js
Reload in the web browser (thus getting a 404)
Copy the file back on to server
Reload in browser
The following does loads an old, CACHED version!:
On the server run: rm -f /webapps/apps/devsite/scripts/script.js
Copy the file back on to server (NOTE: I did not reload in browser yet)
Reload in browser
This shows that Apache is somehow caching it until it gets a new request and cannot find it. Why? How do i fix this?
The issue was it was using the kernel's SendFile which caused it to miss the file being changed. This is a Virtual Machine shared folder. Adding the following fixes it:
EnableSendfile off
(the "file" is lowercase)
More info here: https://www.vagrantup.com/docs/synced-folders/virtualbox.html
http://httpd.apache.org/docs/2.2/mod/core.html#enablesendfile
Apache does not permanently watch all files, only when you request a specific resource.
When you hit the 404 error, Apache loses the information about the file it has had found before.
The last modified timestamp does not change when you don't request a resource in the meantime.

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.

Bypassing authentication for "Options request" (so all headers are sent in the response)

This is in the context of Cross-origin resource sharing. For the preflight request, the server is not sending the headers set.
When a valid cookie is not passed with the "Options request", the server in it's response is not sending the headers I set, however, it's sending "200 OK". I checked this with curl as can be seen below (obviously, I replaced my valid cookie with a dummy "xyzabcde" here)
The curl request WITHOUT cookie:
curl -H "Origin: app2_url" -H "Access-Control-Request-Method: POST" -H "Access-Control-Request-Headers: accept, origin, content-type" -X OPTIONS --verbose app1_url/jsonrpc.cgi
(sends below response...)
HTTP/1.1 200 OK
Date: Tue, 01 Oct 2013 11:37:36 GMT
Server: Apache
Expires: Tue, 01 Oct 2013 11:37:36 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Expires: Tue, 01 Oct 2013 11:37:36 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Content-Length: 4531
Content-Type: text/html; charset=utf-8
with "-H Cookie:xyzabcde":
curl -H "Origin: app2_url" -H "Access-Control-Request-Method: POST" -H "Access-Control-Request-Headers: accept, origin, content-type" "-H Cookie:xyzabcde" -X OPTIONS --verbose app1_url/jsonrpc.cgi
(sends below response...)
HTTP/1.1 403 Forbidden
Date: Wed, 02 Oct 2013 18:48:34 GMT
Server: Apache
X-frame-options: ALLOW-FROM app2_url
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: accept, origin, content-type, Man, Messagetype, Soapaction, X-Requested-With
Access-Control-Allow-Methods: GET, POST, HEAD, PUT, OPTIONS
Access-Control-Allow-Origin: app2_url
Access-Control-Max-Age: 1800
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8
The apache config looks something like...
<VirtualHost *:443>
.
.
Header always set X-Frame-Options "ALLOW-FROM app2_url"
Header always set Access-Control-Allow-Credentials "true"
Header always set Access-Control-Allow-Headers "accept, origin, content-type, Man, Messagetype, Soapaction, X-Requested-With"
Header always set Access-Control-Allow-Methods "GET, POST, HEAD, PUT, OPTIONS"
Header always set Access-Control-Allow-Origin "app2_url"
Header always set Access-Control-Max-Age "1800"
.
.
.
<Directory /app1/dir/>
Options Includes FollowSymLinks ExecCGI MultiViews
AllowOverride None
Order allow,deny
allow from all
AuthType Net
PubcookieInactiveExpire -1
PubcookieAppID app1.company.com
require valid-user
</Directory>
.
.
</VirtualHost>
How can I make all the headers be sent in response to unauthenticated requests?
I guess, Options requests ideally are supposed to not require any authentication.
We solved this with different configuration. Below is the snippet from myApplication.conf file at /usr/local/apache/conf/extra
<Location "/myService">
SetEnvIf Request_URI "/healthCheck" REDIRECT_noauth=1
SetEnvIf Request_Method "OPTIONS" REDIRECT_noauth=1
AuthType Basic
AuthName "myService"
AuthUserFile /usr/local/apache/conf/passwd/passwords
AuthGroupFile /usr/local/apache/conf/passwd/groups
Require group GroupName
Order allow,deny
Allow from env=REDIRECT_noauth
Satisfy any
</Location>
So, we can bypass the authentication:
Based on particular URI, in above example /healthCheck is bypassed
Based on HTTP method, in above example OPTIONS is bypassed and auth will be prompted for other HTTP methods
Hope it helps someone to resolve the issues.
"LimitExcept" directive solved it. In fact, prior to posting the question I tried the directive, however the mistake earlier was including the first two lines ("Options Includes..." and "Alowoverride...") within the "LimitExcept" block.
<Directory /app1/dir/>
Options Includes FollowSymLinks ExecCGI MultiViews
AllowOverride None
<LimitExcept OPTIONS>
Order allow,deny
allow from all
AuthType Net
PubcookieInactiveExpire -1
PubcookieAppID app1.company.com
require valid-user
</LimitExcept> #<- syntax error fixed.
</Directory>