Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

Where I came from

by isotope (Chaplain)
on May 01, 2001 at 03:02 UTC ( #76802=perlmeditation: print w/replies, xml ) Need Help??

Some years ago, I came up with an idea. I thought it would be really neat to write a CGI script, to place on a dependable server, that would 1) check to see if a particular (non-dependable) site was available, 2) if so, redirect the user there, or 3) display a nice message saying try again later. I was a freshman in college and the only languages I'd ever used were BASIC and LOGO (and my programming classes were scheduled for my sophomore year).

I'd heard about this Perl language that was really popular for writing CGIs, so I lurked around c.l.p.m., and bugged all the CS people I knew, asking them if they had any idea how to do it in Perl. It became clear that nobody else knew anything about it, so I started playing around with it. I downloaded scripts from here and there, noting sections of each that pertained in some slight way to my goal. Eventually, after staring at this code (with no book at my disposal), I started pasting things together.

Here's my first Perl program (BTW, this really sucks, I already know that!):
#!/usr/local/bin/perl -w use Socket; $query = "$ENV{'QUERY_STRING'}"; $pro = "http"; if ($query eq "y") { $hostname = ""; } elsif ($query eq "Skippy") { $hostname = ""; } elsif ($query eq "Winpatch") { $hostname = ""; } elsif ($query eq "Spectral") { $hostname = ""; } elsif ($query eq "Magic") { $hostname = ""; } elsif ($query eq "Skylab") { $hostname = ""; } elsif ($query eq "biff") { $hostname = ""; } else { print "Content-type: text/html\n\n"; print <<"EOF"; <HTML> <HEAD><TITLE>Invalid Option</TITLE> <base href=""></HEAD> <BODY background="skippylogo.gif" BGCOLOR="#DCDCDC" TEXT="#000000" LIN +K="#FF1135 " ALINK="#DCDCDC" VLINK="#5A5A5A"> <H1 ALIGN=CENTER>Invalid Option</H1> <HR> "$query" is not a valid option. <BR><a href="$ENV{'HTTP_REFERER'}">Back</a> <HR> <i><a href="mailto:keys\$query">ke +ys\@babylo</a></i> </BODY> </HTML> EOF $stat = "Invalid"; &end; } $hostaddr = (gethostbyname($hostname))[4] || &fail; $proto = (getprotobyname ('tcp'))[2] || &err ("Protocol Failure"); socket (SOCK, AF_INET, SOCK_STREAM, $proto) || &err ("Socket Failure"); connect (SOCK, pack "SnA4x8", AF_INET, $port || 80, $hostaddr) || &fail; select (SOCK); $| = 1; select (STDOUT); print "Location: $pro://$hostname"; print ":$port" if $port ne ""; print "$ENV{'PATH_INFO'}\n\n"; $stat = "Redirected"; &end; sub fail { print "Content-type: text/html\n\n"; print <<"EOF"; <HTML> <HEAD><TITLE>Service Unavailable</TITLE> <base href=""></HEAD> <BODY background="skippylogo.gif" BGCOLOR="#DCDCDC" TEXT="#000000" LIN +K="#FF1135 " ALINK="#DCDCDC" VLINK="#5A5A5A"> <H1 ALIGN=CENTER>$query is unavailable</H1> <HR>Service for $pro on $query is currently down. Please try again la +ter. <BR><a href="$ENV{'HTTP_REFERER'}">Back</a> <HR> <i><a href="mailto:keys\$query">ke +ys\@babylo</a></i> </BODY> </HTML> EOF $stat = "Unavailable"; &end; } sub err { my ($error) = @_; print "Content-type: text/html\n\n"; print <<"EOF"; <HTML> <HEAD><TITLE>Error</TITLE> <base href=""></HEAD> <BODY background="skippylogo.gif" BGCOLOR="#DCDCDC" TEXT="#000000" LIN +K="#FF1135 " ALINK="#DCDCDC" VLINK="#5A5A5A"> <H1 ALIGN=CENTER>Error</H1> <HR> An error has occurred. With any luck I should already know about it, +though... <BR><a href="$ENV{'HTTP_REFERER'}">Back</a> <HR> <i><a href="mailto:keys\$error">keys\@babylon<!- a></i> </BODY> </HTML> EOF $stat = "Error: $error"; &end; } sub end { chmod (0602, "./hidden/server.cgi.log"); open (FILE, ">> ./hidden/server.cgi.log") || open (FILE, "> ./hidden/server.cgi.log"); print FILE scalar localtime; print FILE ",$ENV{'REMOTE_HOST'},$ENV{'HTTP_REFERER'},$query,$stat\n"; close (FILE); exit(0); }
Now, 5 years later, I'm looking at this code again. I've come a very long way. If I had to do this again, it would take around 30 lines, and would consist mostly of method calls to common modules. All variables would be properly scoped, and I'd use a hash.

I'm already digressing. Looking at this program again reminds me of how difficult it was to get started with Perl, and how much I needed just a little push in the right direction. PM is a tremendous resource, and in the 8 months I've been a regular visitor, I've seen drastic improvements in my ability.

In response to footpad's challenge, here's how I'd write it now. Sorry, it's 48 lines (with whitespace and brackets):
#!/usr/local/bin/perl -wT use strict; use CGI; use LWP::Simple; my %hosts = ( 'skylab' => '', 'tarball' => '', 'google' => '', 'secure' => '', ); my $q = new CGI; my $dest = $q->param('dest') || ''; my $dest_url = $hosts{lc($dest)}; my $message = ''; if(defined($dest_url)) { if(head($dest_url)) { print $q->redirect(-location=>$dest_url); exit(0); } else { $message = "$dest is unavailable"; } } else { if($dest) { $message = "$dest is not a recognized destination"; } else { $message = 'No dest specified'; } } print $q->header(); print $q->start_html(-title=>$message); print $q->h1($message); print $q->h2('Please try again'); print $q->end_html();


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://76802]
Approved by root
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (3)
As of 2021-01-17 03:58 GMT
Find Nodes?
    Voting Booth?