Friday, April 2, 2010

htaccess : Stop browser prefetching & information

RewriteEngine On
SetEnvIfNoCase X-Forwarded-For .+ proxy=yes
SetEnvIfNoCase X-moz prefetch no_access=yes

# block pre-fetch requests with X-moz headers
RewriteCond %{ENV:no_access} yes
RewriteRule .* - [F,L]

.htaccess : Prevent Files image/file hotlinking and bandwidth stealing

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?askapache.com/.*$ [NC]
RewriteRule \.(gif|jpg|swf|flv|png)$ /feed/ [R=302,L]

.htaccess : Only allow GET and PUT Request Methods

Article: Request Methods

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_METHOD} !^(GET|PUT)
RewriteRule .* - [F]

.htaccess : Redirecting Wordpress Feeds to Feedburner

Full article:Redirecting Wordpress Feeds to Feedburner

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^/feed\.gif$
RewriteRule .* - [L]

RewriteCond %{HTTP_USER_AGENT} !^.*(FeedBurner|FeedValidator) [NC]
RewriteRule ^feed/?.*$ http://feeds.feedburner.com/apache/htaccess [L,R=302]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

htaccess : Require no subdomain

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} \.([^\.]+\.[^\.0-9]+)$
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

htaccess : Require no subdomain

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} \.([a-z-]+\.[a-z]{2,6})$ [NC]
RewriteRule ^/(.*)$ http://%1/$1 [R=301,L]

Require the www without hardcoding

Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\.[a-z-]+\.[a-z]{2,6} [NC]
RewriteCond %{HTTP_HOST} ([a-z-]+\.[a-z]{2,6})$ [NC]
RewriteRule ^/(.*)$ http://%1/$1 [R=301,L]

.htaccess : Rewrite underscores to hyphens for SEO URL

Converts all underscores “_” in urls to hyphens “-” for SEO benefits… See the full article for more info.

Options +FollowSymLinks
RewriteEngine On
RewriteBase /

RewriteRule !\.(html|php)$ - [S=4]
RewriteRule ^([^_]*)_([^_]*)_([^_]*)_([^_]*)_(.*)$ $1-$2-$3-$4-$5 [E=uscor:Yes]
RewriteRule ^([^_]*)_([^_]*)_([^_]*)_(.*)$ $1-$2-$3-$4 [E=uscor:Yes]
RewriteRule ^([^_]*)_([^_]*)_(.*)$ $1-$2-$3 [E=uscor:Yes]
RewriteRule ^([^_]*)_(.*)$ $1-$2 [E=uscor:Yes]

RewriteCond %{ENV:uscor} ^Yes$
RewriteRule (.*) http://d.com/$1 [R=30

.htaccess : block access to files during certain hours of the day

Options +FollowSymLinks
RewriteEngine On
RewriteBase /
# If the hour is 16 (4 PM) Then deny all access
RewriteCond %{TIME_HOUR} ^16$
RewriteRule ^.*$ - [F,L]

.htaccess : Internal Redirect .php files to .html files (SEO friendly)

Redirects all files that end in .html to be served from filename.php so it looks like all your pages are .html but really they are .php

RewriteRule ^(.*)\.html$ $1.php [R=301,L]

htaccess : External Redirect .php files to .html files (SEO friendly)

RewriteRule ^(.*)\.php$ /$1.html [R=301,L]

.htaccess : Fix for infinite loops

An error message related to this isRequest exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.or you may seeRequest exceeded the limit,probable configuration error,Use 'LogLevel debug' to get a backtrace, orUse 'LimitInternalRecursion' to increase the limit if necessary

RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule .* - [L]

.htaccess : Removes the QUERY_STRING from the URL

If the QUERY_STRING has any value at all besides blank than the?at the end of /login.php? tells mod_rewrite to remove the QUERY_STRING from login.php and redirect.

RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} .
Rew

htaccess : Check for a key in QUERY_STRING

Uses a RewriteCond Directive to check QUERY_STRING for passkey, if it doesn’t find it it redirects all requests for anything in the /logged-in/ directory to the /login.php script.

RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} !passkey
Rewrite

htaccess : Require no www

Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^askapache\.com$ [NC]
RewriteRule ^(.

.htaccess : Deny access to anything in a subfolder except php fopen

This can be very handy if you want to serve media files or special dowmloeds but only through a php proxy script.

RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^/]+)/.*\ HTTP [NC]
RewriteRule .* - [F,L

.htaccess : Deny Access To Everyone Except PHP fopen

This allows access to all files by php fopen, but denies anyone else.

RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^.+$ [NC]
RewriteRule .* - [F,L]

If you are looking for ways to block or deny specific requests/visitors, then you should definately read Blacklist with mod_rewrite. I give it a 10/10

htaccess : Setting the language variable based on Client

For sites using multiviews or with multiple language capabilities, it is nice to be able to send the correct language automatically based on the clients preferred language.

RewriteCond %{HTTP:Accept-Language} ^.*(de|es|fr|it|ja|ru|en).*$ [NC]
RewriteRule ^(.*)$ - [env=prefer-language:%1]

.htaccess : Sending requests to a php script

This .htaccess rewrite example invisibly rewrites requests for all Adobe pdf files to be handled by /cgi-bin/pdf-script.php

RewriteRule ^(.+)\.pdf$ /cgi-bin/pdf-script.php?file=$1.pdf [L,NC,QSA]

.htaccess : Removing the Query_String

On many sites, the page will be displayed for both page.html and page.html?anything=anything, which hurts your SEO with duplicate content. An easy way to fix this issue is to redirect external requests containing a query string to the same uri without the query_string.

RewriteCond %{THE_REQUEST} ^GET\ /.*\;.*\ HTTP/
RewriteCond %{QUERY_STRING} !^$
RewriteRule .* http://www.askapache.com%{REQUEST_URI}? [R=301,L]

.htaccess : Cache-Friendly File Names

This is probably my favorite, and I use it on every site I work on. It allows me to update my javascript and css files in my visitors cache’s simply by naming them differently in the html, on the server they stay the same name. This rewrites all files for /zap/j/anything-anynumber.js to /zap/j/anything.js and /zap/c/anything-anynumber.css to /zap/c/anything.css

RewriteRule ^zap/(j|c)/([a-z]+)-([0-9]+)\.(js|css)$ /zap/$1/$2.$4 [L]

.htaccess : Loop Stopping Code

RewriteCond %{REQUEST_URI} ^/(stats/|missing\.html|failed_auth\.html|error/).* [NC]
RewriteRule .* - [L]

RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule .* - [L]

.htaccess : Require the www

Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\.askapache\.com$ [NC]
RewriteRule ^(.*)$ http://www.askapache.com/$1 [R=301,L]

.htaccess rewrite examples should begin with:

Options +FollowSymLinks

RewriteEngine On
RewriteBase /

htaccess : URL Rewriting

URL rewriting takes the url submitted by the browser and adjusts it to be interpretted by the web server in a different way. In othewords, rewriting allows you to send people to yourdomain.com/a/1/b/2/c/3 and the server will serve up the page for yourdomain.com/index.php?a=1&b=2$c=3. What this does is allow you to take dynamic urls and rewrite them to look and act like static urls. The benefit to this is that it enables some search engines to index your page using parameters they would not previously have been able to.

URL rewriting can be helpful in a few ways. The most common URL rewriting is done on Apache servers. To set up URL rewriting on an Apache server, you need to be able to access the .htaccess file. In the directory where you want to perform URL rewriting, you need to open the .htaccess file. If it does not have one, create a new one. If you do not know how to do this, click on the .htaccess "home" link to the left.

URL rewriting at its best uses regular expression. HowGuru.com addresses regular expression elsewhere on the site, but a brief statement will suffice here. Here is the structure of a rewrite statement:


RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*)$ page.php?variable_1=$1 [QSA,L]


The "" tells the server to look for the rewrite module, if the server can rewrite urls, then follow the code until "." Othewise, if the server does not have a rewrite module, it will ignore the information between the "if" brackets.

The next line ("RewriteEngine on") activates this function on the server.

The next line ("RewriteCond %{REQUEST_FILENAME} –d")states a condition for the rule to apply. In this case, a file name is being requested.

Finally comes the rule with is proceeded by "RewriteRule". This is followed by the regular expression statement defining what pattern to look for, which is followed by the destination file and/or query string combination to search for on the server.

The regular expression is pretty easy to understand. Regular expression is all about finding patterns, the “^” indicates the beginning of the input. The “$” at the end indicates the end of the input. Numbered variables are assigned to each pattern that meets the criteria in each set of parenthesis. So if I wrote:

RewriteRule ^(.*)$ page.php?var_1=$1 [QSA,L]

The “(.*)” refers to any set of numbers and letters and length long, this is then referred to in the destination page portion of the rule as “$1”.

htaccess : Control access

.htaccess is most often used to restrict or deny access to individual files and folders. A typical example would be an "includes" folder. Your site's pages can call these included scripts all they like, but you don't want users accessing these files directly, over the web. In that case you would drop an .htaccess file in the includes folder with content something like this..

NO ENTRY!
# no one gets in here!
deny from all


which would deny ALL direct access to ANY files in that folder. You can be more specific with your conditions, for instance limiting access to a particular IP range, here's a handy top-level rule for a local test server..

NO ENTRY outside of the LAN!
# no nasty crackers in here!
order deny,allow
deny from all
allow from 192.168.0.0/24
# this would do the same thing..
#allow from 192.168.0


Generally these sorts of requests would bounce off your firewall anyway, but on a live server (like my dev mirror sometimes is) they become useful for filtering out undesirable IP blocks, known risks, lots of things. By the way, in case you hadn't spotted; lines beginning with "#" are ignored by Apache; handy for comments.

Sometimes, you will only want to ban one IP, perhaps some persistent robot that doesn't play by the rules..

post user agent every fifth request only. hmmm. ban IP..
# someone else giving the ruskies a bad name..
order allow,deny
deny from 83.222.23.219
allow from all


The usual rules for IP addresses apply, so you can use partial matches, ranges, and so on. Whatever, the user gets a 403 "access denied" error page in their client software (browser, usually), which certainly gets the message across. This is probably fine for most situations, but in part two I'll demonstrate some cooler ways to deny access, as well as how to deny those nasty web suckers, bad referrers, script kiddies and more.

.htaccess : Password protected directories..

The next most obvious use for our .htaccess files is to allow access to only specific users, or user groups, in other words; password protected folders. a simple authorisation mechanism might look something like this..

a simple sample .htaccess file for password protection:
AuthType Basic
AuthName "restricted area"
AuthUserFile /usr/local/var/www/html/.htpasses
require valid-user


You can use this same mechanism to limit only certain kinds of requests, too..

only valid users can POST in here, anyone can GET, PUT, etc:
AuthType Basic
AuthName "restricted area"
AuthUserFile /usr/local/var/www/html/.htpasses

require valid-user



You can find loads of online examples of how to setup authorization using .htaccess, and so long as you have a real user (or create one, in this case, 'jimmy') with a real password (you will be prompted for this, twice) in a real password file (the -c switch will create it)..

htpasswd -c /usr/local/var/www/html/.htpasses jimmy

..the above will work just fine. htpasswd is a tool that comes free with Apache, specifically for making and updating password files, check it out. The windows version is the same; only the file path needs to be changed; to wherever you want to put the password file.

Note: if the Apache bin/ folder isn't in your PATH, you will need to cd into that directory before performing the command. Also note: You can use forward and back-slashes interchangeably with Apache/php on Windows, so this would work just fine..

htpasswd -c c:/unix/usr/local/Apache2/conf/.htpasses jimmy

Relative paths are fine too; assuming you were inside the bin/ directory of our fictional Apache install, the following would do exactly the same as the above..

htpasswd -c ../conf/.htpasses jimmy

Naming the password file .htpasses is a habit from when I had to keep that file inside the web site itself, and as web servers are configured to ignore files beginning with .ht, they too, remain hidden. If you keep your password file outside the web root (a better idea), then you can call it whatever you like, but the .ht_something habit is a good one to keep, even inside the web tree, it is secure enough for our basic purpose..

Once they are logged in, you can access the remote_user environmental variable, and do stuff with it..

the remote_user variable is now available..
RewriteEngine on
RewriteCond %{remote_user} !^$ [nc]
RewriteRule ^(.*)$ /users/%{remote_user}/$1

.htaccess : 500 error

If you add something that the server doesn't understand or support, you will get a 500 error page, aka.. "the server did a boo-boo". Even directives that work perfectly on your test server at home may fail dramatically at your real site. In fact this is a great way to find out if .htaccess files are enabled on your site; create one, put some gibberish in it, and load a page in that folder, wait for the 500 error. if there isn't one, probably they are not enabled.

If they are, we need a way to safely do live-testing without bringing the whole site to a 500 standstill.

Fortunately, in much the same way as we used the tag above, we can create conditional directives, things which will only come into effect if certain conditions are true. The most useful of these is the "ifModule" condition, which goes something like this..

only if PHP is loaded, will this directive have any effect (switch the 4 for a 5 if using php5)

php_value default_charset utf-8



..which placed in your master .htaccess file, that would set the default character encoding of your entire site to utf-8 (a good idea!), at least, anything output by PHP. If the PHP4** module isn't running on the server, the above .htaccess directive will do exactly nothing; Apache just ignores it. As well as proofing us against knocking the server into 500 mode, this also makes our .htaccess directives that wee bit more portable. Of course, if your syntax is messed-up, no amount of if-module-ing is going to prevent a error of some kind, all the more reason to practice this stuff on a local test server.

** note: if you are using php5, you would obviously instead use .

.htaccess : Groovy things to do with .htaccess..

So far we've only scratched the surface. Aside from authorisation, the humble .htaccess file can be put to all kinds of uses. If you've ever had a look in my public archives you will have noticed that that the directories are fully browsable, just like in the old days before adult web hosts realized how to turn that feature off! A line like this..

bring back the directories!
Options +Indexes +MultiViews +FollowSymlinks


..will almost certainly turn it back on again. And if you have mod_autoindex.c installed on your server (probably, yes), you can get nice fancy indexing, too..

show me those files!

IndexOptions FancyIndexing



..which, as well as being neater, allows users to click the titles and, for instance, order the listing by date, or file size, or whatever. It's all for free too, built-in to the server, we're just switching it on. You can control certain parameters too..

let's go all the way!

IndexOptions FancyIndexing IconHeight=16 IconWidth=16



Other parameters you could add include..

NameWidth=30
DescriptionWidth=30
IconsAreLinks SuppressHTMLPreamble (handy!)


I'm not mentioning the "XHTML" parameter in Apache2, because it still isn't! Anyways, I've chucked one of my old fancy indexing .htaccess file onsite for you to have some fun with. Just add readme.html and away you go! note: these days I use a single header files for all the indexes..

HeaderName /inc/header.html


.. and only drop in local "readme" files. Check out the example, and my public archives for more details.

custom directory index files

While I'm here, it's worth mentioning that .htaccess is where you can specify which files you want to use as your indexes, that is, if a user requests /foo/, Apache will serve up /foo/index.html, or whatever file you specify.

You can also specify multiple files, and Apache will look for each in order, and present the first one it finds. It's generally setup something like..

DirectoryIndex index.html index.php index.htm



It really is worth scouting around the Apache documentation, often you will find controls for things you imagined were uncontrollable, thereby creating new possibilities, better options for your website. My experience of the magic "LAMP" (Linux-Apache-MySQL-PHP) has been.. "If you can imagine that it can be done, it can be done". Swap "Linux" for any decent operating system, the "AMP" part runs on most of them.

Okay, so now we have nice fancy directories, and some of them password protected, if you don't watch out, you're site will get popular, and that means bandwidth..

.htaccess :

These days, using is preferred over , mainly because you can use regular expression in the conditions (very handy), produce clean, more readable code. Here's an example. which I use for my php-generated style sheets..

parse file.css and file.style with the php machine..
# handler for phpsuexec..

SetHandler application/x-httpd-php



Any files with a *.css or *.style extension will now be handled by php, rather than simply served up by Apache. And because you can use regexp, you could do stuff like , which is handy. Any statements you come across can be advantageously replaced by statements. Good to know.

Hide and deny files..

Do you remember I mentioned that any file beginning with .ht is invisible? .."almost every web server in the world is configured to ignore them, by default" and that is, of course, because .ht_anything files generally have server directives and passwords and stuff in them, most servers will have something like this in their main configuration..

Standard setting..

Order allow,deny
Deny from all
Satisfy All



which instructs the server to deny access to any file beginning with .ht, effectively protecting our .htaccess and other files. The "." at the start prevents them being displayed in an index, and the .ht prevents them being accessed. This version..

ignore what you want

Order allow,deny
Deny from all
Satisfy All



tells the server to deny access to *.log files. You can insert multiple file types into each rule, separating them with a pipe "|", and you can insert multiple blocks into your .htaccess file, too. I find it convenient to put all the files starting with a dot into one, and the files with denied extensions into another, something like this..

the whole lot
# deny all .htaccess, .DS_Store $hî†é and ._* (resource fork) files

Order allow,deny
Deny from all
Satisfy All


# deny access to all .log and .comment files

Order allow,deny
Deny from all
Satisfy All



would cover all ._* resource fork files, .DS_Store files (which the Mac Finder creates all over the place) *.log files, *.comment files and of course, our .ht* files. You can add whatever file types you need to protect from direct access. I think it's clear now why the file is called ".htaccess".

htaccess : save bandwidth

If you pay for your bandwidth, this wee line could save you hard cash..

save me hard cash! and help the internet!

php_value zlib.output_compression 16386



All it does is enables PHP's built-in transparent zlib compression. This will half your bandwidth usage in one stroke, more than that, in fact. Of course it only works with data being output by the PHP module, but if you design your pages with this in mind, you can use php echo statements, or better yet, php "includes" for your plain html output and just compress everything! Remember, if you run phpsuexec, you'll need to put php directives in a local php.ini file, not .htaccess. See here for more details.

htaccess rules

If you are looking for the examples of URL rewriting then this post might be useful for you. In this post, I’ve given five useful examples of URL rewriting using .htacess. If you don’t know something about url rewriting then please check my older post about url rewriting using .htaccess.

Now let’s look at the examples

1)Rewriting product.php?id=12 to product-12.html

It is a simple redirection in which .php extension is hidden from the browser’s address bar and dynamic url (containing “?” character) is converted into a static URL.

RewriteEngine on
RewriteRule ^product-([0-9]+)\.html$ product.php?id=$1

2) Rewriting product.php?id=12 to product/ipod-nano/12.html

SEO expert always suggest to display the main keyword in the URL. In the following URL rewriting technique you can display the name of the product in URL.

RewriteEngine on
RewriteRule ^product/([a-zA-Z0-9_-]+)/([0-9]+)\.html$ product.php?id=$2

3) Redirecting non www URL to www URL

If you type yahoo.com in browser it will be redirected to www.yahoo.com. If you want to do same with your website then put the following code to .htaccess file. What is benefit of this kind of redirection?? Please check the post about SEO friendly redirect (301) redirect in php and .htaccess.

RewriteEngine On
RewriteCond %{HTTP_HOST} ^optimaxwebsolutions\.com$
RewriteRule (.*) http://www.optimaxwebsolutions.com/$1 [R=301,L]

4) Rewriting yoursite.com/user.php?username=xyz to yoursite.com/xyz

Have you checked zorpia.com.If you type http://zorpia.com/roshanbh233 in browser you can see my profile over there. If you want to do the same kind of redirection i.e http://yoursite.com/xyz to http://yoursite.com/user.php?username=xyz then you can add the following code to the .htaccess file.

RewriteEngine On
RewriteRule ^([a-zA-Z0-9_-]+)$ user.php?username=$1
RewriteRule ^([a-zA-Z0-9_-]+)/$ user.php?username=$1

5) Redirecting the domain to a new subfolder of inside public_html.

Suppose the you’ve redeveloped your site and all the new development reside inside the “new” folder of inside root folder.Then the new development of the website can be accessed like “test.com/new”. Now moving these files to the root folder can be a hectic process so you can create the following code inside the .htaccess file and place it under the root folder of the website. In result, www.test.com point out to the files inside “new” folder.

RewriteEngine On
RewriteCond %{HTTP_HOST} ^test\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.test\.com$
RewriteCond %{REQUEST_URI} !^/new/
RewriteRule (.*) /new/$1

Popularity: 85% [?]

htaccess Control access,Control access by htaccess

.htaccess is most often used to restrict or deny access to individual files and folders. A typical example would be an "includes" folder. Your site's pages can call these included scripts all they like, but you don't want users accessing these files directly, over the web. In that case you would drop an .htaccess file in the includes folder with content something like this..

NO ENTRY!
# no one gets in here!
deny from all


which would deny ALL direct access to ANY files in that folder. You can be more specific with your conditions, for instance limiting access to a particular IP range, here's a handy top-level rule for a local test server..

NO ENTRY outside of the LAN!
# no nasty crackers in here!
order deny,allow
deny from all
allow from 192.168.0.0/24
# this would do the same thing..
#allow from 192.168.0


Generally these sorts of requests would bounce off your firewall anyway, but on a live server (like my dev mirror sometimes is) they become useful for filtering out undesirable IP blocks, known risks, lots of things. By the way, in case you hadn't spotted; lines beginning with "#" are ignored by Apache; handy for comments.

Sometimes, you will only want to ban one IP, perhaps some persistent robot that doesn't play by the rules..

post user agent every fifth request only. hmmm. ban IP..
# someone else giving the ruskies a bad name..
order allow,deny
deny from 83.222.23.219
allow from all


The usual rules for IP addresses apply, so you can use partial matches, ranges, and so on. Whatever, the user gets a 403 "access denied" error page in their client software (browser, usually), which certainly gets the message across. This is probably fine for most situations, but in part two I'll demonstrate some cooler ways to deny access, as well as how to deny those nasty web suckers, bad referrers, script kiddies and more.