Thursday, 19. March 2009, 20:24:41
I've started delving into Perl today. Well, I spent a good share of the day to simply figure out how the heck
mod_perl was supposed to work, but after some advice from
nicomen, things started rolling, and soon I started digging myself down through the book and, hopefully, the understanding.
My first real WTF about Perl, when using it to improve and dynamicalize web pages, was that I didn't have any way of getting POST and GET (or rather, when the user submits a form with either
POST or GET as the method) in the Perl script, as I for instance have in PHP (where I can use the arrays $_POST and $_GET).
Acknowledging this, I found a that I had to read the data from Perl's STDIN, and I found a heavy piece of script that did about this. "Heck, do I have to do this everytime I want some data?", I thought, and started digging through the code.
After fiddling with it at the end of work today, I finally got something working:
sub getPost
{
my %_POST, $r, @parts;
%_POST = ();
read( STDIN, $r, $ENV{ "CONTENT_LENGTH" } );
@parts = split( /\&/, $r);
foreach my $p (@parts)
{
my($n, $v) = split( /\=/, $p);
$v = uri_decode($v);
$_POST{ "$n" } = $v;
}
return %_POST;
}
What this code does, is basically that it reads the string submitted by the form (which is of the form
a=something&b=somethingelse&c=somethingelseagain). It then splits the string on "&" and then stuffs the entries splitted into an array
@parts and iterates through the array of elements that looks like
a=something and splits each string on "=" and puts it into the hash %_POST. An example of how it would look with my initial string example would be:
$_POST{"a"} = "something"
$_POST{"b"} = "somethingelse"
$_POST{"c"} = "somethingelseagain"
One question that might arise: What happens if the string contains "=" or "&" or other special characters? It's quite simple really; when submitting the initial form, everything's uri encoded. For instance, "=" will be shown as "%3D".
I then tried to make another script call my initial Perl module (cuddingly named HTTPerl for a poor pun and no laugh), which didn't prove to be an easy task. HTTPerl.pm, the file name of the module, must, apparently, be in one of the folders of Perl's include folders (@INC). However, getting the current folder added to there was no simple task, and I still do not know how I can do that. Apparently, most that asked on other forums stated "Hah, no, you can't", or failed miserably trying to get it working as a workaround.
In either way, I made a test script for today's work, and it's accessible from
http://shael.ath.cx/test.html. Below is the entire script in its "glory". I have not included the test.html file since it is merely a form. NB! There's a bug going on for some reason; half of the time the script won't load, giving an "Server Misconfiguration Error", while the other half it runs perfectly. I am puzzled by this, as the log file says that Perl exited with this error:
[Thu Mar 19 21:01:06 2009] [error] "getPost" is not exported by the HTTPerl module\nCan't continue after import errors at /home/robert/public_html/perl/skript.pl line 2\nBEGIN failed--compilation aborted at /home/robert/public_html/perl/skript.pl line 2.\n Any ideas to why it is like this? I am empty of ideas.
HTTPerl.pm
#!/usr/bin/perl
package HTTPerl;
use base 'Exporter';
our sub getPost
{
my %_POST, $r, @parts;
%_POST = ();
read( STDIN, $r, $ENV{ "CONTENT_LENGTH" } );
@parts = split( /\&/, $r);
foreach my $p (@parts)
{
my($n, $v) = split( /\=/, $p);
$v = uri_decode($v);
$_POST{ "$n" } = $v;
}
return %_POST;
}
our @EXPORT_OK = ('getPost');
our @EXPORT = {'getPost');
1;
Skript.pl
#!/usr/bin/perl -I .
use HTTPerl 'getPost';
%_POST = getPost();
print "content-type: text/html\n\n";
print "<html><head><title>Testing the script</title></head>";
print "<style type=\"text/css\">* { font-family: Verdana; font-size: 10px; } h1 { font-size: 16px; }</style>";
print "<body><h1>Using the information</h1>";
printf("<p>Hello %s!<br />You're %d years old and you just said: '%s'.</p>", $_POST{"name"}, $_POST{"age"}, $_POST{"text"});
print "</body></html>";