Week 13 - Server Headers, Introduction to Forms & Query Strings

Followups:

Here are the followups to ambiguous points or unanswered questions raised in the previous week of class.

Assigning Arrays to Scalars

First Item: We discussed two ways to get the size of an array by assigning it to a scalar: either @array or $#array. Here is the final word on how this works, presented in the form of this simple program:


#!/usr/bin/perl -w
@array = qw(Phil Dan Andy);
$scalar = @array;
print '$scalar = @array : ', $scalar, "\n";	# prints '3'
$scalar = $#array;
print '$scalar = $#array : ', $scalar, "\n"; # prints '2'

So, as we see, @array will give you the total number of items in the array (or in other words, one past the end--suitable for the condition of a for loop), and the $#array method will get you the index of the last element in the array.

Second Item: I have amended last week's notes to include a third CGI specification. Be sure to check that out if you haven't attended the lectures.

Server Headers (or "Header Field Definitions")

In order for the server to communicate special information to the remote agent (usually a browswer, but occasionally a proxy server), the server sends Server Headers with each page, which are text strings that proceed the opening <HTML> line.

Most of the time, these strings are printed implicitly by the server, but they can also be sent as META tags in HTML pages. In a CGI program, you exercize Olympian powers regarding what strings you can send.

Important Point: Each Server Header string must be followed by a carriage return. Once you are done printing out all the Server Headers, you must put one more carriage return.

A header with only one line would look like this:

Content-type: text/html

<HTML>
<HEAD>
<TITLE> Escorial Treatiste on the Deposition of Rutabegas </TITLE>
.
.

A header with more than one line would look like this:

Content-type: text/html
Pragma: no-cache

<HTML>
<HEAD>
<TITLE> Escorial Treatiste on the Deposition of Rutabegas </TITLE>
.
.

Get it?

You can find a full list of Header Field Definitions on the W3C's Website . The following is a list of the most common Server >Headers:

Instroduction to Forms

The front end to most CGI programs (and the front-end to your assignment #3) is an HTML form. Forms display widgets inside the browser and allow you to enter information.

Example Form

A sample form looks like this:


<FORM ACTION="cgi-bin/myprog.cgi" METHOD="GET">
Name: <INPUT type="text" NAME="username" SIZE=40> <BR>
Email: <INPUT type="text" NAME="email" SIZE=40> <BR>
Password: <INPUT type="password" NAME="password" SIZE=40> <BR>
<INPUT type="hidden" NAME="hiddenfield" VALUE="hiddentext"> <BR>
<INPUT type="submit" VALUE="Submit">
</FORM>

Here's what all that means:

See an example form in action right here .

Other FORM Widgets

For a full listing of the kinds of widgets you can use inside FORM tags, have a look at the HTML FORMs documentation on the W3C Website. We will go over this document in more detail on the next lab night. I highly recommend that you look at this documentation, because it contains a lot of good examples on how to use forms.

For an example of a really big form, look here

Communication Between Forms and CGI programs

Somehow, your HTML form needs to be able to send its information to your CGI program. Here's how it's done:

Query Strings

"Query Strings" are big, mangled-looking strings that get passed to your CGI program from your HTML form either by a GET or a POST method. Another way of putting it is: The way your HTML form communicates with your CGI program is with Query Strings.

An example query string looks like this:

http://osiris/~mark/cgi-bin/myprog.cgi?username=Barney+Fife&email=barney%40mayberry.org&password=secret&hiddenfield=hiddentext

The format goes like this:

  1. The first part might begin with a URL and if so, the whole thing will show up in the URL window on your browser. If this is the case, you are using the GET method (see below).
  2. Key / value pairs are seperated with ampersands ('&').
  3. Individual keys and values are seperated with equal signs ('=').
  4. Spaces are converted to plus signs ('+'), because they are not allowed in a URL.
  5. Any other characters that are either not allowed in a URL or have special meaning are converted to their two-character hexadecimal equivalents and preceeded with a percent ('%') sign.

GET and POST Methods

The following table outlines the subtle differences. We will go over these at greater length in class.

Method Description Pro Con
GET The form variables are sent with the GET request to the Web server and show up in the URL text field in your browser. Handy for doing "canned" queries, letting the user either enter in the CGI variables by hand, or use those variables in a link. The size of the string you can send to the Web server is limited to 256(?) characters.
POST The form variables are sent after the URL request and do not show up in the URL text field in your browser. Handy when you need to send lots of form variables to the CGI program. Susceptible to buffer overflows if you're not careful.

See also: Form Submission Methods on the W3C's Website.

Example Query String Parser

The following hunk of Perl code will handle any kind of query string you care to pass it (using either GET or POST method) and will build a %FORM hash that contains the form variables. You should put this close to the top of your program.


# Determine the request method
if ($ENV{REQUEST_METHOD} eq 'GET') {
	$query = $ENV{QUERY_STRING};
} elsif ($ENV{REQUEST_METHOD} eq 'POST') {
	read(STDIN, $query, $ENV{CONTENT_LENGTH});
} else {
	print "Error: Unrecognized method.\n";
}

# Split up the query string into key/value pairs (i.e. username=Fred)
@pairs = split /&/, $query;

foreach $pair (@pairs) {

	# Split the pair into a key and value
	($key, $value) = split /=/, $pair;

	# Substitute plus signs for whitespace
	$key   =~ tr/+/ /;
	$value =~ tr/+/ /;

	# Substitue hexidecimal characters for their decimal equivalents
	# (The most common substitutions you make are for spaces, slashes,
	# and colons, since these characters either have special meanings
	# or are not allowed in URLs.)
	$key   =~ s/%([\da-fA-F]{2})/pack "C", hex($1)/eg;
	$value =~ s/%([\da-fA-F]{2})/pack "C", hex($1)/eg;

	# Add the key and value to the %FORM hash
	if (exists $FORM{$key}) {
		# If the FORM key already exists,  make a comma delimited
		# list of the values and assign it to that key.
		# (This is the case for menus & checkboxes.)
		$FORM{$key} = join ',', $FORM{$key}, $value;
	} else {
		$FORM{$key} = $value;
	}
}


We will go over the details of how this works in class.


Changelog:

4/8/99 - Initial Revision
4/9/99 - Corrected a few bugs found in class, added the bigform.html link