Showing posts with label PHP Apache. Show all posts
Showing posts with label PHP Apache. Show all posts

Tuesday, 18 September 2018

Compressing files on Apache with mod_deflate

It's possible with the Apache web server to compress files that are sent to the browser so less bandwidth is consumed and the load time should generally be faster. The module in Apache 2.0 and up is called mod_deflate and for older versions of Apache there was, what I recall as being, a third party module called mod_gzip. In this article I am looking at mod deflate on Apache 2.x
In order to compress files using mod_deflate on Apache 2.x you first need to load the module, so you'll need to edit the Apache configuration. The exact location of the configuration file varies between each Linux/BSD distro, but it's often found at /etc/httpd/httpd.conf or /etc/apache2/httpd.conf, or /etc/httpd/conf/httpd.conf or /etc/apache2/conf/httpd.conf. If you are unsure of its location locate httpd.conf will usually send you in the right direction.
So now that you've found the Apache config file, open it up in your favourite text editor as root or using sudo, and add this line:
LoadModule deflate_module modules/mod_deflate.so
and this section:
<Location />
    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/x-js text/css
</Location>
The above example will compress all html, plain text, xml, javascript and css files. You can change which are compressed by adding to or removing from the list above when you add it to your configuration. You can also vary it on a virtualhost by virtualhost basis, and/or a directory by directory basis. The above example, added to the main httpd.conf file will apply it to all virtualhosts on the web server.
After you've adjusted the httpd.conf settings you'll then need to reload Apache:
/etc/init.d/httpd reload
The affect of mod_deflate can be seen in a couple of examples below, with compression enabled for javascript and css. The following are extracts from the Apache log file before and after mod_deflate was enabled. The file size is bolded.

No compresssion:

192.168.1.10 - - [02/Nov/2007:10:09:19 +1300] "GET /js/prototype.js HTTP/1.1" 200 122911 "-" "Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.7 (like Gecko) SUSE"
192.168.1.10 - - [02/Nov/2007:10:17:02 +1300] "GET /style/style.css HTTP/1.0" 200 7039 "-" "Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.7 (like Gecko) SUSE"

Compression enabled

192.168.1.10 - - [02/Nov/2007:10:12:32 +1300] "GET /js/prototype.js HTTP/1.1" 200 28138 "-" "Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.7 (like Gecko) SUSE"
192.168.1.10 - - [02/Nov/2007:10:16:10 +1300] "GET /style/style.css HTTP/1.1" 200 2149 "-" "Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.7 (like Gecko) SUSE"
As you can see, the Javascript file was 122911 bytes when not compressed and 28138 bytes when compressed; the CSS file was 7039 bytes when not compressed and 2149 bytes when compressed. Results will vary depending on the contents of the file.
Some file types are already compressed, such as graphics files, music files and similar, so you shouldn't attempt to compress those files types. Generally it will just be text files that you would want to compress.
On a final note, compressions takes up additional CPU cycles and memory at both the server and the client, so you need to be careful about what you compress. For example it may be much better to leave HTML, CSS or Javascript files served in their normal state if they are quite small anyway because the overhead required to compress and decompress may not justify the small amount of bandwidth savings.
The full documentation for mod_deflate can be found in the Apache documentation

A note on the mime types

I was setting this up for another site for Javascript files and discovered the files were not being compressed. After messing around for a little while I realised that Apache was using a different mime type for Javascript and as soon as I changed it and reloaded again it worked.
On Apache on CentOS 5.x the mime types are located from /etc/mime.types but this location will vary from distribution to distribution. If you locate the "TypesConfig" directive in your Apache httpd.conf this will show you where it's getting them from, and you can ensure you are using the correct mime type.
Alternatively, use Lynx or similar to do a headers dump on the file and it will tell you want the mime type is, e.g.:
$ lynx -head -dump http://www.example.com/js/jquery-1.2.6.min.js
HTTP/1.1 200 OK
Date: Wed, 25 Jun 2008 03:25:53 GMT
Server: Apache/2.2.3 (CentOS)
Last-Modified: Wed, 25 Jun 2008 03:24:47 GMT
ETag: "38016-d9de-37f45dc0"
Accept-Ranges: bytes
Content-Length: 55774
Connection: close
Content-Type: application/x-javascript
The Content-Type: line tells us the mime type is "application/x-javascript" so it's then just a matter of putting this into your location directive like so (obviously putting your appropriate mime type(s) there):
<Location />
    AddOutputFilterByType DEFLATE application/x-javascript
</Location>
and then reload Apache again.Related posts:

Using Apache mod_expires to control browser caching

Apache's mod_expires module allows settings by file type to control how long browsers cache files. This is useful for ensuring browsers cache image, Javascript and/or CSS files without making additional unecessary requests when loading pages.

Making sure mod_expires is enabled

mod_expires may not be enabled by default in your Apache install. On a Debian based system (e.g. Debian, Ubuntu and their derivitives) run the following command to enable mod_expires:
sudo a2enmod expires
The resulting output will look like this:
Enabling module expires.
Run '/etc/init.d/apache2 restart' to activate new configuration!
Follow the instructions to restart Apache to enable mod_expires. If it had already been enabled you would instead see this:
Module expires already enabled
On a RHEL/CentOS based system, edit /etc/httpd/conf/httpd.conf and make sure the following line is not commented out, restarting Apache after making any changes.
LoadModule expires_module modules/mod_expires.so

Configuring mod_expires

Add any required rules to the .htaccess file in the website's root directory. If there isn't already an .htaccess file then create one.
The file should contain this line:
ExpiresActive on
And then the necessary rules. To configure how long a file type should be cached for, add a line following this rule:
ExpiresByType [mime type here] "access plus [number] [timeframe]"
The timeframe should be one of years, months, weeks, days, hours, minutes or seconds.
Here's an example from one of my sites:
ExpiresActive on
ExpiresByType application/javascript "access plus 1 months"
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 text/css "access plus 1 months"
This ensures that all Javascript, image and CSS files on the website are cached for a month from the first request. Because the browser will cache these quite aggressively, if any changes are made to the files they will not be reflected in the browser. If changes to a file are required then the filename must be changed to avoid caching issues, so be sure to set rules carefully.
(Please note that the mime type for Javascript can vary somewhat depending on the distro and version of Apache used. Read my "Content-type for Javascript with Apache" post for some more details about this).
I personally have a system in place for websites where I use these rules so that whenever changes are made to the Javascript or CSS files they are given unique names.
As far as images are concerned, I create new files with unique names if they need to be changed.
By doing this with the expires rules I am able to get the browsers to do a high level of caching but still have them get fresh files if and when I need them to.

Related posts:

Wednesday, 12 September 2018

Get Apache to parse .html files as PHP

When PHP is installed in Apache files with the .php extension are interpreted as PHP scripts. It is possible to make any file extension be parsed as PHP including .html.

Make a .html file be parsed as PHP

This can be done at the following levels:
  1. The main Apache configuration which will apply to all virtualhosts
  2. An individual <virtualhost>
  3. In an .htaccess file
It can either be done for everything, or using e.g. a <Directory> block to limit it to a specific directory. With an .htaccess file it will apply to the directory the .htaccess file is in and all subdirectories below that one.
Simply add the following line to the appropriate location as noted above:
AddType application/x-httpd-php .html
Now all files with a .html extension will be parsed as PHP.
A note of warning: it is not generally a good idea to make all .html files be parsed as PHP. If they do not contain any PHP code then they will still invoke the PHP interpreter which will cause additional overhead on the web server. Make sure you have good reason to do so, and ideally limit it to an individual virtualhost and then possibly to particular directories.