_CGI AND THE WORLD WIDE WEB_
by G. Dinesh Dutt
Listing One
Listing Two
###############################################################################
## CGI-PARSE.PL ##
## A library to read and parse the input available from forms as per the ##
## CGI 1.1 specification. ##
## This code is in the public domain for people to do whatever they wish to ##
## with it. But, maintain this copyright notice and don't say you wrote it. ##
## This work is distributed in the hope that its useful. But, the author is ##
## not liable for any any incurred damages, directly or indirectly due to ##
## the use or inability to use this software. ##
###############################################################################
###############################################################################
## CGIGetInput ##
## This is a small function which decodes the forms input. It looks at the ##
## REQUEST_METHOD environment variable to decide where to get the input from.##
## The user can invoke this subroutine thus : ##
## &CGIGetInput (*cgi_in); ##
## and the input is returned in an associative array called cgi_in, with the ##
## key being the name of field and its value being the value of the field ##
## as supplied by user. If the field does not have any input, the entry in ##
## the associative array will be undefined. ##
###############################################################################
sub CGIGetInput {
local (*input) = @_;
local ($buffer,@nv_pairs);
if ($ENV{'REQUEST_METHOD'} eq "GET") {
$buffer = $ENV{'QUERY_STRING'};
}
elsif ($ENV{'REQUEST_METHOD'} eq "POST") {
read (STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
}
else {
return -1;
}
@nv_pairs = split (/\&/,$buffer);
foreach $nvp (0..$#nv_pairs) {
$nv_pairs[$nvp] =~ tr/+/ /;
($key, $keyword) = split (/=/, $nv_pairs[$nvp], 2);
$key =~ s#%(..)#pack("c",hex($1))#ge;
$keyword =~ s#%(..)#pack("c",hex($1))#ge;
$input{$key} .= '\0' if (defined ($input{$key}));
$input{$key} .= $keyword;
}
return 1;
}
###############################################################################
## &PrintHeader (type/URL, is_it_a_URL) ##
## This function prints the default header. If a type is specified, that is ##
## printed, else the default text/html is printed. If the second parameter is##
## 1, then the Location header is printed instead of the text/html header. ##
## ##
## Example invocations : ##
## &PrintHeader ("text/plain", 0) ##
## &PrintHeader ("http://www.halcyon.com/hedlund/cgi-faq/",1) ##
## &PrintHeader ("",0) ##
###############################################################################
sub PrintHeader {
local ($toprint, $url_p) = @_;
if ($toprint eq "") {
print "Content-type: text/html\n\n";
}
elsif ($url_p) {
print "Location: $toprint\n\n";
}
else {
print "Content-type: $toprint\n\n";
}
}
1;
Listing Three
###############################################################################
## DEBUGCGI.PL ##
## This is a simple script which sets up a test environment for CGI script ##
## to be executed and then traps the common errors. The PATH is set to the ##
## minimal set by most systems, for example. All error messages are trapped ##
## and made available to the user. ##
## ##
## This code is in the public domain for people to do whatever they wish to ##
## with it. But, maintain this copyright notice and don't say you wrote it. ##
## This work is distributed in the hope that its useful. But, the author is ##
## not liable for any any incurred damages, directly or indirectly due to ##
## the use or inability to use this software. ##
###############################################################################
$tmpdir = "/tmp/"; # The directory under which the error file will
# be created.
require "cgi-parse.pl";
%cgi_input = ();
&CGIGetInput(*cgi_input);
$script = $cgi_input{'DebugCgi-ScriptName'};
$method = $cgi_input{'DebugCgi-Method'};
$cmdargs = $cgi_input {'DebugCgi-CmdArgs'};
delete ($cgi_input {'DebugCgi-ScriptName'});
delete ($cgi_input {'DebugCgi-Method'});
delete ($cgi_input {'DebugCgi-CmdArgs'});
$inp = "";
foreach $elem (keys %cgi_input) {
$cgi_input{$elem} = $cgi_input{$elem};
$cgi_input{$elem} =~ s# #+#g;
$cgi_input{$elem} =~ s#([^+A-Za-z0-9])#sprintf("%%%02x",ord($1))#ge;
$cgi_input{$elem} =~ s#%3d#=#g;
$inp .= "$elem=$cgi_input{$elem}&";
}
# Encode the input in the form used by HTTP.
#Turn off the include path. The script must use its own @INC and environment.
if (! -e $script) {
&PrintErrHeader;
print "Script $script does not exist
";
&PrintErrTrailer;
exit (2);
}
if (! -r $script && ! -x $script) {
&PrintErrHeader;
print "Script $script is not readable/executable by
server
";
&PrintErrTrailer;
exit (2);
}
#Set the request method.
$error_file = $tmpdir.$^T;
$ENV{'REQUEST_METHOD'} = $method;
if ($method eq "GET") {
$ENV{'QUERY_STRING'} = $inp;
open (OUTPUT, "$script $cmdargs 2\>/tmp/errors |") ||
&cry ("unable to pipe script $! \n");
}
elsif ($method eq "POST") {
$ENV{'CONTENT_LENGTH'} = length($inp);
open (OUTPUT, "echo \"$inp\" | $script $cmdargs 2>$error_file |") ||
&cry ("unable to pipe script $! \n");
}
else {
&PrintHeader;
print "Unknown method: $method\n";
exit (3);
}
$_ =