next up previous contents
Next: The cgiparse approach Up: Form Processing Previous: Form Processing

The DIY Approach

The following example is a script written in the perl language to process the output of our ``Pub Feedback'' form above. It should work on servers implementing CGI and the POST method on Unix systems. This does not use any of the available form parsing programs to make your job easier, so it illustrates what these scripts have to do.gif

#!/usr/local/perl
#Read standard input in to "data"
$data = <STDIN>;

#Split the fields up using "$" as the separator
@fields=split(/\&/, $data);

#Go through each field in turn, storing it and URL decoding it
foreach $pair (0..$#fields)
{
    #Split the field into the name of the field (key) and its value
    ($key, $value)=split(/=/, $fields[$pair]);

    #We want to keep the encoded version of this one for later...
    if ($key eq "pubname") { $encfilename=$value; }

    #URL decode the field's value...
    #First replace pluses with spaces
    $value =~tr/+/ /;
    #Now split the value into sections with each section starting 
    #...with an octal code
    @valuebits = split("%", $value);
    foreach $i (1..$#valuebits)
    {
        $thispart=$valuebits[$i];
        #get the two characters comprising the octal code
        $octal=substr($thispart,0,2);
        #convert them to a decimal number
        $decimal=hex("0x".$octal);
        #and replace the octal characters in this part of the string
        #with the ASCII character they should represent
        $valuebits[$i]=pack("C", $decimal).substr($thispart,2);
    }
    #and finally put the sections of the value back together again
    $value=join("", @valuebits);

    #and store it in an associative array for later...
    $assocarray{$key}=$value;
}

$filename=$assocarray{"pubname"};
$doc_root="/cs/research/www/www/htdocs";
$fullfilename=$doc_root."/misc/uk/london/pubs/auto-".$filename.".html";

#Write the entry to a file in HTML
open(OFILE,">".$fullfilename);
print OFILE "<TITLE>", $assocarray{"pubname"}, "</TITLE>\n";
print OFILE "<H1>", $assocarray{"pubname"}, "</H1><HR>\n";
print OFILE "<I>", $assocarray{"pubaddress"}, "</I><P>\n";
print OFILE "<h2>Area:</h2> ", $assocarray{"area"}, "\n";
print OFILE "<h2>Description:</H2>", 
    $assocarray{"description"}, "\n";
print OFILE "<h2>Grade: ", $assocarray{"grade"}, "</H2>\n";
print OFILE "1=Average, 2=Worth going to, ",
    "3=Worth a detour, 4=Worth a long detour!\n";
print OFILE "<HR><I>Information submitted by ",
    $assocarray{"username"};
print OFILE " (", $assocarray{"useremail"}, ")\n";
close OFILE;

#Send the entry back to the user so they get some feedback
print "Content-Type: text/html\n\n";
open(INFILE, $longfilename);
print <INFILE>;
close INFILE;

#Add a link to our index file so we can get to the new page
$indexfile=$doc_root."/misc/uk/london/pubs/index.html";
open(IXFILE, ">>".$indexfile);
print IXFILE "<P><a href=\"/misc/uk/london/pubs/auto-"
    .$encfilename.".html\">";
print IXFILE $assocarray{"pubname"}, "</A> ", 
    $assocarray{"area"}, "\n";
close IXFILE;

The script first reads the form data from its standard input, which is how the server feeds the body of the POST request to a CGI script.

At this stage the form data looks something like:

    pubname=Northumberland+Arms&pubaddress=Tottenham+Court
    +Road%0ANear+Warren+Street+Tube&area=Bloomsbury&descri
    ption=UCL+CSs+usual+hangout%21%0A&grade=1&username=Mar
    k+Handley&useremail=mhandley@cs.ucl.ac.uk

First we separate the data up into all the original fields by splitting it at the `` &'' characters.

Next we separate each field into the field name and the corresponding field value by splitting it at the `` ='' character (any equals characters in the data itself will have been coded as octal by the client).

Then we URL decode the value of each field. URL encoding is performed by the browser, replacing spaces with pluses and any special characters with a `` %'' follows by the ASCII code of the character in octal. In the server we must reverse this process to obtain the original data.

When we've done all this, we can actually do something with the data - in this case we create a file and write the data to it as HTML, then we send this data back to the user as feedback, and finally we link the new file into our index file so we can refer to it later.



Jon Crowcroft
Wed May 10 11:46:29 BST 1995