Archive

Posts Tagged ‘Apache’

Redirect One Directory To Another With .htaccess

May 19th, 2008 No comments

To stop access to a directory (and anything in that directory) all you need is a simple RewriteRule.

RewriteEngine on
RewriteBase /
RewriteRule ^exampledirectory/(.*)$ / [R=301,L]

In this example, if this .htaccess file resides in the root directory of the site and you try to access anything within /exampledirectory you will be redirected back to the root folder. To redirect to another folder (like anotherdirectory) on your web server use the following rule.

RewriteEngine on
RewriteBase /
RewriteRule ^exampledirectory/(.*)$ /anotherdirectory [R=301,L]

Categories: Apache Tags: , , ,

When To Use .htaccess Files

May 1st, 2008 No comments

Hypertext access, or .htaccess files, allow you to change the Apache configuration on a by directory basis. However, you should always use the main server configuration file to do configuration changes whenever possible. This is because when Apache is configured to process .htaccess files it looks at every directory underneath the current directory to see if there are any files present, resulting in a slightly longer page load time. Although this might not be noticeable with low traffic levels, at high traffic levels it can cause sites to slow down. You should therefore use .htaccess files only when the main server configuration file (http.conf) is inaccessible.

To increase performance you can use the AllowOverride directive in your top level directory, or any directory who’s subdirectories do not use .htaccess files. This will stop Apache from searching through all sub directories.

AllowOverride None

Having .htaccess files can also be a security problem. In order to stop anyone writing to your .htaccess files you must set the permissions at "644". This allows universal read access and user-only write access. You should also make sure that your Apache configuration contains the following lines that will stop external access to your .htaccess files.

<Files .htaccess>
 order allow,deny
 deny from all
</Files>

Preventing Image Bandwidth Theft With .htaccess

April 21st, 2008 No comments

When people link to your images from their own site they are essentially using your bandwidth to show images on their site, this is also known as hotlinking.

The simplest way of preventing people from doing this is to add a .htaccess file to only allow locally linked images to be served. This checks the domain that is linking to your images by using the referrer and if the domain does not equal you own site then a different image is served, in this case blank.jpg.

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_REFERER} !^http://(.+\.)?talkincode\.com/ [NC]
RewriteCond %{HTTP_REFERER} !^http://(.+\.)?google\.co\.uk/ [NC]
RewriteCond %{HTTP_REFERER} !^http://(.+\.)?google\.com/ [NC]
RewriteRule .*\.(jpe?g|gif|bmp|png)$ /images/blank.jpg [L]

You can also prevent hotlinking from high traffic sites like myspace by using the following .htaccess file.

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_REFERER} ^http://(.+\.)?myspace\.com/ [NC,OR]
RewriteCond %{HTTP_REFERER} ^http://(.+\.)?blogspot\.com/ [NC,OR]
RewriteCond %{HTTP_REFERER} ^http://(.+\.)?livejournal\.com/ [NC]
RewriteRule .*\.(jpe?g|gif|bmp|png)$ /images/blank.jpg [L]

Instead of returning a blank image you could produce a 403 Forbidden error by using the F RewriteRule flag.

RewriteRule .*\.(jpe?g|gif|bmp|png)$ - [F]

Another way is to use the mod_setenvif module to figure out what the referrer name is. You will first need to go into your Apache httpd.conf file and make sure that the mod_setenvif module is enabled.
LoadModule setenvif_module modules/mod_setenvif.so
If it isn’t enabled then uncomment the line and restart Apache. This module is normally turned on by default so it should be enabled on most hosts.

Next, upload the following .htaccess file to your root directory, replacing the domain name with your own.

SetEnvIfNoCase Referer "^http://www.talkincode.com/" locally_linked=1
SetEnvIfNoCase Referer "^http://www.talkincode.com$" locally_linked=1
SetEnvIfNoCase Referer "^http://talkincode.com/" locally_linked=1
SetEnvIfNoCase Referer "^http://talkincode.com$" locally_linked=1
SetEnvIfNoCase Referer "^$" locally_linked=1
<FilesMatch "\.(bmp|gif|png|jpe?g)$">
 Order Allow,Deny
 Allow from env=locally_linked
</FilesMatch>

This method simply stops the image being served, rather than presenting a different image.

However, there is nothing you can do to stop people downloading images from your site and using them on their own site. If your images are copyrighted in anyway then you will need to contact the site directly to get them to remove your images.

Categories: Apache Tags: , , ,

Using mod_rewrite On Form Parameters

March 5th, 2008 11 comments

Using mod_rewrite on websites is fairly straightforward and can create some lovely looking URL structures. Instead of having a URL that contains lots of odd looking parameters like this:
http://www.example.com/example.php?parameter1=value1&parameter2=value2

You can use a .htaccess file to rewrite the URL on the server side in order to shorten this to something like this:
http://www.example.com/p-value1

In this occasion the value of parameter2 will always be value2 so we can just include that in the rewrite rule, which would look something like the following. $1 is a back-reference to the first parenthesized value matched in the RewriteRule.
RewriteRule ^p-(.*)$ /example.php?parameter1=$1&parameter2=value2 [L]

Remember to turn ensure that the FollowSynLinks directive is enabled and that the rewrite engine is turned on before starting your rewrite rules. FollowSynLinks should have been enabled by your server administrator, but you can include here just in case they haven’t.
Options +FollowSymLinks
RewriteEngine On

You can also make sure that mod_rewrite is actually installed by enclosing all of this in an if statement. This will stop the server throwing an error if you don’t have mod_rewrite.
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
</IfModule>

What PHP sees on the server side is exactly the same as normal so you can retrieve the parameters with a standard $_GET lookup.

However, the default behaviour of forms messes this up. Lets say that we had a search page that we created a rewrite rule so that it read like this:
http://www.example.com/s-value1

This redirects to the page search.php and passes any parameters to that page. The problem here is if we call the same page through a form. Here is an example search form.
<form action="search.php" method="get">
<input type="text" name="q" value="" />
<input type="submit" name="s" value="Search" />
</form>

When this is run with the string "test" the URL looks like this.
search.php?q=test&s=Search

This is the default browser behaviour, but it still messes up the nice URL structure created previously. There is a way to fix this. Have a look at the following .htaccess file.

<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
 
RewriteCond %{REQUEST_URI} /search.php$
RewriteCond %{QUERY_STRING} ^q=([A-Za-z0-9\+]+)&s=Search$
RewriteRule ^(.*)$ /s-%1? [R=301,L]
 
RewriteRule ^s-(.*)$ /search.php?q=$1&s=Search&a=1 [L]
</IfModule>

Here we are using the RewriteCond directive which allows us to test for certain conditions. In this case we have two conditions.
RewriteCond %{REQUEST_URI} /search.php$
RewriteCond %{QUERY_STRING} ^q=([A-Za-z0-9\+]+)&s=Search$

The first condition allows us to only run the rule on the page search.php. This stops any annoying confusion if we want to pass a similar query string to a different page. The second condition allows us to test the query string to see if it contains the parameters we are looking for. The %{QUERY_STRING} bit is a reference to the actual query string passed, minus the question mark at the beginning. In this case we want to trap the parameter q with any value and the parameter s with the value of Search. The dollar sign at the end is very important, but I’ll come back to that.

The first rewrite rule redirects the page search.php to the URL /s- and whatever the query string was. The %1 is a back-reference to the first parenthesized value matched in the most-recently-matched RewriteCond.
RewriteRule ^(.*)$ /s-%1? [R=301,L]

We then also need to include a rewrite rule that will recognise the new URL and act on it. However, want we don’t want to do is confuse the server and put it into an endless loop, which is quite easy since we are redirecting from search.php to search.php. So what we do is include the parameter "a" at the end of our rewrite rule with the value of 1.
RewriteRule ^s-(.*)$ /search.php?q=$1&s=Search&a=1 [L]

Going back to the second rewrite condition above we included a dollar sign at the end of the rule. This meant that the string had to end there, so if we include anything else after the end of the query string the rewrite condition will return false. So although we don’t actually use the a in our script it is needed there to stop the server going into an infinite loop of redirects.

For more information on mod_rewrite and other .htaccess examples have a look at the excellent tutorial at Ask Apache.

Apache Bench Tool

February 25th, 2008 No comments

The Apache Bench tool can be found in the bin directory of any standard instillation of the Apache HTTP server. It can be used to test the response times of any web server you want and can be useful if you want to stress test a mission critical server before it goes live.

To use the tool open a command prompt (or terminal), navigate the Apache bin folder and find the program ab, this is the Apache Bench tool. The simplest form of running the tool is to use a single URL. However, you must enter a full file name or the tool will give you an invalid URL error.

./ab http://www.google.com/index.html

This gives the following output.

Benchmarking www.google.com (be patient).....done
 
Server Software: gws
Server Hostname: www.google.com
Server Port: 80
 
Document Path: /index.html
Document Length: 231 bytes
 
Concurrency Level: 1
Time taken for tests: 0.94090 seconds
Complete requests: 1
Failed requests: 0
Write errors: 0
Non-2xx responses: 1
Total transferred: 590 bytes
HTML transferred: 231 bytes
Requests per second: 10.63 [#/sec] (mean)
Time per request: 94.090 [ms] (mean)
Time per request: 94.090 [ms] (mean, across all concurrent requests)
Transfer rate: 0.00 [Kbytes/sec] received
 
Connection Times (ms)
  min mean[+/-sd] median max
Connect: 41 41 0.0 41 41
Processing: 52 52 0.0 52 52
Waiting: 51 51 0.0 51 51
Total: 93 93 0.0 93 93

In this example, the tool has made a single request to the Google server. Apache Bench can be made to complete multiple, concurrent requests to the server with the addition of two flags. The first flag is -n, which is used to tell Apache Bench how many tests it should run, if the number 5 is used, the tool will repeat itself 5 times. The second flag is -c, which is used to tell Apache Bench how many concurrent connections should be made. The following example repeats the original test, but this time uses the -n and -c flags to run the tests 10 times, with 10 connections each time.

./ab -n 10 -c 10 http://www.google.com/index.html

This produced the following output.

Benchmarking www.google.com (be patient).....done
 
Server Software: gws
Server Hostname: www.google.com
Server Port: 80
 
Document Path: /index.html
Document Length: 231 bytes
 
Concurrency Level: 10
Time taken for tests: 0.229686 seconds
Complete requests: 10
Failed requests: 0
Write errors: 0
Non-2xx responses: 10
Total transferred: 5900 bytes
HTML transferred: 2310 bytes
Requests per second: 43.54 [#/sec] (mean)
Time per request: 229.686 [ms] (mean)
Time per request: 22.969 [ms] (mean, across all concurrent requests)
Transfer rate: 21.77 [Kbytes/sec] received
 
Connection Times (ms)
    min mean[+/-sd] median max
Connect: 41 55 9.1 55 68
Processing: 54 100 37.9 87 164
Waiting: 51 97 37.8 83 159
Total: 95 155 43.9 149 229
 
Percentage of the requests served within a certain time (ms)
50% 149
66% 175
75% 189
80% 210
90% 229
95% 229
98% 229
99% 229
100% 229 (longest request)

When running the tool on your own server you will rarely see times like this. For example, when running the tool with the same parameters on a local server with a standard WordPress install it longest request time was 4227.

To find out a list of the options available just type in the following.
./ab -h

Categories: Apache Tags: , , , , , ,