Following old advices here and here
I'm curious what is the proper syntax for APACHE server:
AddType font/woff2 .woff2
ExpiresByType font/woff2 "access plus 1 year"
or
AddType application/woff2 .woff2
ExpiresByType application/woff2 "access plus 1 year"
what is the proper syntax for APACHE server
It's not really a question of "syntax". Both your examples use the same "syntax". But rather, what is the correct/official mime-type (that user-agents understand).
The official mime-type according to the WOFF2 spec (W3C Recommendation / 1-March-2022) is:
font/woff2
This was initially discussed in the WOFF File Format 2.0 - W3C Working Draft 14 April 2015 - Appendix A: Internet Media Type Registration
AddType application/woff2 .woff2
I don't think application/woff2 has ever been a (proposed) mime-type? The IANA Media Types initially defined application/font-woff for woff font files, so by extension you could assume that application/font-woff2 would be used for woff2, but I don't see this documented anywhere? And IANA have since "deprecated" application/font-woff in favour of font/woff and list only font/woff2 for woff2 font files.
AddType font/woff2 .woff2
You shouldn't need to manually add the AddType directive here. Providing you are using a relatively recent distro of Apache then the mime.types file that is imported (using the TypesConfig directive) during startup already includes the necessary (and correct) mime-type for .woff2 files:
font/woff2 woff2
See also:
RFC 8081 - The "font" Top-Level Media Type / WOFF 2.0
https://www.w3.org/standards/history/WOFF2
Did you include the ExpiresActive on?
<IfModule mod_expires.c>
ExpiresActive On
AddType font/woff2 .woff2
ExpiresByType font/woff2 "access plus 1 year"
</IfModule>
Related
I want browsers to cache html files. I set up Apache2.4 and confirm css, js, png are cached, but html files are never cached.
Chrome 90 and Edge 90
Apache 2.4
/etc/httpd/conf/httpd.conf
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 30 days"
</IfModule>
Hi try to add ExpiresByType text/html "access plus 7200 seconds". Hope it works !
I have recently deployed a website on a VPS that supports Apache2, and was working on performance improvement suggestions by YSlow.
Among those improvements were using mod_deflate and mod_expires, and since I have root access, I can directly edit the Apache config files.
mod_deflate is now working, but I am having issues with mod_expires so here is what I have done:
enable expires module and restart the server
a2enmod expires
service apache2 restart
create a new file "expires.conf" under mods_enabled that contains the following:
<IfModule mod_expires.c>
# Enable expirations
ExpiresActive On
# Default directive
ExpiresDefault "access plus 1 month"
# My favicon
ExpiresByType image/x-icon "access plus 1 year"
# Images
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
# CSS
ExpiresByType text/css "access plus 1 month"
# Javascript
ExpiresByType application/javascript "access plus 1 year"
</IfModule>
However, when checking on various browsers Dev Tools under Network, the files show a Cache Control of None.
I thought of using my mod_expires script above in a .htaccess located in the root directory of my website: /var/www/sitename/public_html, since settings in the .htaccess override any prior settings made in the apache config files.
For that, i enabled the use of htaccess in apache2.conf.
I tested that my htaccess file was indeed working by willingly introducing an error in it (commented out the IfModule open tag). Refreshing the browser gave me a 500 server error. So the htaccess file was being processed.
Unfortunately, the browser dev tools still showed no cache control, and I am running out of ideas.
Am I missing something?
Thanks!
Most likely, your expires.conf is getting parsed before the expires module is loaded, as you have included the configuration file in the mods-enabled folder.
Place your config file in conf.d and restart Apache.
I finally fixed the issue:
firstly i noticed a difference between all the other config files and the one i had created under mods-enabled: the others were symlinks to their respective files under mods-available. This shouldn't be an issue but definitely better stick to the convention.
It seems I may not have restarted the apache2 service after creating the file
In my case, I had to:
Move the expires.conf to /etc/apache2/conf-available/ . I think this would be necessary to load the configs after the module.
mv /etc/apache2/mods-available/expires.conf /etc/apache2/conf-available/
Also I had forgotten to enable the config before restarting apache.
a2enconf expires
service apache2 reload
I read the official caching guide of the latest Apache httpd version, but did not understand how to get a minimal caching setup for static content.
Googling around, I finally added these rules to my /etc/apache2/apache2.conf (I'm using Ubuntu):
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 5 seconds"
ExpiresByType image/x-icon "access plus 2592000 seconds"
ExpiresByType image/jpeg "access plus 2592000 seconds"
ExpiresByType image/png "access plus 2592000 seconds"
ExpiresByType image/gif "access plus 2592000 seconds"
ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds"
ExpiresByType text/css "access plus 604800 seconds"
ExpiresByType text/javascript "access plus 216000 seconds"
ExpiresByType application/javascript "access plus 216000 seconds"
ExpiresByType application/x-javascript "access plus 216000 seconds"
</IfModule>
<IfModule mod_headers.c>
Header set Cache-Control "public"
</IfModule>
FileETag None
Obviously, I already enabled expires, headers, cache modules.
When I try to access an image, a css or js file, I see 200 OK the first time, and 304 the next ones. So, I thought I was right... but Google Pagespeed (for example) still complains about files that are not cached.
Actually, I had some suspects that I'm missing something:
I didn't activate mod_cache or mod_cache_disk. Should I? What's the basic set of rules for doing so?
Why is it necessary to disable the ETag?
I absolutely need my cache to expire suddenly when the file is changed: ideally, the expiration time (for css, js) could be very long, let's say, two weeks, but if the file changes after one hour, the user should mandatory get the updated file! Is that behavior automatically managed by Apache?
I absolutely need my cache to expire suddenly when the file is changed
TWhen you use mod_expires to send an Expires header the client doesn't have to make sure the file is fresh and you can't force a change ever.
If you drop mod_expires, your static files will have an ETAG and a last-modified-time which allows browsers to make sure the file hasn't changed (these are the 304 responses).
You'll need to a) scrutinize the pagespeed messages more closely B) assess them against your requirement and C) look at real world traffic in your access log wrt 304s.
You do not want mod_cache for static files.
I'm trying to set it up so that the browser will cache the webfonts for a long period and also attempting to gzip them for a faster download.
From what I can understand you can do this via your httpd.conf file in Apache or via .htaccess.
I'm not sure how to tell if gzip is enabled though, I read something about searching your httpd.conf file for DEFLATE; I did that, but found nothing - so not sure if it's enabled or not!?
Anyway, I have put this code below into the .htaccess file, partially because I didn't know where to put it in the httpd.conf file and partially because it's easier to make changes in .htaccess file without bothering my host continually.
Here is the code..
# Add correct content-type for fonts
AddType application/vnd.ms-fontobject .eot
AddType font/ttf .ttf
AddType font/otf .otf
AddType font/x-woff .woff
AddType image/svg+xml .svg
# Compress compressible fonts
AddOutputFilterByType DEFLATE font/ttf font/otf image/svg+xml
# Add a far future Expires header for fonts
ExpiresByType application/vnd.ms-fontobject "access plus 1 year"
ExpiresByType font/ttf "access plus 1 year"
ExpiresByType font/otf "access plus 1 year"
ExpiresByType font/x-woff "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
Now, I'm wondering if this is correct or not as I also seen this similar, but different code for the expiry..
ExpiresByType application/x-font-ttf "access plus 1 month"
ExpiresByType font/opentype "access plus 1 month"
ExpiresByType application/x-font-woff "access plus 1 month"
ExpiresByType image/svg+xml "access plus 1 month"
ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
Does it matter where you place it in the .htaccess file or can it go anywhere?
ExpiresByType can go in your httpd.conf, virtualhost config or htaccess, as shown in the apache documentation overview box at the top of each directive entry:
http://httpd.apache.org/docs/2.2/mod/mod_expires.html#expiresbytype
The Context listing is how you can tell which configuration files you can put your various Apache directive types into.
Assuming you are using PHP, your phpinfo details should tell you if gzip is enabled.
Edit
In response to your question about correct way MIME type for your fonts, in terms of their file association with the Apache Server, my mime.types file (found in apache conf folder where your httpd.conf lives) tells me that
application/x-font-(extension)
would be the association to use with ExpiresByType. I would suggest getting the fonts working first, and then checking the headers for the font url to see if its giving proper expiration date.
As for the browsers receiving the web fonts, this article seems to indicate that MIME types aren't considered and thus don't matter. But yet this one seems to contradict that. As I understand it, there is no official font/ MIME type so any browser implementation is outside the MIME specifications.
Related questions:
Proper MIME type for fonts
Correct Apache AddType directives for font MIME types
I've not seen anything specifying placement requirements in .htaccess so you should be safe putting these rules wherever you see fit, although if you do AddTypes you need to do so above any further directives that reference that declared Type. It's probably best to put these near the top above your rewrite rules.
I would like to check the age of the document in the webpage, but it does not show! Here is the result of a telnet to the server:
telnet av.hostoi.com 80
Connected to av.hostoi.com. HEAD / HTTP/1.0
HTTP/1.1 200 OK Date: Tue, 23 Oct 2012 16:55:40 GMT
Server: Apache
X-Powered-By: PHP/5.2.17
Connection: close
Content-Type: text/html
Connection closed by foreign host.
On another server the following 2 lines are also included which are not present above:
Last-Modified: Fri, 17 Jun 2011 11:17:45 GMT
ETag: "2ce392-b1-4a5e688eae840"
So I searched the Internet and as far as I could figure out, there should be a configuration in Apache to set headers on and etag on in htaccess. But I couldn't find any place that shows me that.
Here are the loaded modules in Apache if it would help:
core mod_authn_file mod_authn_default mod_authz_host mod_authz_groupfile mod_authz_user mod_authz_default mod_auth_basic mod_include mod_filter mod_log_config mod_env mod_expires mod_headers mod_setenvif mod_version prefork http_core mod_mime mod_status mod_autoindex mod_asis mod_info mod_vhost_alias mod_negotiation mod_dir mod_actions mod_alias mod_rewrite mod_so mod_php5 mod_ruid2
As far as I read mod_header must be enabled which seems to be the case.
Any help on this?
edit:
tried the proposed solution:
put a .htaccess file in / folder even though there is a file named do not upload here.
contents of .htaccess:
<code>
# Do not remove this line, otherwise mod_rewrite rules will stop working
RewriteBase /
Options -Indexes
SSILastModified on
<IfModule mod_expires.c>
FileETag MTime Size
ExpiresActive on
ExpiresDefault "access plus 10 days"
ExpiresByType application/javascript "access plus 1 week"
ExpiresByType application/x-javascript "access plus 1 week"
ExpiresByType application/x-shockwave-flash "access plus 1 week"
ExpiresByType text/css "access plus 1 week"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/x-icon "access plus 6 month"
ExpiresByType image/ico "access plus 6 month"
</IfModule>
</code>
i put this file in public_html folder and in the sub folder nod_update3 where the file update.ver exists.
then i execute the script that checks the age of the document like so:
./check_http -H av.hostoi.com -u /nod_update3/update.ver -M 2d
HTTP CRITICAL: HTTP/1.1 200 OK - Document modification date unknown - 26316 bytes in 0,159 second response time |time=0,158965s;;;0,000000 size=26316B;;;0
as you can see no modification date is shown even though on the ftp client it shows it was last modified 25.10.2012
i tried the check on another file in the same folder like so:
./check_http -H av.hostoi.com -u /nod_update3/em000_32_l0.nup -M 2d
HTTP CRITICAL: HTTP/1.1 200 OK - Last modified 13,5 days ago - 56472 bytes in 1,059 second response time |time=1,059014s;;;0,000000 size=56472B;;;0
srvmon plugins #
as you can see the date modification is known. so why the problem with ver file?
the file can be checked in this url:
http://av.hostoi.com/nod_update3//update.ver
The problem is that you have caching of static content enabled on first server, and on second one that is not the case.
Please take a look in apache main configuration file,virtual host or .htacess on second server
if you have something similar to:
<IfModule mod_expires.c>
FileETag MTime Size
ExpiresActive on
<filesMatch "\.ver$">
ExpiresDefault "modification plus 2 week"
</filesMatch>
</IfModule>
Also you need to enable apache module mod_expires.
Hope this helps!
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);
}
One possible solution here is to replace "SSILastModified on" with "Xbithack Full".