March 16, 2007

mod_rewrite

mod_rewrite

Introduction.

Welcome to mod_rewrite, the Swiss Army Knife of URL manipulation! Despite the tons of examples and docs, mod_rewrite is voodoo!

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, for instance server variables, environment variables, HTTP headers, time stamps and even external database lookups in various formats can be used to achieve a really 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 even 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.

This module was invented and originally written in April 1996. [1]

How to change your URLs from dynamic to search engine friendly static URLs using mod_rewrite.

Get an example of the dynamic URL and the way you want it. For example

http://www.domain.com/cgi-bin/store.cgi?section=Nintendo&id=4867635&item=Pokemon
and
http://www.domain.com/store/Nintendo/4867635/Pokemon.html

Now that you got both URLs, make a domain.com/.htaccess file starting with…

Options +Indexes
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
RewriteRule ^

Depending on the server, you might not need the first two lines.

Right after RewriteRule ^ enter the static URL, then a $, a space, and then original URL (with out the domain part for both URLs).

You now got…

Options +Indexes
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
RewriteRule ^store/Nintendo/4867635/Pokemon.html$ cgi-bin/store.cgi?section=Nintendo&id=4867635&item=Pokemon

In the first URL, the static URL code, where ever the URL will change, replace it with a (.*) (Nintendo, 4867635
and Pokemon in the example above).

Then after .html add a $ and add a \ before the .html
If you have a hyphen (-) in the new static URL, add a \ before the hyphen, for example…

RewriteRule ^store\-(.*)\-(.*)\.html$ cgi-bin/store.cgi?section=Nintendo&id=4867635&item=Pokemon

If you don't add the \, you might get an Internal Server Error message, depending on the servers Apache version.

Now in the static part of the URL where the URL changes, in the first change, change it to $1, then $2 and so on. Then add an [L] at the very end, with a space before the [L].

You now got…

Options +Indexes
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
RewriteRule ^store/(.*)/(.*)/(.*)\.html$ cgi-bin/store.cgi?section=$1&id=$2&item=3 [L]

Save the .htaccess file and upload it at domain.com/.htaccess and your static URLs will now work.
http://www.domain.com/store/Nintendo/4867635/Pokemon.html

Here's some other examples…

http://www.domain.com/cgi-bin/store.cgi?section=Nintendo&id=4867635
RewriteRule ^store/(.*)/(.*)\.html$ cgi-bin/store.cgi?section=$1&id=$2 [L]

http://www.domain.com/cgi-bin/store.cgi?section=Nintendo
RewriteRule ^store/(.*)\.html$ cgi-bin/store.cgi?section=$1 [L]

http://www.domain.com/cgi-bin/store.cgi
RewriteRule ^index\.html$ cgi-bin/store.cgi [L]

In this last example domain.com will show the index of the script. If the page shows nothing, try

RewriteRule ^$ cgi-bin/store.cgi [L]

With all the examples combined, you got…

Options +Indexes
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
RewriteRule ^store/(.*)/(.*)/(.*)\.html$ cgi-bin/store.cgi?section=$1&id=$2&item=3 [L]
RewriteRule ^store/(.*)/(.*)\.html$ cgi-bin/store.cgi?section=$1&id=$2 [L]
RewriteRule ^store/(.*)\.html$ cgi-bin/store.cgi?section=$1 [L]
RewriteRule ^index\.html$ cgi-bin/store.cgi [L]

Notice the order. if you list it as…

Options +Indexes
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
RewriteRule ^index\.html$ cgi-bin/store.cgi [L]
RewriteRule ^store/(.*)\.html$ cgi-bin/store.cgi?section=$1 [L]
RewriteRule ^store/(.*)/(.*)\.html$ cgi-bin/store.cgi?section=$1&id=$2 [L]
RewriteRule ^store/(.*)/(.*)/(.*)\.html$ cgi-bin/store.cgi?section=$1&id=$2&item=3 [L]

then mod_rewrite will freak out and it won't work! List the line with the most variables first, then the second most and so on.

Can I have the .htaccess in a directory?

Yes.

In the above example, for having it at domain.com/store/.htaccess, change the code to…

Options +Indexes
Options +FollowSymlinks
RewriteEngine on
RewriteBase /store/
RewriteRule ^index\.html$ /cgi-bin/store.cgi [L]
RewriteRule ^(.*)\.html$ /cgi-bin/store.cgi?section=$1 [L]
RewriteRule ^(.*)/(.*)\.html$ /cgi-bin/store.cgi?section=$1&id=$2 [L]
RewriteRule ^(.*)/(.*)/(.*)\.html$ /cgi-bin/store.cgi?section=$1&id=$2&item=3 [L]

You moved store/ up to the RewriteBase line and added / before cgi-bin. If the script was in /store/store.cgi
you would of had store/ instead of cgi-bin/ and then just got rid of it, to look like…

Options +Indexes
Options +FollowSymlinks
RewriteEngine on
RewriteBase /store/
RewriteRule ^index\.html$ store.cgi [L]
RewriteRule ^(.*)\.html$ store.cgi?section=$1 [L]
RewriteRule ^(.*)/(.*)\.html$ store.cgi?section=$1&id=$2 [L]
RewriteRule ^(.*)/(.*)/(.*)\.html$ store.cgi?section=$1&id=$2&item=3 [L]

The URL to the index of the store will be domain.com/store/

Ack!!! Now it's messing up the rest of my site.

If you have domain.com/index.html for example, make sure your mod_rewrited URLs use another extension, like .htm or .shtml.

The original script URLs don't have the product name in the URL. Can I add the product name to the URL?

Yes! If you can change the script to put the product names in the URL, or edit the links to link to them, yes you can. Here's an example. Notice there are two (.*)'s and no $2.

RewriteRule ^(.*)/(.*)\.html$ cgi-bin/file.cgi?Item=$1 [L]

Just edit the script links, or links in the static page to link to domain.com/whatever/PRODUCT_NAME.html have the product name show up where the last (.*) is in the .htaccess code.

But how can I get rid of special characters or spaces?

For perl, you can do search and replaces, for example…

$value =~ s/ /_/g;
$value =~ s/?//g;
or
$value =~ s/[^\w\d\-_. ]//g;

which gets rid of almost everything but letters and numbers. Just make sure it only changes the URL and not the content. As for php or asp, I don't know how to do it there.

Can I rewrite a sub-domain to a directory?

Yes. Here's the code [url=http://forums.digitalpoint.com/member.php?find=lastposter&t=20416]mnemtsas came up with…

xxxxx.domain.com

to

www.domain.com/XXXXXX/

RewriteCond %{HTTP_HOST} ^[www\.]*xxxxx.domain-name.com [NC]
RewriteCond %{REQUEST_URL} !^/XXXXX/.*
RewriteRule ^(.*) /XXXXX/$1 [L]

Does .htaccess increase server load?

I have yet to ever see it increase server load on my dedicated server. IMO, that's just a rumor. I got about 30 domains with about 54 lines in the domain.com/.htaccess file and have yet to ever see it effect the server. The only effect I've ever got is getting GoogleBombed (Google chomping away at the static URLs so much that the server almost crashes or does crash!!!). Don't panic. This is why you have static URLs, to help search engines crawl your site.

If you ever see high server loads or a slow server, try optimizing Apache.

How do I optimize Apache?

You have to have access to the actual server through telnet as root.

Edit your httpd.conf file.

Here's the best settings I've found.

Timeout 50
KeepAlive On
MaxKeepAliveRequests 120
KeepAliveTimeout 10
MinSpareServers 10
MaxSpareServers 20
StartServers 16
MaxClients 125
MaxRequestsPerChild 5000

and then restart apache. Even when I have massively HIGH server loads, the sites are fast. Once I had the server load above 100, which is EXTREMELY high, and the static pages loaded as if nothing was high!!

Don't ask me how to do it. If you don't know what you're doing, don't mess with it. Ask your web host. Mess up and your sites can 'die' until it get's fixed! For example, simply pressing return can crash your sites until you go back and undo the return, geting it back to how it was before.

How can I do a 301 redirect?

at domain.com/.htaccess

Options +Indexes
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
RewriteRule ^whatever/(.*)$ http://www.domain.com/$1/ [R=301,L]
or
RewriteRule ^index.htm$ http://www.domain.com/ [R=301,L]

The second example only changes one URL.

(.*) and $1 work the same way here as in mod_rewrite, so you can easily change a lot of URLs with one line. The only change with redirects and mod_rewrite is the R=301 (Redirect 301).

Filed under free feed news by javascript codes.
Permalink • Print •  • Comment

Directorycontest-May the best Directory Win!

Mike Dammann has started a directory contest.It is simple you will have to rank first in google for keyword directorycontest.com .

May thhe best directory win.

Onsite optimization is not allowed in contest.

First prize is 2000$.

Visit directorycontest.com for more info!

Filed under free feed news by javascript codes.
Permalink • Print •  • Comment

Validate credit card numbers without submitting and refreshing the entire web page.

Entering a credit card number on a web page has become common place. This hack verifies the entered credit card number, then only submits it to the server component if the number is valid. Nothing else changes on the page except for a user message, which notifies the user of any error conditions or that their credit card has passed muster and has been sent to the server to be processed. The server connection would likely be initiated over Secure Sockets Layer (SSL), such as with the HTTPS protocol, and is involved with an e=commerce component that further verifies the purchase information with a merchant bank. This hack, however, just verifies the number, generates a message, and makes an HTTP request using Ajax techniques.

Figure 3-4 shows what the web page looks like.

 

 

 

 

Enter credit-card number for verification

 

  

This is the web page code. It imports two JavaScript files.

XXXredpre#22XXX

The user chooses a credit card type (e.g., "Mastercard"), enters the card number, expiration date, and Card Security Code, and clicks the XXXredpre#198XXX button. However, instead of having the page dissolve and the values depart immediately for the server, the application verifies a few conditions first. The JavaScript makes sure that the fields are not blank or contain a minimum number of characters (such as three for the Card Security Code), then it verifies the card number using the Luhn formula or algorithm.

NOTE

 

This is a well-known algorithm used to verify ID numbers like credit card numbers.

 

If one of these checks fails, the hack displays a message in red. Figure 3-5 shows one of these messages.

 

 

 

 

Time to re-enter the credit card

 

  

If the credit card number is verified and everything else has been correctly entered, then the hack uses XXXredpre#199XXX to send this information to a server.

We are not strictly making a secure connection in this hack, but a real application would not send any purchase information unencrypted over a network.

A message in blue notifies the user, as in figure 3-6.

 

 

 

 

Purchase information passes muster

 

   

Verifying the Card Number

cc.js contains the code for responding to the user's button click, as well as for verifying the information and generating a user message. http_request.js creates and calls the methods of XXXredpre#200XXX. See Hack #3. Here is the code for cc.js.

XXXredpre#23XXX

There is a lot of functionality to absorb here, so first we will discuss the button click. When the browser completes loading the web page, this event is captured by the code XXXredpre#201XXX. This event handler is a sensible place to set up other event handlers, because the code is assured that the browser has finished loading other HTML tags that might be used by these handlers. Then the code sets up an event handler for when the user submits the form.

XXXredpre#24XXX

The form's XXXredpre#202XXX event handler points to a function that calls XXXredpre#203XXX, then retuns XXXredpre#204XXX, which effectively cancels the browser's form submission. We are using the request object to send the form values, only after verifying that the submissions are valid. Let's look at the XXXredpre#205XXX function.

XXXredpre#25XXX

This function includes a number of common-sense checks before it validates the credit-card number using another function, XXXredpre#206XXX. If the latter function returns XXXredpre#207XXX, then the code builds a URL for the server component, then uses XXXredpre#208XXX to send the card information.

The XXXredpre#209XXX function is responsible for setting up XXXredpre#210XXX and connecting with the server. The function takes four parameters: The type of request (as in XXXredpre#211XXX or XXXredpre#212XXX), the URL, whether or not the request shuld be asynchronous or not, and the name of the function that will handle the response.

NOTE

 

This function name should be passed in without the following parentheses. It can also be a function literal, as in XXXredpre#213XXX.

 

This code appears in the file http_request.js. See Hack #3.

 

Shooting the Luhn

The XXXredpre#214XXX function verifies that the credit-card number is at least 13 characters and does not contain any letters. If the credit card number passes these checks, then the code removes any spaces or dashes from the string and calls a function that uses the Luhn formula.

XXXredpre#26XXX

Here is the code for the XXXredpre#215XXX function.

XXXredpre#27XXX

Information on the Luhn formula or algorithm is easily found on the web, so we will not take up a lot of space describing it here.

NOTE

 

This function takes a XXXredpre#216XXX of numbers, applies the formula to the numbers, and returns the sum to XXXredpre#217XXX. If the total can be evenly divided by 10, then the credit card number is valid. Here is the piece of code from XXXredpre#218XXX that makes this determination.

XXXredpre#28XXX

The server component returns a bit of XML indicating success or failure, mimicking the processing of a purchase order, as in XXXredpre#219XXX. The XXXredpre#220XXX function generates a user message from this return value.

XXXredpre#29XXX

The XXXredpre#221XXX function is responsible for generating a styled user message, in red in the event of an error in handling the purchase information, in blue otherwise. Figure 3-6 shows a user message after the credit card has been verified and handled by the server. However, the entire process takes place back stage, the web page never refreshes, and only small parts of the user interface change as the user interacts with the application.

Filed under ajax tutorials by javascript codes.
Permalink • Print •  • Comment