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.
Related
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
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
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.
I'm trying to dynamically concatenate a bunch of javascript files into a single file using the INCLUDE filter. The include.shtml.js test script is
<!--#include virtual="/static/script2.js" -->
<!--#include virtual="/static/script1.js" -->
The virtual server config has both SSIETag and SSILastModified set to On for that file
<VirtualHost *:80>
ServerName test.dkt
ServerAlias test.com
UseCanonicalName Off
ErrorLog logs/test.dkt-error_log
CustomLog logs/test.dkt-access_log combined
LogLevel info
FileEtag All
AddType application/javascript .js
DocumentRoot /var/www/html/test.com
<Directory /var/www/html/test.com>
Options -Indexes
ExpiresActive Off
ExpiresDefault "access plus 1 years"
Header append Cache-Control "public"
Order deny,allow
Allow from all
</Directory>
<Directory /var/www/html/test.com/static>
<FilesMatch "\.shtml\.js$">
SSIETag On
SSILastModified On
Options +Includes
SetOutputFilter INCLUDES
</FilesMatch>
</Directory>
</VirtualHost>
It correctly serves the concatenated scripts but is always a full 200 OK in instead of a 304 Not Modified. The Firebug log
Response Headers
HTTP/1.1 200 OK
Date: Fri, 24 Jan 2014 16:57:12 GMT
Server: Apache/2.2.15 (CentOS)
Last-Modified: Fri, 24 Jan 2014 16:53:32 GMT
Etag: "460bbc-5c-4f0ba32b7447d"
Accept-Ranges: bytes
Vary: Accept-Encoding
Content-Encoding: gzip
Cache-Control: public
Content-Length: 40
Connection: close
Content-Type: application/javascript
Request Headers
GET /static/include.shtml.js HTTP/1.1
Host: test.dkt
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:26.0) Gecko/20100101 Firefox/26.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: pt-br,en-us;q=0.9,es;q=0.7,en;q=0.6,zh-tw;q=0.4,ar-sa;q=0.3,ar;q=0.1
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
If-Modified-Since: Fri, 24 Jan 2014 16:53:32 GMT
If-None-Match: "460bbc-5c-4f0ba32b7447d"
Cache-Control: max-age=0
Is there a hard coded restriction on conditional requests for the INCLUDE filter?
I'm aware that I should "touch" the including script whenever there is a change in any of the included scripts. The Apache version is 2.2 running in Centos 6
EDIT
Using the #covener answer I made it work setting the group execute permission of the file and adding the XBitHack full directive
Even though you've opted into the etags, it seems you need to separately enable xbithack to allow a 304 to be generated (ap_meets_conditions in the core checks no_local_copy flag referenced in mod_include
http://httpd.apache.org/docs/current/mod/mod_include.html#xbithack
/* When our xbithack value isn't set to full or our platform isn't
* providing group-level protection bits or our group-level bits do not
* have group-execite on, we will set the no_local_copy value to 1 so
* that we will not send 304s.
*/
if ((conf->xbithack != XBITHACK_FULL)
|| !(f->r->finfo.valid & APR_FINFO_GPROT)
|| !(f->r->finfo.protection & APR_GEXECUTE)) {
f->r->no_local_copy = 1;
}
When having
SSILastModified on
XBitHack full
together in configuration file, the setting "SSILastModified On" is a silent misconfiguration, because whether "SSILastModified" is on or not, it does not change any program behavior.
By tracking back to the source code of Apache, we can see the root cause of this misconfiguration is that the semantics enabled by "Xbithack Full" implicitly overwrite the semantics enabled by "SSILastModified On".
if (conf->lastmodified > 0) {
... {
ap_update_mtime(r, r->finfo.mtime);
ap_set_last_modified(r);}}
else if (((conf->xbithack == XBITHACK_FULL ||
(conf->xbithack == XBITHACK_UNSET &&
DEFAULT_XBITHACK == XBITHACK_FULL))
...)) {
ap_update_mtime(r, r->finfo.mtime);
ap_set_last_modified(r);
}
So one possible solution would be just keep this
Xbithack full
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?