CGI III

Environment Variables

#!/usr/local/bin/perl

use CGI qw(:standard);
print header();
print "<html><head><title> Environment Variables </title></head><body>";
print "<h3>Environment variables script</h3>";
print "<p> Here are the environment variables that this CGI script has been called with<p><hr>";
print "
<pre>
SERVER_SOFTWARE = $ENV{'SERVER_SOFTWARE'}
SERVER_NAME = $ENV{'SERVER_NAME'}
GATEWAY_INTERFACE = $ENV{'GATEWAY_INTERFACE'}
SERVER_PROTOCOL = $ENV{'SERVER_PROTOCOL'}
SERVER_PORT = $ENV{'SERVER_PORT'}
REQUEST_METHOD = $ENV{'REQUEST_METHOD'}
HTTP_ACCEPT = '$ENV{'HTTP_ACCEPT'}'
PATH_INFO = $ENV{'PATH_INFO'}
PATH_TRANSLATED = $ENV{'PATH_TRANSLATED'}
SCRIPT_NAME = $ENV{'SCRIPT_NAME'}
QUERY_STRING = $ENV{'QUERY_STRING'}
REMOTE_HOST = $ENV{'REMOTE_HOST'}
REMOTE_ADDR = $ENV{'REMOTE_ADDR'}
REMOTE_USER = $ENV{'REMOTE_USER'}
CONTENT_TYPE = $ENV{'CONTENT_TYPE'}
CONTENT_LENGTH = $ENV{'CONTENT_LENGTH'}
DOCUMENT_ROOT= $ENV{'DOCUMENT_ROOT'}
HTTP_USER_AGENT =$ENV{'HTTP_USER_AGENT'}
HTTP_REFERER =$ENV{'HTTP_REFERER'}
</pre>";
print "<hr></body></html>";

Exercise

1) You can also print all environment variables using the following code (try it).
foreach $elem (keys %ENV) {
print "$elem $ENV{$elem}<br>";
}

2) Use one of the CGI scripts that you have created earlier in this semester. Include a print statement in the CGI script that prints the environment variables REQUEST_METHOD, QUERY_STRING and CONTENT_LENGTH. Note: that some of these are only available if the method for sending the form is "get", others are only available if the method is "post". (Check the
<form action=... method=... > tag in your form.) REQUEST_METHOD and CONTENT_LENGTH can be used to increase the security of your script. CONTENT_LENGTH should not be longer than a predefined maximum length.

Maintaining State

If one form invokes another form, it is often the case that information from the first form must be send to the second form. This is part of "maintaining state", i.e. maintaining accurate information between different CGI scripts invoked by one user. There are three possibilities to maintain state:
a) send hidden text,
b) write information to a file (on the server),
c) set cookies (on the client).

Hidden text

Exercise:

3) Create a form that asks a user for his/her name and some comments. Then create two CGI scripts that create a response. The first script displays the information which the user has submitted ("Hello $name. These are your comments: $comments") and asks the user whether he/she really wants to submit the information. The second script is invoked by the first one and displays "Thank you $name. Your comments have been submitted: $comments".

To implement this add a form and hidden tags to the first CGI script, such as

<input type='hidden' name='hiddenname' value=\"$name\">
<input type='hidden' name='hiddencomments' value=\"$comments\">

The second CGI script retrieves these strings via

my $name = param('hiddenname');
my $comments = param('hiddencomments');

Cookies

Exercise

4) Use a cookie instead of hidden text in the previous exercise.

The following code in the first CGI script sets a cookie.

$cookiedata = $name."|".$comments;
$cookie = cookie(-name=>'nameandcomments',-value=>"$cookiedata", -expires=>'+1h');
print header(-cookie=>$cookie);

The second CGI script retrieves the cookie similarly to retrieving parameters:

$cookiedata = cookie(-name=>'nameandcomments');
($name, $comments) = split(/\|/,$cookiedata);

Writing to a file

Exercise (optional):

5) Instead of using hidden tags, save the information to a file.

There are several problems involved with saving to a file because several users can look at the CGI script at the same time. To keep track of which user wrote which comments, write user name and comments to the file; send the user name as hidden text and use the name to retrieve the correct comments from the file.

A file that is written to should be locked to prevent the file from getting corrupted.

flock(FILEHANDLE,2) || die("cannot flock $!");

Exercise:

6) A hit counter: create a file that contains only the number "0". Your CGI script must open that file for reading; read the first line of the file into a scalar variable; increase the number by one; close the file; open the file again for writing (not appending); write the number to the file; close the file.