eekim.com > Publications > CGI Developer's Guide > Chapter 2

Chapter 2: The Basics    (01)

<Next | Table of Contents | Previous>    (02)

Accepting Input From the Browser    (03)

In previous examples, you saw how to write a CGI program that sends information from the server to the browser. In reality, a CGI program that only outputs data does not have many applications (but it does have some; see Chapter 4 for examples). More important is the capability of CGI to receive information from the browser, the feature that gives the Web its interactive nature.    (04)

A CGI program receives two types of information from the browser.    (05)

Environment Variables    (08)

Knowing what environment variables are available for the CGI program can be useful, both as a learning aid and as a debugging tool. Table 2.2 lists some of the available CGI environment variables. You can also write a CGI program that prints the environment variables and their values to the Web browser.    (09)


Table 2.2. Some important CGI environment variables.    (010)

Environment variable Purpose
REMOTE_ADDR The IP address of the client's machine.
REMOTE_HOST The host name of the client's machine.
HTTP_ACCEPT Lists the MIME types of the data the browser knows how to interpret.
HTTP_USER_AGENT Browser information (such as name, version number, operating system, and so on)
REQUEST_METHOD GET or POST.
CONTENT_LENGTH The size of input if it is sent via POST. If there is no input or if the GET method is used, this is undefined.
QUERY_STRING Contains the input information when it's passed using the GET method.
PATH_INFO Enables the user to specify a path from the CGI command line (for example, http://hostname/cgi-bin/programname/path).
PATH_TRANSLATED Translates the relative path in PATH_INFO to the actual path on the system.

In order to write a CGI application that displays the environment variables, you have to know how to do two things:    (011)

You already know how to do the latter. In Perl, the environment variables are stored in the associative array %ENV which is keyed by the environment variable name. Listing 2.3 contains env.cgi, a Perl program that accomplishes our objective.    (014)


Listing 2.3. A Perl program, env.cgi, which outputs all CGI environment variables.    (015)


#!/usr/local/bin/perl
print "Content-type: text/html\n\n";
print "<html> <head>\n";
print "<title>CGI Environment</title>\n";
print "</head>\n";
print "<body>\n";
print "<h1>CGI Environment</h1>\n";
foreach $env_var (keys %ENV) {
   print "<B>$env_var</B> = $ENV{$env_var}<BR>\n";
}
print "</body> </html>\n";    (016)

A similar program can be written in C; the complete code is in Listing 2.4.    (017)


Listing 2.4. env.cgi.c in C    (018)


/* env.cgi.c */
#include <stdio.h>
extern char **environ;
int main()
{
   char **p = environ;
   printf("Content-Type: text/html\r\n\r\n");
   printf("<html> <head>\n");
   printf("<title>CGI Environment</title>\n");
   printf("</head>\n");
   printf("<body>\n");
   printf("<h1>CGI Environment</h1>\n");
   while(*p != NULL)
      printf("%s<br>\n",*p++);
   printf("</body> </html>\n");
}    (019)

GET Versus POST    (020)

What is the difference between the GET and POST methods? GET passes the encoded input string via the environment variable QUERY_STRING whereas POST passes it through stdin. POST is the preferable method, especially for forms with a lot of data, because there is no limit to how much information you can send. On the other hand, you are limited with the GET method by the amount of environment space you have. GET has some utility, however; this is discussed in detail in Chapter 5, "Input."    (021)

In order to determine which method is used, the CGI program checks the environment variable REQUEST_METHOD, which will either be set to GET or POST. If it is set to POST, the length of the encoded information is stored in the environment variable CONTENT_LENGTH.    (022)

Encoded Input    (023)

When the user submits a form, the browser first encodes the information before sending it to the server and subsequently to the CGI application. When you use the <input> tag, every field is given a symbolic name, which can be thought of as the variable. The value entered by the user can be thought of as the value of the variable.    (024)

In order to specify this, the browser uses something called the URL encoding specification, which can be summed up as follows:    (025)

Your final encoded string will look something like the following:    (030)


name1=value1&name2=value2&name3=value3 ...    (031)

NOTE    (032)

The specifications for URL encoding are in RFC1738.    (033)


For example, suppose you had a form that asked for name and age. The HTML used to produce this form is in Listing 2.5.    (034)


Listing 2.5. HTML to produce name and age form.    (035)


<html> <head>
<title>Name and Age</title>
</head>
<body>
<form action="/cgi-bin/nameage.cgi" method=POST>
Enter your name: <input type=text name="name"><p>
Enter your age: <input type=text name="age"><p>
<input type=submit>
</form>
</body> </html>    (036)

Suppose the user enters Joe Schmoe in the name field, and 20 in the age field. The input will be encoded into the input string.    (037)

name=Joe+Schmoe&age=20    (038)

Parsing the Input    (039)

In order for this information to be useful, you need to be able to parse the information into something your CGI programs can use. You learn strategies for parsing the input in Chapter 5. For all practical purposes, you will never have to think about how to parse the input because several people have already written freely available libraries that do the parsing for you. Two such libraries are introduced in this chapter in the following sections: cgi-lib.pl for Perl (written by Steve Brenner) and cgihtml for C (written by me).    (040)

The general idea for most of the libraries written in different languages is to parse the encoded string and place the name and value pairs into a data structure. There is a clear advantage to using a language that has built-in data structures such as Perl; however, most of the libraries for lower-level languages such as C and C++ include data structure implementations and routines.    (041)

Don't worry about understanding every detail of the libraries; what is really important is to learn to use them as tools to make your job as a CGI programmer easier.    (042)

cgi-lib.pl    (043)

Cgi-lib.pl takes advantage of Perl's associative arrays. The function &ReadParse parses the input string and keys each name/value pair by the name. For example, the appropriate lines of Perl necessary to decode the name/age input string just presented would be:    (044)


&ReadParse(*input);    (045)

Now, if you want to see the value entered for "name," you can access the associative array variable $input{"name"}. Similarly, to access the value for "age," you look at the variable $input{"age"}.    (046)

cgihtml    (047)

C does not have any built-in data structures, so cgihtml implements its own linked list for use with its CGI parsing routines. It defines the structure entrytype as follows:    (048)


typedef struct {
   char *name;
   char *value;
} entrytype;    (049)

In order to parse the name/age input string in C using cgihtml, you would use the following:    (050)


llist input;  /* declare linked list called input */
read_cgi_input(&input);  /* parse input and place in linked list */    (051)

To access the information for the age, you could either parse through the list manually, or use the provided cgi_val() function.    (052)


#include <stdlib.h>
#include <string.h>

char *age = malloc(sizeof(char) * strlen(cgi_val(input,"age")) + 1);
strcpy(age,cgi_val(input,"age"));    (053)

The value for "age" is now stored in the string age.    (054)


NOTE    (055)

Instead of using a simple array (like char age[5];), I go through the trouble of dynamically allocating memory space for the string age. Although this makes the programming more complex, it is important for security reasons. See Chapter 9 for more details.    (056)


Chapter 5 goes into more depth for these and other libraries. For now, you're ready to combine your knowledge of input and output to write a full-fledged, yet simple, CGI program.    (057)

<Next | Table of Contents | Previous>    (058)

Copyright © 1997 Sams.Net Publishing    (059)