My most used htaccess settings
The file .htaccess allows us to change some of the settings
of a server for a particular directory and it's subdirectories. While it
is preferable to make this type of configurations in the server
configuration file itself by the use of a <Directory>
section, sometimes we simply don't have access to this configuration
file, specially when we have a shared hosting account. Most shared
hosting providers allows us to make changes to the behavior of the
server only in this way.
The .htaccess file is a simple text file that we name like
this, note the dot at the beginning of the file name for this is
important. We can edit this file in our favorite text editor, and then
upload it to our server, placing it in the folder where we want to alter
the default behavior.
Some of the things that we can do with the .htaccess file
are password protect a folder, create redirections, adjust php settings,
control the caching of files, control how extensions are treated by the
server (we can make an HTML file be run through the php module instead
of just serve it), and in general alter how files are served to the
visitors.
This section is likely to be updated in the future with new functionality, however, I will try to cover the most common uses that I have for this file.
Topics
Disabling the file listing
in directories without an index file
Creating
a redirection or changing the response status of missing files
Creating
custom error response pages
Setting
the cache expiration time of different types of files
Compressing
the files before serve them to the browser
Password
protecting a folder
Treating HTML
files as PHP files
Changing default
PHP settings
Disabling the file listing in directories without an index file
By default, when we access a subfolder in a website that does not have an index file (whether it's .html, .htm, .php), the server will show us an list of the content in the folder, the typical "Index of" followed by all of the files and subdirectories in the directory we are accessing. This setting is particularly dangerous, as it may expose the inner structure of our website and/or provide access to files and information that we would rather not show publicly but that for some reason we put in there.
In order to disable this setting, we can create an .htaccess
file in the root folder of the website, and add to it the line:
Options -Indexes
Creating a redirection or changing the response status of missing files
When we request a file from a server, and this file is not found, by default the server returns a 404 status code, a status that indicates the browser (and us, as the browser will present us this status code) that said file is not available there. But it is only a generic message, it indicates nothing but the fact that right at that very moment the file is not accessible. However sometimes we can indicate the browser why the file is not currently there so the browser can act properly. My three most used cases are:
The file has been moved permanently
The status 301 indicates the browser that the file has been permanently
moved to a different location. This is a good way to implement a
redirection with .htaccess, as browsers with link editing
capabilities will automatically update all references to the file to the
new address. And this response is cacheable, which means that a browser
won't keep trying to access that address and will instead request the
new address of the file. Just add to your .htaccess the
following line, indicating the file that was moved, which may be any
type of file, and the new location of the file.
Redirect 301 /path/from/htaccess/file.html
http://www.domain.tld/path/file.html
The file has been moved temporally
The status 307 indicates the browser that the file was moved, but that this move is only temporal, the browser will follow the new address as it does when it receives a 301 status, but it will not change any links to the file, nor will it create a cache with this new address (unless it's indicated by a Cache-Control or an expiration header field), the browser will continue requesting the original direction every time.
Redirect 307 /path/from/htaccess/file.html
http://www.domain.tld/path/file.html
The file is gone
The status 410 indicates the browser that the file being requested has been permanently removed from the server. Unlike the 404 status, which only indicates that the file is not there, this status code indicates that the file is not going to be there anymore.
Redirect 410 /path/from/htaccess/file.html
Creating custom error response pages
Instead of send back to the browser a status code, so that it can
present us with it's own error page, we can create custom error pages,
e.g. for the errors 401 (Unauthorized) and 404 (not found). All we need
to do it's modify our .htaccess file, adding the following
lines:
ErrorDocument 401 /path/to/401.html
ErrorDocument
404 /path/to/404.html
Setting the cache expiration time of different types of files
This setting will indicate the browser how long it should keep the cache
of the files so it won't query the server for this files every time that
they are needed, this is what I refer to when I speak of Cache-Control.
What happens here is that the server will send a "Expires"
header accompanying the files that it serves.
We can define the default expiration time of files with the directive ExpiresDefault
followed by a base and a time, or we can specify the expiration time of
specific types of files with ExpiresByType, followed by a
file type, a base and a time.
The base can be either the access time or the modification time, where access starts counting the time since the browser requested the file, and modification starts counting the time from the last time that this file was modified. Note that if you use a modification based expiration, the Expires header will not be added to content that does not come from a file in the disk, as in the case of an on-the-fly generated image, this is of course because a non existent file can not possibly have a modification date.
And the time is used in conjunction with the base, by adding a plus
and a time, this time can be given in seconds, minutes, hours, days,
weeks, months or years, and it can be expressed in singular if we only
use one unit, we can specify it as "1 minute" or as "10 minutes".
In this example I am going to set a default expiration time for all
files of one day, by using the ExpiresDefault directive,
and then specify different expiration times for common types of files
using ExpiresByType.
<ifModule mod_expires.c>
ExpiresActive
On
ExpiresDefault "access plus 1 day"
ExpiresByType
image/png "access plus 30 days"
ExpiresByType
image/jpeg "access plus 4 weeks"
ExpiresByType
image/gif "access plus 1 month"
ExpiresByType
image/x-icon "access plus 1 year"
ExpiresByType
application/javascript "modification plus 2 weeks"
ExpiresByType
text/css "modification plus 14 days"
</ifModule>
Compressing the files before serve them to the browser
About every modern browser have the ability of request, accept and process the information received from the server in a compressed way, in order to reduce the loading time of the web site when it is being served.
To enable the compression of files, in case the server is not configured
to do this by default, we need to add to our .htaccess file
the line:
AddOutputFilterByType DEFLATE text/html text/plain
text/xml text/css application/javascript application/x-javascript
application/rss+xml application/atom_xml text/javascript
We don't add here images and other type of content, because our images and other elements should be already using some sort of compression. The server doesn't start to serve every file compressed, only does it when the browser tell it that it can receive compressed information.
Password protecting a folder
In order to protect the contents of a folder we need to create a file
containing a list of valid usernames and passwords, and add some lines
to our .htaccess file. The username and the password will
be send in plain text to the server, so it is still vulnerable to
man-in-the-middle attacks, unless we use SSL (highly recommended).
We start by creating a file called .htpasswd, change the
permissions of the file to 644.
touch .htpasswd
chmod 644 .htpasswd
Once this is done, we need to fill the file with the usernames and the
(preferably and highly recommended to be encrypted) passwords. If you
are using Linux or another Unix based operating system and count with
the program htpasswd this is easy to do, or even better, if
you can log in via SSH to your server you can use htpasswd
to manage the usernames and passwords in the file. If not, there are
multiple online utilities that will allow you to generate the encrypted
passwords for use in your .htpasswd file (I don't trust any
of them, but then I am a paranoid person). Here is one of such sites http://www.htaccesstools.com/htpasswd-generator/
To generate the password and store it along with the username in the file, we can use:
htpasswd [passwd file] [user]
e.g.
htpasswd .htpasswd juan
This will prompt you for the password, and then it will encrypt it and
store it in the .htpasswd file.
By default, if apache is installed in any system but Windows, Netware
and TPF (Transaction Process Facility, an IBM mainframe) it will use the
function crypt() to encrypt the password. Using this
command we can create as many users as we want, as well as change the
password of any existent user in the file.
Optionally you can use the parameter -n to obtain the results of the command:
htpasswd -n juan
Again, this will prompt you for the password, and it will return something like this:
juan:n94xSo6uSwhCY
You can open the file .htpasswd in your favorite text
editor and paste the information, one per line if you give access to
multiple users.
Other ways of encrypt the password may be with MD5 by using the command -m,
this is the default in Windows, Netware and TPF. Or you can use SHA
instead with the parameter -s. And the parameter -d
makes the command use the crypt function but this is already the default
behavior in most systems.
Some additional parameters of htpasswd are -c which will
create the file if this doesn't already exist, or rewrite it and
truncate it if it already exists, leaving only the new user on it. The
parameter -D will delete a user from the .htpasswd
file if this exist.
And finally, in case we want to use this command in conjunction with
other commands, we can use the parameter -b which allow us
to specify the password in the command line. For obvious reasons, this
is not a very secure way to do this, specially if the command is logged
in the history (we can use a space before the command to prevent it from
being recorded in our history, but still, this is not a recommended way
to do it).
htpasswd .htpasswd juan randompassword
Once we are done creating users that will be able to access the
directory and it's subdirectories, we need to add the following lines to
our .htaccess file located in the folder that we want to
protect:
AuthName "Please authenticate in order to access
the contents of this folder"
AuthType Basic
AuthUserFile
/full/path/to/.htpasswd
Require valid-user
Where AuthName is the text that appears in the prompt
requesting the username and the password. AuthType is the
type of authentication required, in this case we want a simple dialog
box prompting us for a username and a password, so we use Basic.
AuthUserFile is the file where the list of usernames and
passwords is located, in this case is named .htpasswd and
is located in the same folder as our .htaccess file. And
finally Require valid-user makes this folder only
accessible to valid users, as defined in the .htpasswd file.
Treating HTML files as PHP files
To treat files with an html extension (or any other extension) as PHP
files, i.e. to make the server parse the html files through the PHP
module instead of just serving them directly to the browser, we need to
add the following lines to our .htaccess file:
AddType application/x-httpd-php .htm .html
Update: PHP does not always run as a module, some times it runs as CGI (Common Gateway Interface). To achieve the same thing when PHP is used as CGI use the following code:
AddHandler application/x-httpd-php .html .htm
In some servers running PHP as CGI the following code would also work:
AddHandler php5-cgi .html .htm
Changing PHP settings
If we don't have access to the php.ini file, some hosting providers allows to change some of it's default settings by modifying the .htaccess file, e.g. if I am generating thumbnails of uploaded images as I described in some of my previous posts (scaled thumbnails, cropped and scaled thumbnails), the default memory limit of PHP in some hosting providers is as low as 2 MB, this is just not enough to process images with the sizes that are used nowadays, so I change this limit to something bigger, something like 16 MB should be good enough for most images. But this is not the only useful setting that we can change from the default php.ini configuration, I will probably make a post on this later. The default memory limit in for PHP scripts has been increasing, the default before PHP 5.2.0 was 8 MB, after PHP 5.2.0 it was increased to 16 MB, currently it is 128 MB. Also, to remove the memory limit, this can be set to -1 .
To change a PHP default setting in our .htaccess file, the
option AllowOverride Options (or AllowOverride all)
must be on in the server. If it is on, we just need to add the following
line to our .htaccess file:
php_value memory_limit 16M
This is, php_value, followed by the setting name, followed
by the new value.
