Chapter Outline
Internet Programming 2: CGI
FORM Elements
The FORM Tag
A Sample Page
The INPUT Tag
The SELECT Tag
The TEXTAREA Tag
Sending Information to the WWW ServerInformation Encoding
Returning HTML to the Client
Server Program
Writing a Server-side CGI Program
CGI Programs Using Extended URLs
Decoding the Form Data
Using Perl as a Back End to the CGI
Tips and TricksMaking Sure Your CGI Program Exits
An Application
Redirecting the Client
Dynamic Graphics
Hiding Context Information
SummaryLecture Notes
Internet Programming 2: CGI
We'll learn how to allow the viewer to send information back to the server. The server is programmed to act dynamically on this information.
The interface specification that defines how information can be passed from the browsers back to the server is called the Common Gateway Interface, (CGI).
![]()
FORM Elements
We can set up fields that allow user input using the <FORM> tag.
The <FORM> tag and its embedded tags, the form elements, have the following syntax:
![]()
The FORM Tag
The <FORM> tag starts an HTML form. IT takes three attributes:
![]()
The INPUT Tag
The <INPUT> tag defines input types. The appearance and behavior of the input is controlled with TYPE attribute.
TEXT
When the TYPE attribute takes the value TEXT, the browser display a single line box into which we can enter text.
Here's a fragment of HTML, illustrating the TEXT style of input:
![]()
PASSWORD
The PASSWORD value is the sams as the TEXT value, excepts that the contents of the field can't be seen in the browser.
Here's a fragment of HTML, illustrating the PASSWORD type:
![]()
HIDDEN
Setting TYPE=HIDDNE results in a text field that the usr doesn't see on the browser screen and can't enter information into. It is used by server programs.
HEre's a fragment of HTML, illustrating a HIDDEN field:
![]()
CHECKBOX
The CHECKBOX allows the user to select several of a number of options. Checkbox fields are grouped by specifying several of them wiht the same NAME attribute.
Here's a fragment of HTML, illustrating the CHECKBOX type of field.
![]()
RADIO
The RADIO is similar to the CHECKBOX type, except that only one option may be chosen and marked CHECKED.
Here's a fragment of HTML, illustrating the RADIO type of field.
![]()
IMAGE
The IMAGE type allows the selection of an (x,y) coordinates from an image.
SUBMIT
The SUBMIT type cause a button to be displayed by the browser. When this button is selected, the contents of the form are sent back to the server for processing.
HEre's an example:
![]()
RESET
TYPE=RESET also causes a button to be displayed by the browser. When this button is selected, the form elements are reset to the values displayed when the form was first loaded.
![]()
The SELECT Tag
The <SELECT> tag allows the user to select from a list o9f values. It has the attributes NAME, MULTIPLE and SIZE.
An example of the SELECT tag is:
![]()
The TEXTAREA Tag
The <TEXTAREA> tag allows multiple input lines to be entered and returned to the server.
Here's an xample of <TEXTAREA>
![]()
A Sample Page
Now we are going to make a sample page using the above features.
Try It Out -A Simple Query Form
1. Start with basic HTML template, like the one below, and save it as cgi1.html.
![]()
2. Now for the FORM element which fills the rest of the page. It goes before the /BODY tag. It starts with TEXT and PASSWD type elements:
![]()
3. For all the different parts of the world the customer might want to visit, we provide a series of checkboxes:
![]()
4. You can copy and modify the last section to use radio buttons to find out the customer's home continent:
![]()
5. Now we use the <SELECT> tags for finding out the user's modem speed:
![]()
6. Use the TEXTAREA input type for the customer's address:
![]()
7. Lastly, the Submit and Rest buttons and the closing <FORM> tag:
![]()
Having typedall this in, you should see the following output:
![]()
How It Works
We created a form which the user can enter information into and submit it to the server.
Sending Information to the WWW Server
When the Submit butten is selected, the browser encodes all the information in the form and sends it to the server using HTTP protocol.
The server uses a GCI program to process the information.
Information encoding
When the data in a form is prepared for transmission to a server, a sequence of transformtions is applied to encode the data.
Server Program
We now need to look at the programs on the server. These are normally stored in a subdirectory of the main HTTP server, called cgi-bin.
The program to be invoked is specified by the ACTION attribute of the <FORM> tag, like this:
![]()
Security
When you allow people to send form information to your server, you're allowing them to specify some arbitrary data and pass it to a program on the server.
For starters, here are some security tips on things to avoid:
![]()
Writing a Server-side CGI Program
CGI programs can be written in many languages including: C, shell scripts, Tcl, and Perl.
METHOD=GET passes information to the CGI program on the command line. METHOD=POST passes information to th CGI program from the standard input.
![]()
Environment Variables
Several important pieces of information are passed to the CGI program as environment variables. The standard variables are:
![]()
The Apache server, and many others, also provide:
![]()
Putting it all Together
How do we return information to the client?
For now, it's enough to know that writing Content-type:text/plain and a blank line followed by the text you wish to display is sifficient for the browser to display simple text on the screen.
Try It Out - Our First CGI Program
We'll use a shell program for this example, because that's the easiest method for the processing we need at this stage.
1. We're going to write cgi1.sh, so we'll comment that into the header:
![]()
2. We start the output to the browser with the two lines that we were given above:
![]()
3. Next, we want to display the arguments:
![]()
4. We show the environment variables under the CGI requrest was made, the meat of this first program:
![]()
5. We change our HTML example page (call itcgi2.html) so that the request references our shell script.
To do this, we just need to change the ACTION attribute, right after the HTML header:
![]()
6. We must access these scripts via our WWW server in order for the CGI program to invoked them correctly. The cgi1.sh should be in the cgi-bin subdirectory.
We can now accews our form via the server. When we press the Submit button on the form, this is what we see:
![]()
How It Works
When we press the Submit button, the data is sent to the server, which uses cgi1.sh to return the data to the browser.
Try It Out - Reading the Data
Save a copy of cgi1.sh as cgi2.sh. Add the following code to the end of the cgi2.sh script.
![]()
We also change the ACTION attribute of our HTML form (call it cgi3.html) to reference the new CGI program, cgi2.sh.
Here is the new output:
![]()
How It Works
We now read the entire standard input stream and return it to the browser.
![]()
There are two important things to notice in the information the CGI program received:
![]()
Try It Out -Using the GET Method
To complete our look at HTML forms, change the METHOD type to GET in our HTML sample, now cgi4.html.
Now the information is passed in a slightly different way, so we see:
![]()
CGI Programs Using Extended URLs
The remaining way to send data to a CGi program is to append it to a URL. The data comes after the ?.
Try It Out - A Query String
Invoke cgi2.sh again, this time using the URL:
http://locathost/cgi-bin/cgi2.sh?Andrew+Stones=6
Now the CGI program sees:![]()
Decoding the Form Data
We're going to decode the data using our own program. Let's call our first attempt decode1.c.
Try It Out - A CGI Decode Program in C
1. After adding the standard headers and a couple of constants, we define a data structure.
![]()
2. The main function calls get_input, loading th name_val_pairs structure, and sends decoding information back to the client.
![]()
3. We define a function get_input that does just what it says.
![]()
4. We need to extract the NAME and VALUE components of the HTML submission and decode them individually.
![]()
5. We pass all errors to a function called send_error, which sends an error string back to the client.
![]()
6. The actual decpding is handled by the function load_nv_pair, which we called in get_input
![]()
7. The function unescape_url then decodes the special characters in the text from the %HH representation by running through the array and calling the function x2c:
![]()
We compile this program, copy it into the cgi-bin directory and change our HTML form so the FORM ACTION is now /cgi-bin/decode1 and the METHOD=POST. This is now cgi5.html.
Here is the form information that we submit:
![]()
After submitting the form, we see:
![]()
How It Works
We call the routine get_input to load the name_val_pairs array. We process the input and simply print out the pairs.
Using Perl as a Back End to the CGI
Now let's see what the CGI script would look like using Perl.
Try It Out - A CGI Script Using Perl
Here's our Perl script. Call it decode2.pl:
![]()
How It Works
If you're comfortable with the UNIX shell and regular expressions, some of this will look familar.
![]()
Let's look at hte code:
![]()
This tells the UNIX system to use /usr/bin/perl to execute this script.
![]()
This simply prints out the header we need to tell the browser we are sending it plain text.
![]()
This is where some Perl magic starts:
![]()
So, this line finds how many bytes of data to expect, creates a variable in which to store the data and reads the appropriate number of bytes into the variable.
![]()
This line creates a new variable name_values.
![]()
This is a loop that runs through each member of the array @name_values and assigns each member in turn to the new variable $name_value_pair.
![]()
This succinct line of code creates two new variables, $name and $value, from the split of the variable $name_value_pair.
![]()
This line of code translates + characters iin the value variable and assigns it back to the variable.
![]()
This decodes the %XX escapes into normal characters by substituting the %XX with the result of the pack command called on the two hex characters.
![]()
Finally, we print out the variables.
Perl is popular for writing CGI programs because of its brevity.
![]()
Returning HTML to the Client
We'll now look at generating HTML, so that the CGI program's output looks more like a normal Web page.
We could simply write code like this,
![]()
The function html_content sends a string to the client to let it know that we'll be sending HTML to it:
![]()
html_start then starts the HTML header section, sends a title string and starts the HTML body section:
![]()
We can use two more functions, html_header and html_text, simply as a convenient utility routines to print header and ordinary body text.
![]()
Finally, html_end terminates the HTML.
![]()
A minimal CGI program could then consist of these routines; something as simple as:
![]()
Try It Out - Returning HTML to the client
1. Add the following function prototypes that we've just placed at the end.
![]()
2. Most changes happen in the main function.
![]()
3. The only other function that we need to change is send_error, the output from which must now also be in HTML format:
![]()
After the changes, here is the new output.
![]()
Tips and Tricks
Here are a few hints and tips that you may find useful in writing your own CGI programs.
Making Sure Your CGI Program Exits
We can trap the SIGALRM signal and call alarm to generate a signal in 30 seconds so that we can terminate even if the network goes down.
Redirecting the Client
A common trick is for the CGI program to redirect the request to a different Web page.
We can direct the client to the appropriate page like this:
![]()
Dynamic Graphics
By making the cgi-bin program one that can generate images on the fly, a dynamic image can be returned, such as hits counter.
Hiding Context Information
We can pass information between one form and the next using hidden fields or by appending information to the URL afte a ? character.
An Application
We will now adapt our database application for access over the Web.
Try It Out - An HTML Database Interface
1. This is the full listing of the program app_html.c. The main function starts the database.
![]()
2. If there was a legitimate query string, display the tracks for the CD.
![]()
3. If we get here, no entry has been selected.
![]()
4. If we get here, the additional parameters have already been parsed:
![]()
5. This code shows a screen with one entry, defined by cat_title:
![]()
6. This short function lives up to its name by accepting a string and changing any occurrence of the space character to a + symbol:
![]()
How It Works
The first part of the process is to check that the database will initialize. Information on a specific CD is given by the process_cat.
process_no_entry is invoked and displays a list of all the CDs. We then display them using HTML. The 'clever' part is in the lines:
![]()
To create the full application, we need to define all the functions that we used in app_html.c. We create a file calledd html.c and start it like this,
![]()
decode3.c./P>
![]()
to put everything together, we can use a short makefile:
![]()
When we compile the program with make, the program is moved into the cgi-bin directory and we can access it using the URL http:localhost/cgi-bin/cddb/cdhtml.
This gives us a list of CDs, like this:
![]()
If we then click one of the highlighted links. What we see are the tracks of the selected CD:
![]()
Summary
This chapter shown how to crete dynamic, interactive Web pages.
To recap, in this chapter we've covered:
![]()
CS 248 - UNIX Programming Web Site Menu
Information | Syllabus | Schedule | Online "Lectures" | Projects | Quizzes | Web Board
Copyright © 2001 by James L. Fuller, all rights reserved.