URL Redirects with CGI.pm | 2 | WebReference

URL Redirects with CGI.pm | 2

URL Redirects with CGI.pm

CGI.pm redirect()

Fortunately, we can whip up a short Perl script that will glean this information for us and drop it in the Web log. The CGI module provides a redirect() method which redirects the Web client to a different URL. To the user, it will seem like they're simply visiting an external site. What will really be happening is that the link will actually point to a redirect script; the URL that we want to forward the user to is appended to the URL:

For example, we would use the following HTML link to redirect a user to http://internet.com:

<a href="/cgi-bin/perl/7/redirect.pl?http%3A%2F%2Fwww%2Einternet%2Ecom">internet.com</a>

The string after the ? character in the link is the encoded URL we want to redirect the Web browser to. If you don't encode the forwarding URL, the redirect script probably won't work.

To figure out how to encode a URL, simply read RFC 2396 at http://www.ietf.org/rfc/rfc2396.txt. You can skip the informative reading by using a CGI script I wrote to encode a URL. It's available at http://www.webreference.com/cgi-bin/perl/7/encode.pl.

Once you have your encoded URL, all you need to do is add it to the end of the redirect.pl URL, pre-pended by a ?.

The Code

Well, it's time to examine the source. The script evolved into 50 lines of code including the copyright. Lines 1-10 contain the shebang and copyrights; the GNU copyright that is.

Lines 12-15 load our modules. You'll notice that we're loading the CGI::Carp module on line 14. It writes warnings and errors into your Web server's error log, which makes troubleshooting much easier.

As with any Web application, there's always a potential for abuse. Our two constants (lines 18-23), $restricted and %ok_hosts, are used to limit the hosts that are able to use the script. If $restricted contains a non-null value, it only allows hosts listed in the %ok_hosts hash to use the script.

Now we create a new instance of the CGI module on line 26.

On line 29, we call the &error subroutine if $q->keywords() is empty. The keywords() method returns the contents of $ENV{'QUERY_STRING'} which contains the encoded URL we want to forward the Web browser to.

Then on line 32, we check for a referer URL by testing $q->referer for a value. If a referer URL doesn't exist, it means that someone tried to run the script directly from the URL line in their browser. This can be faked of course by any experience Perl hacker, but hey, it keeps the other 99% from abusing your script. If you don't believe me, type in the following URL in your browser:

http://www.webreference.com/cgi-bin/perl/7/redirect.pl

See? Next, we grab the referer URL on line 35 so we can check if the referer host is in our %ok_hosts hash (Lines 38-39). If it's not, we send the client a nasty error message.

Lastly, we redirect the client to the url specified by $q->keywords on line 42.

The end result is that we have a line in our log file that we can evaluate. It might look something like this:

127.0.0.1 - - [18/Aug/1999:18:42:20 -0400] "GET /cgi-bin/redirect.pl?http%3A%2F%2Fwww%2Einternet%2Ecom HTTP/1.0" 302 0

And in case you're breaking into a cold sweat looking at that encoded URL, the uri_unescape() method in the URL::Encode module will turn it back into http://www.internet.com.


http://www.internet.com

Produced by Jonathan Eisenzopf and
Created: August 18, 1999
Revised: August 18, 1999

URL: http://www.webreference.com/perl/tutorial/7/