CGI: Common Gateway Interface Using CGI.pm


Common Gateway Interface (CGI) define the interface between the web server and an external gateway application (called CGI application).

Perl as CGI language of choice is further enhanced by the CGI.pm module created by Lincoln Stein.

REQUEST_METHOD: GET vs. POST
POST Method:
For the following web page,
Registration Form
<form action="http://blanca.uccs.edu/~cs301/cgi-bin/fullecho.cgi" method="post"><br>
First Name: <input type="text" name="firstName" value="Edward"><br>
Last Name: <input type="text" name="lastName" value="Chow Chow"><br>
Email: <input type="text" name="email" value="chow@cs.uccs.edu"><br>
Phone: <input type="text" name="phone" value="(719)262-3110"><br>
Password: <input type="password" name="passwd" value="sogood"><br>
<input type="submit" value="submit">
</form>
and user hits submit button.

The following http request will be sent by the browser:

POST /~cs301/cgi-bin/fullecho.cgi HTTP/1.1
Accept: */*
Referer: http://cs.uccs.edu/~cs301/reg8888.html
Accept-Language: en-us
Content-Type: application/x-www-form-urlencoded
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; InfoPath.1)
Host: blanca.uccs.edu:8888
Content-Length: 96
Connection: Keep-Alive
Cache-Control: no-cache

firstName=Edward&lastName=Chow+Chow&email=chow@cs.uccs.edu&phone=%28719%29262-3110&passwd=sogood

Note that space character between chow and chow is replaced with + as www-urlencode rule; ( is encoded as %28; ) is encoded as %29 hexa decimal representation.

The fullcecho.cgi  uses the following code to retrieve the input values of the form web page.

#!/usr/bin/perl

use CGI qw(:standard);
print header(); # header() generate the content type meta header for
# the return web page
print <<ENDTITLE;
<HTML>
<BODY BGColor=\"#bbffbb\" TEXT=\"#2222222\">
<H2>This is the name value pairs you entered in the form.<P>
<HR>
ENDTITLE

@names=param;
foreach $key (@names)
{
$name = $key;
$value = param($key);
print "name=$key, value=$value<br>";
}

print "</H2></BODY></HTML>\n";

GET Method:

For the following web page
Registration Form
<form action="http://blanca.uccs.edu/~cs301/cgi-bin/fullecho.cgi"
method="get"><br>
First Name: <input type="text" name="firstName" value="Edward"><br>
Last Name: <input type="text" name="lastName" value="Chow Chow"><br>
Email: <input type="text" name="email" value="chow@cs.uccs.edu"><br>
Phone: <input type="text" name="phone" value="(719)262-3110"><br>
Password: <input type="password" name="passwd" value="sogood"><br>
<input type="submit" value="submit">
</form>
and user hits submit button.

The following http request will be sent by the browser:

GET /~cs301/cgi-bin/fullecho.cgi?firstName=Edward&lastName=Chow+Chow&email=chow@cs.uccs.edu&phone=%28719%29262-3110&passwd=sogood HTTP/1.1
Accept: */*
Referer: http://cs.uccs.edu/~cs301/reg8888get.html
Accept-Language: en-us
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; InfoPath.1)
Host: blanca.uccs.edu:8888
Connection: Keep-Alive

Note that There is no data in the body of the http request. All form data are concatenated as the first parameter of GET command. That is also the reason why space characters needs to be replaced with +.

The web server parse the uri, forks a process to execute fullechol.pl and pass the uri after ? through the environment variable QUERY_STRING.
There are limitation on how many bytes can be carried over an environment variable. If the data exceed certain length, the web server will complain that
"Your browser sent a non-HTTP compliant message."  See the example http://owl.uccs.edu/~cs301/envLimit.html.

Bonus exercise: What is the number of characters allowed?

To get the above post and get responses, you can run "~cs301/bin/ws4 8888" command on blanca using SSH Secure Shell, and hit submit button on http://cs.uccs.edu/~cs301/reg8888.html and http://cs.uccs.edu/~cs301/reg8888get.html respectively. After the screen shows the http request, you can enter a msg and '$'. If the connection does not termiante. Hit control-C to terminate the process. You may have to wait a minute before the zombie ws4 process release the port number 8888 assigned to it.

Important environment/HTTP session variables (Can be accessed through%ENV associative array. See example in http://blanca.uccs.edu/~cs301/cgi-bin/sessionvar.cgi.)

SERVER_SOFTWARE=Netscape-Communications/1.1
GATEWAY_INTERFACE=CGI/1.1
HTTP_ACCEPT_LANGUAGE=it,en
SCRIPT_NAME=/cgi-bin/cs301/sessionvar.pl
HTTP_ACCEPT_ENCODING=gzip
REMOTE_ADDR=165.212.199.97
SERVER_NAME=owl.uccs.edu
SERVER_PROTOCOL=HTTP/1.0
HTTP_ACCEPT_CHARSET=iso-8859-1,*,utf-8
REQUEST_METHOD=GET
REMOTE_HOST=port33.cos1-pm3.iex.net
SERVER_URL=http://owl.uccs.edu
SERVER_PORT=80
HTTP_USER_AGENT=Mozilla/4.06 [en] (Win95; I)
HTTP_HOST=owl.uccs.edu
PATH=/sbin:/etc:/usr/sbin
HTTP_ACCEPT=image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*
HTTP_CONNECTION=Keep-Alive

Note that the REMOTE_ADDR and REMOTE_HOST can be used to restrict access.
The HTTP_USER_AGENT, HTTP_ACCEPT, SERVER_PROTOCOL can be used to customize the response from the CGI applications.