Showing posts with label mod_rewrite. Show all posts
Showing posts with label mod_rewrite. Show all posts

Tuesday, January 24, 2012

Htaccess Rewrites – Rewrite Tricks and Tips

SkyHi @ Tuesday, January 24, 2012
Contents
  1. Htaccess rewrites TOC
  2. .htaccess rewrite examples should begin with:
  3. Require the www
  4. Loop Stopping Code
  5. Cache-Friendly File Names
  6. SEO friendly link for non-flash browsers
  7. Removing the Query_String
  8. Sending requests to a php script
  9. Setting the language variable based on Client
  10. Deny Access To Everyone Except PHP fopen
  11. Deny access to anything in a subfolder except php fopen
  12. Require no www
  13. Check for a key in QUERY_STRING
  14. Removes the QUERY_STRING from the URL
  15. Fix for infinite loops
  16. External Redirect .php files to .html files (SEO friendly)
  17. Internal Redirect .php files to .html files (SEO friendly)
  18. block access to files during certain hours of the day
  19. Rewrite underscores to hyphens for SEO URL
  20. Require the www without hardcoding
  21. Require no subdomain
  22. Require no subdomain
  23. Redirecting WordPress Feeds to Feedburner
  24. Only allow GET and PUT Request Methods
  25. Prevent Files image/file hotlinking and bandwidth stealing
  26. Stop browser prefetching
  27. Directives
  28. htaccess Guide Sections
Htaccess Rewrites are enabled by using the Apache module mod_rewrite, which is one of the most powerful Apache modules and features availale. Htaccess Rewrites through mod_rewrite provide the special ability to Rewrite requests internally as well as Redirect request externally.
When the url in your browser's location bar stays the same for a request it is an internal rewrite, when the url changes an external redirection is taking place. This is one of the first, and one of the biggest mental-blocks people have when learning about mod_rewrite... But I have a secret weapon for you to use, a new discovery from years of research that makes learning mod_rewrite drastically quicker and easier. It truly does or I wouldn't be saying so in the introduction of this article.
Despite the tons of examples and docs, mod_rewrite is voodoo. Damned cool voodoo, but still voodoo.
-- Brian Moore
Note: After years of fighting to learn my way through rewriting urls with mod_rewrite, I finally had a breakthrough and found a way to outsmart the difficulty of mod_rewrite that I just couldn't seem to master. The Mod_Rewrite RewriteCond/RewriteRule Variable Value Cheatsheet is the one-of-a-kind tool that changed the game for me and made mod_rewriting no-harder than anything else.
So keep that mod_rewrite reference bookmarked and you will be able to figure out any RewriteRule or RewriteCond, an amazing feat considering it took me a LONG time to figure this stuff out on my own. But that was before the craziness, one of the most challenging and productive .htaccess experiments I've done... An experiment so ILL it's sick like a diamond disease on your wrist! $$$. That mod_rewrite experiment/tutorial was the culmination of many different advanced mod_rewrite experiments I had done in the past and included most of my very best .htaccess tricks. With the cheatsheet it's no longer Voodoo.. Its just what you do. Now lets dig in!

Htaccess rewrites TOC ^


If you really want to take a look, check out the mod_rewrite.c and mod_rewrite.h files.
Be aware that mod_rewrite (RewriteRule, RewriteBase, and RewriteCond) code is executed for each and every HTTP request that accesses a file in or below the directory where the code resides, so it's always good to limit the code to certain circumstances if readily identifiable.
For example, to limit the next 5 RewriteRules to only be applied to .html and .php files, you can use the following code, which tests if the url does not end in .html or .php and if it doesn't, it will skip the next 5 RewriteRules.

RewriteRule !\.(html|php)$ - [S=5]
RewriteRule ^.*-(vf12|vf13|vf5|vf35|vf1|vf10|vf33|vf8).+$ - [S=1]

.htaccess rewrite examples should begin with: ^

Options +FollowSymLinks
 
RewriteEngine On
RewriteBase /

Require the www ^

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

Loop Stopping Code ^

Sometimes your rewrites cause infinite loops, stop it with one of these rewrite code snippets.
RewriteCond %{REQUEST_URI} ^/(stats/|missing\.html|failed_auth\.html|error/).* [NC]
RewriteRule .* - [L]
 
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule .* - [L]

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]

SEO friendly link for non-flash browsers ^

When you use flash on your site and you properly supply a link to download flash that shows up for non-flash aware browsers, it is nice to use a shortcut to keep your code clean and your external links to a minimum. This code allows me to link to site.com/getflash/ for non-flash aware browsers.
RewriteRule ^getflash/?$ http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash [NC,L,R=307]

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]

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]

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]

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

Deny access to anything in a subfolder except php fopen ^

This can be very handy if you want to serve media files or special downloads but only through a php proxy script.
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^/]+)/.*\ HTTP [NC]
RewriteRule .* - [F,L]

Require no www ^

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

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
RewriteRule ^/logged-in/(.*)$ /login.php [L]

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} .
RewriteRule ^login.php /login.php? [L]

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]

External Redirect .php files to .html files (SEO friendly) ^

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

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]

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]

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=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]

Require no subdomain ^

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

Require no subdomain ^

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

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]

Only allow GET and PUT Request Methods ^

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

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]

Stop browser prefetching ^

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]
This module uses a rule-based rewriting engine (based on a regular-expression parser) to rewrite requested URLs on the fly. It supports an unlimited number of rules and an unlimited number of attached rule conditions for each rule, to provide a really flexible and powerful URL manipulation mechanism. The URL manipulations can depend on various tests, of server variables, environment variables, HTTP headers, or time stamps. Even external database lookups in various formats can be used to achieve highly granular URL matching.
This module operates on the full URLs (including the path-info part) both in per-server context (httpd.conf) and per-directory context (.htaccess) and can generate query-string parts on result. The rewritten result can lead to internal sub-processing, external request redirection or even to an internal proxy throughput.
Further details, discussion, and examples, are provided in the detailed mod_rewrite documentation.

Directives ^

If you aren't already comfortable using mod_rewrite then I recommend this excellent mod_rewrite guide by one of my favorite mod_rewrite gurus that I've met.

htaccess Guide Sections ^


REFERENCES
http://www.askapache.com/htaccess/modrewrite-tips-tricks.html

Wednesday, December 28, 2011

A simple way to limit file downloads to only logged in users in WordPress

SkyHi @ Wednesday, December 28, 2011
So, you’ve used WordPress to build your client’s site and to provide downloads for the site’s users. You’re hiding the links to download content based on the user’s logged in status. Great. But what happens when the logged in user copies the download URL and sends it to his friend? Well, unless you’re filtering the download links and checking them with WordPress first his friend gets to download the file.
I’m not a big fan of checking every file download with WordPress as it can take a lot of overhead if you’re running a busy site. So here is a pretty straight forward way to limit downloads from a WordPress site with a minimal amount of code. In this example I’ll illustrate how to prevent non-logged in users from downloading audio files in mp3 and m4a format.

Basic Blocking

First, lets use some ModRewrite rules to get Apache to show users a 403 forbidden page when trying to access the files. This isn’t pretty, it simply gets Apache to dump the user in to a default 403 page and the user is told that their access is forbidden. The .htaccess changes:

# These next two lines will already exist in your .htaccess file
 RewriteEngine On
 RewriteBase /
 # Add these lines right after the preceding two
 RewriteCond %{REQUEST_FILENAME} ^.*(mp3|m4a)$
 RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in.*$ [NC]
 RewriteRule . - [R=403,L]








On the first line of this code you’ll see (mp3|m4a). This is the part that looks at the ending of the file name and determines which files it will act upon. replace the items inside the parentheses with the file types that you want to protect, each one separated by the pipe character. So, for example, if you wanted to protect PDF and RTF files you’d change it to: RewriteCond %{REQUEST_FILENAME} ^.*(pdf|doc)$
That is really all we need but its not very nice to dump the user like that and not inform them of why they were forbidden. They may assume that the site is broken. So lets do this the right way and get the users redirected to a page that will inform them of why they were denied access to the content.

Redirecting the Access Denied

For this we’ll need a page template. You can create anything you’d like, but the basics of it are:


<?php


/**
  * Template Name: 403
  *
  * The template for displaying 403 pages (Forbidden/Not Allowed).
  */
  get_header(); ?>
   <div id="container">
   <div id="content" role="main">
   <div id="post-0" class="post error403 not-allowed">
   <h1 class="entry-title"> <?php _e( "Action Not Allowed", "twentyten" ); ?> </h1>
   <div class="entry-content">
   <p> <?php _e("Apologies, but you are not allowed to download files while not logged in.", "twentyten"; ); ?> </p>
   </div> <!-- .entry-content -->
   </div> <!-- #post-0 -->
   </div> <!-- #content -->
   </div> <!-- #container -->

 <?php get_footer(); ?>




Your template will obviously look a bit different. I did this one as an extension to the new Twenty Ten theme in WordPress 3.0 and based it off of the provided 404 template.
Save the file to your theme’s directory. It doesn’t matter what you name it. WordPress will actually pick up on the Template Name: 403 portion as the template ID.
Next we need to create a page in the WordPress admin for our notification page. Create a new page, name it whatever you want. For my purposes I titled the page “Not Allowed” so my slug ended up as “not-allowed”. You can edit these to be any values you want if the page title created a slug that you don’t like. You’ll need that slug here in the next step. Next select the 403 page template from page templates select input in the Attributes meta box (typically on the right side of the page, underneath the Publish button. Publish the page.
Now let’s alter that .htacess directive to redirect to this page instead of showing that unfriendly Apache notice. The modified directives are:


RewriteCond %{REQUEST_FILENAME} ^.*(mp3|m4a)$
 RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in.*$ [NC]
 RewriteRule . /not-allowed [R,L]





The relevant change happened on the third line where the dash was replaced by the relative url to my 403 page. In my case that is /not-allowed. Yours will differ depending upon how named your page. Don’t forget the leading slash when adding your slug so that it’s a valid relative path. (This can be an absolute path as well, ie: one that contains the full http://domain.com/blah-blah but there’s no need to do that here unless you’ve got valid reason to do so, like if you want to redirect the user to a different domain).
Now, whenever someone who is not logged in tries to download a file type that you’ve specified they’ll be redirected to your 403 page. What you tell them there is up to you.

But…

…now, if you’re theme lists out pages anywhere, you’ve got this 403 page sticking its nose in where it doesn’t belong. Not very pretty, now, is it? This is pretty easily remedied. Head on in to the WP Admin and to the page edit screen for the 403 page. Take note of its page ID in the url. It will be the number after the word “post=” in the url. For example, if your URL looks like http://wp30.local/wp-admin/post.php?post=8&action=edit the post id is 8.
We now need to make an addition to your theme’s functions.php file. This file is located in your theme directory. Open this file and add in the following code:


<?php


// Do error page excludes
 function exclude_error_pages($excludes) {
  array_push($excludes, 8);
  return $excludes;
 }
 // we don't want any funny stuff in the admin, only add to front end
 if (!is_admin()) {
  add_filter('wp_list_pages_excludes', 'exclude_error_pages');
 }
 ?>




On the line that says array_push($excludes, 8); replace the 8 with the id of the page you just created. This will keep the function wp_list_pages() from outputting the 403 page in any of its lists.
Note: if you’ve got other places in your theme that are pulling page lists through different means you’ll want to modify or filter those results as well. Depending upon the methods used to make the lists you can probably exclude the page as a parameter of the call for pages instead of using a filter. Your mileage will vary, but it is certainly doable.

Ta da!

And there you have it. Simple and straight forward. No real frills, though. As it sits now the user is redirected to a page that just tells then simply that they need to be a logged in user. That’s not very informative all by itself. There are a hundred ways to modify this to make it more convenient on the user.
Hopefully this gives you some ideas on what can be done to help legitimate users get to your content while keeping the rif-raff from poaching it.


REFERENCES
http://top-frog.com/2010/07/01/a-simple-way-to-limit-file-downloads-to-only-logged-in-users-in-wordpress/

If not found, redirect to a different URL to check

SkyHi @ Wednesday, December 28, 2011

# Rewrite URLs of the form 'x' to the form 'index.php?q=x'.

##.htaccess
RewriteCond %{REQUEST_FILENAME} !-f
#RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ([^/\.]+)$ http://www.rose1.com/check_url.php?string=$1 [L]


#check_url.php
session_start();
require_once ("functions.php");
$db = new db_mysql();
$file_db = $db->getValue ("SELECT pl_name FROM promo_link");
$file_db2 = $db->getValue ("SELECT sl_name FROM specials_links");


$str = $_SERVER['REQUEST_URI'];
$str_arr = explode ("/", $str);
$file_name = $str_arr[count ($str_arr) - 1];

if ($file_name == $file_db) {
   header ("Location: promotions/booking.php");
   exit;
}


RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

... means that if the file with the specified name in the browser doesn't exist, or the directory in the browser doesn't exist then procede to the rewrite rule below

REFERENCES
http://www.sitepoint.com/forums/showthread.php?259764-What-does-this-mean-RewriteCond-REQUEST_FILENAME-!-f-d
http://www.datakoncepts.com/seo

Monday, September 12, 2011

Apache2: How To Redirect Users To Mobile Or Normal Web Site Based On Device Using mod_rewrite

SkyHi @ Monday, September 12, 2011
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} "!(android|blackberry|googlebot-mobile|iemobile|ipad|iphone|ipod|opera mobile|palmos|webos)" [NC]
RewriteRule ^$ http://www.example.com/ [L,R=302]
</IfModule>


<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} "android|blackberry|googlebot-mobile|iemobile|ipad|iphone|ipod|opera mobile|palmos|webos" [NC]
RewriteRule ^$ http://m.example.com/ [L,R=302]
</IfModule>




REFERENCES
http://www.howtoforge.com/apache2-how-to-redirect-users-to-mobile-or-normal-web-site-based-on-device-using-mod_rewrite

Wednesday, June 29, 2011

Old domain to new domain permanent redirection

SkyHi @ Wednesday, June 29, 2011
Domain name redirection

Why to redirect domain name?

When webhost is changed (moving site), there is no problem to point domain to new server, just changing DNS. When new domain must replace old domain, then could be a problem with search engines. Two domains leading to one site, it means duplicate content, and duplicate content for search engines is not acceptable, both your domains could be penalized or, worse, banned from search engine listing.

To avoid duplicate content penalty, you need to "tell" search engine spider, that your site is moved on new domain, (i.e. you need to use redirect from old domain to new).

Instead of old way with redirection pages, better is to use a permanent (301) redirection.

Simple way to do that is to use htaccess redirection - mod rewrite (apache server)

Case One: old domain to new domain - same hosting account

New domain to replace primary domain? You can't do that. Primary (main) domain is connected with your hosting account, and all add-on and parked (alias) domains are connected with your main domain. If hosting is good, and you want to keep it, you can contact support, they can do that. So, old domain could be parked, and new domain set as primary domain (account moved).

Anyway, if you wish to try, you can set new domain as "main domain", there are two ways:

Using parked domain as main domain

Parked domain (alias) is pointing to root (only if parked on your account), what means, it is the same as main domain. It could be used as "main domain" on your account, if traffic from your old domain is redirected (permanent redirect). It is not problem, but, you still need to keep your old domain, it is connected with your account, and if it is removed (or expired), all other domains (parked, ad-ons) will disappear. So, keep your primary (old) domain in good health.

In this case (alias as main domain), it is not neccessary to move any page from your site, but it is neccessary to remove any instance of old domain from page. If you are using relative linking (without full url), you don't need to change anything. In this example below, we are redirecting our primary (old) domain to new (parked, alias) domain.

#Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.olddomain.com$[OR]
RewriteCond %{HTTP_HOST} ^olddomain.com$
RewriteRule ^(.*)$ http://www.newdomain.com/$1 [R=301,L]

Now, with this setup, every request for olddomain.com/page.html is permanently redirected (301) to newdomain.com/page.html, About htaccess, and how to add this code above, see on bottom.

There is one problem with this setup. If your stats or logs are on olddomain.com/stats/, you need to disable redirection (uploading old htaccess) at that moment. Due to redirection, your stats directory is "moved" to newdomain.com/stats/,and you will get login screen again.

Using Add-on domain as main domain

Difference from parked domain (alias) is that add-on domain is pointed to subdirectory of main (primary) domain, (i.e. addondomain.com is pointing to maindomain.com/addondomain/), while alias is pointing to root. In this case, we need to move (copy) all files to /addondomain/ directory of main domain and add redirection from root to /addondomain/.

Code is the same as above for parked page, just be sure that everything is working on add-on domain before old domain is redirected.

Anyway, you should ask your hosting support is this above possible. You can test redirection to check is it working, but not all servers are the same, so, first ask support.


Case 2 (best): Old domain to new domain - different accounts

This is the best way to change domain name. Set up new account, host new domain on that account, test if everything is working, and add redirection from old domain (account). Keep old domain and account for a few months, or for a year, leaving redirection on place.

When you are sure that new domain is indexed on search engines, and google PR updated for new domain, and there is no links to old domain, and redirected visitors, you can do with old domain and account what you wish.

Sure, htaccess code (directives) is the same as above.

Subdomain to new domain redirection

Say that you have popular site on subdomain, and wish to move to the new domain on other account. Just use code below.

#Options +FollowSymlinks
RewriteEngine On
RewriteCond %{HTTP_HOST} ^yoursite.hosting.com$ [OR]
RewriteCond %{HTTP_HOST} ^www.yoursite.hosting.com$
RewriteRule (.*)$ http://www.yournewdomain.com/$1 [R=301,L]

That code could be used if you have account without domain (your account is connected with subdomain.hostingcompany.com), just add new domain to the same account, and use above redirect.

Non WWW to WWW version redirection

Believe or not, there are still sites you cannot reach without using www in domain name. That is server configuration "problem", but what if you find that your site is indexed with two "domain names", with www.yoursite.com and yoursite.com. For search engines, these are still two different sites with the same content. This happens when your link partners are using version without WWW. Search engine spiders are following those links, and in that case your site is indexed without WWW. Although you can check on YAHOO Site Explorer who is linked to your site and what version of domain name they are using, it is better to add redirection to WWW version. Working example, tested.
Uncomment first line if you have any problem.

#Options +FollowSymlinks
RewriteEngine On
RewriteCond %{http_host} ^yoursite.com
RewriteRule ^(.*) http://www.yoursite.com/$1 [R=301,L]

WWW to NON WWW version redirection

If you prefer non WWW version of domain name, code is below:

#Options +FollowSymlinks
RewriteEngine On
RewriteCond %{http_host} ^www.yoursite.com
RewriteRule ^(.*) http://yoursite.com/$1 [R=301,L]

To test it, just add www. in front of domain name in browser address bar, and you will be redirected to non WWW version.

One version of domain name will boost your Google PR.

Other examples of domain redirection

All pages from old domain to main page (root) of new domain:

redirect 301 / http://www.newdomain.com

More examples soon...

Problems?

Whatever example you wish to use, don't forget two things. Htaccess is a text file, it must be uploaded in ASCII (text) mode, not binary. It will be good to keep it offline with .txt extension, to be sure that will be uploaded in ASCII mode. Don't forget to rename it to .htaccess after upload. Second, always test it.

To avoid any interruption during testing, keep two versions of htaccess, i.e. htaccess_redir.txt and htaccess_original.txt. Upload htacces_redir.txt, rename it to .htaccess, and with opened FTP program, test domain name redirection in browser. If it is not working (server error 500), upload original file back (htaccess_original.txt) or edit and try again.

Use some online header checker (or check in website log) to confirm that server response is 301 (moved permanently). AND, do not promote new domain (if content is the same) before redirection from old domain is on place.

Search engines and 301 redirection - example

In recent experiment (Feb 2007) main domain was redirected to alias domain (same account - IP). That site is small (30 pages), it was easy to track indexing under new domain. So, month later, here is situation:

Google - new domain indexed, old domain deindexed, rank lowered (domain is new) PR 0 (3 before)
Yahoo - new domain indexed, old domain - a few pages left, indexed under both domains, rank lowered
MSN - No sign of new domain, all pages still indexed under old domain, cache shows redirect (document moved here)

What about traffic from search engines? If you are redirecting old domain to new domain, your search engine position will change. Not only due to different domain name (keyword), other factors are involved too. One month is small time frame to get things on place again. When you are sure that pages are indexed under new domain, replace/edit/ask links from other sites.

Update May 2007 : After last Google PR update, new domain has PR 2 , all pages indexed, old domain could not be found. For PR 2, we can talk about good internal linking, not that PR is transferred to new domain. New domain is new domain.
YAHOO: Old domain removed, new domain indexed. Pages are slowly getting positions where they were before, under old domain.
MSN is still waiting for something. New domain still not included in index, and main page (only that page) is still indexed under old domain. According to above, I am not sure how MSN spider is handling with 301 redirection.

Update Jun 2007 : End of experiment, no success. While google has all pages indexed under new domain, Yahoo don't want to listen. Main page and a few others are again indexed under old domain (redirection was on place all the time.). MSN still refuse to index new domain, keeping main page indexed under old domain. Since many links are still pointing to the old domain, now the new domain is redirected back to the old domain. New domain AND new hosting account is still the best solution. This example is from 2007, it exist possibility that, at time when you reading this, things are changed, even then, be carefull.

Moving site from free hosting to new domain

This is not a permanent redirection, here is META tag used to redirect old page to the new page on new domain. So, if you still have an old site hosted on "free" hosting, and want to move that site to new domain, make and upload (different) page with the same name, add redirection META tag with 10 - 15 seconds, add page moved, bla, bla... in body, with link to newdomain.com/samepage.html, and your new site will be indexed fast. Maybe will a problem with duplicate content for the first time, but that will disappear after search engine database update. Old site will remain in index, so you can use it to to get other new site indexed faster, or add some other content there. Google "page moved" or "site moved", and you will see some examples how to do this kind of redirection.

Using this "redirection" new site (domain) was indexed from Google and Yahoo fast, but two months later, domain still could not be found using MSN search (although spidered).
Update: It is fully indexed after three months.

BASE HREF tag and search engines

Base href META tag is useful when you are using relative linking on site (i.e. ../index.html instead of http://domain.com/index.html). When that tag is added to pages on new domain, it helps search engine spiders to determine real website domain.

So, it will not hurt when it is used in combination with domain redirection. Include domain version (with or without www) and page:

<base href="http://www.yourdomain.com/yourpage.html">

For main page (or subdirectory index page) could be added without page name (don't forget slash on the end):

<base href="http://www.yourdomain.com/">

Related:

Add more domains to one hosting account example
Hide affiliate links using htaccess
http://www.affiliatebeginnersguide.com/domains/redirection.html