Laboratory Exercises For Computer Science 151

CGI Programming

CGI Programming

Goals: The lab discusses some basic elements of CGI programming, which allows a Web developer to tailor documents to an individual Web user.

CGI Scripts

As you have seen previously, the Common Gateway Interface (CGI) provides a mechanism that allows a Web browser to provide information to a server, as part of a request for a document. In addition, a Web document can specify that a Web server should run a CGI script and program as part of a response for a document. One simple example of a cgi script is what-i-know-script.cgi, as shown below:


#!/usr/bin/csh

/usr/local/bin/scm -q << !
(load "what-i-know-script.ss")
!
As explained in a previous lab, the primary purpose of this script is to run scm Scheme and load the Scheme program ~walker/public_html/cgi-bin/what-i-know-script.ss .

  1. Run the http://www.math.grin.edu/~walker/cgi-bin/what-i-know-script.cgi script, to see what is printed.

  2. Copy the what-i-know-script.cgi script and the Scheme program what-i-know-script.ss to your account, and share each program. Then try running your copy of the script from your Web browser.

Retrieving Information from the Browser

As you can see, the CGI script and program receives and prints information received from your browser. On our system, using SCM Scheme, the particular mechanism through which this information is transferred is a non-standard, predefined procedure named getenv, which takes a string as its argument and returns another string as its value.

Five strings that can be used as arguments are found in the what-i-know-script.ss program:

  1. Add comments to the Scheme program what-i-know-script.ss to annotate what each section of code is doing.

  2. Add a couple lines at the end of the program, so that the program displays your name at the bottom of the Web page it produces.

Query Strings

CGI also provides a mechanism for a browser to explicitly pass information to the Web server for use in a CGI script and program. As an example, consider the common Web application of looking up information on a designated topic within a directory. Such a capability is illustrated with the interface http://www.walker.cs.grinnell.edu/cgi-bin/fac-directory.html. This example allows you to retrieve information about a member of the 1998-1999 Mathematics and Computer Science Department at Grinnell College.

  1. Fill in the requested information in http://www.walker.cs.grinnell.edu/cgi-bin/fac-directory.html, to determine information about Henry Walker and about John Stone.

In outline, this full interaction works in several steps:

  1. You fill in blanks in the html document http://www.math.grin.edu/~walker/cgi-bin/fac-directory.html and press the submit button. For example, you might enter "Henry" and "Walker" for the name of the instructor.
  2. The html form includes this information in a URL request in the format: http://www.math.grin.edu/~walker/cgi-bin/fac-directory.cgi?firstname=Henry&lastname=Walker. Note that the end of this URL, following the file name fac-directory.cgi, there is a question mark ?, followed by the data: firstname=Henry&lastname=Walker.
  3. The CGI script fac-directory.cgi calls the program fac-directory.ss, in the process described previously.
  4. Program fac-directory.ss obtains this special data as a query string, which can be retrieved with the getenv procedure using the string query_string. Program fac-directory.ss then extracts specific name information, and looks up data in a data file http://www.walker.cs.grinnell.edu/cgi-bin/math-cs.faculty.98 .

    We now look at each of these steps in somewhat more detail. The html document /~walker/cgi-bin/fac-directory.html contains a special formatting element, called a form which sets up the blocks for data input and the buttons for responses and which specifies what action should accompany the user's typing.

    1. To view this form, click on the above document and then ask your browser to view the page source. There, you will see that the submit input will result in the action of requesting the CGI script fac-directory.cgi. Similarly, you will find the labels and field names for each input textual field.

    When Henry is entered into the First Name box and Walker is entered into the Last Name box, then when the user clicks the submit button, a request is generated to the Web server -- as shown in step B above.

    1. Instead of using this html form, type the line http://www.math.grin.edu/~walker/cgi-bin/fac-directory.cgi?firstname=Henry&lastname=Walker as the URL directly into your browser. Note that the result is exactly the same as using the form. That is, the html form within fac-directory.html simply provides a convenient way to generate URL addresses with query string information added.

    The fac-directory.cgi script loads program fac-directory.ss. Using SCM Scheme, fac-directory.cgi may recover this information using the procedure call

    
    (getenv "QUERY_STRING")
    
    This call returns the string firstname=Henry&lastname=Walker, just as the previous calls to getenv returned other environmental variables. More generally, the procedure call (getenv "QUERY_STRING") looks at the URL that the browser used to activate the CGI program. If that URL just ends in .cgi, then (getenv "QUERY_STRING") returns #f. However, if there is a question mark after the .cgi, and a string of characters after that, then (getenv "QUERY_STRING") returns the characters in this additional string. The user can supply almost any kind of information to the CGI program through a query string, and the CGI program recovers it by decoding and parsing that string.

    1. Modify the what-i-know-script.ss program, which you annotated and expanded earlier in this lab, to display any query string which is included in a URL to the script what-i-know-script.cgi. Thus, if you typed the URL
      
      http://www.math.grin.edu/~yourUsername/cgi-bin/what-i-know-script.cgi?IlikePOPCORN!
      
      
      the program should include the following text in its output
      
      IlikePOPCORN!
      
      

    In CGI programming, a query string usually consists of a sequence of equations separated by ampersands, with some attribute on the left-hand side of each equation and the value of that attribute on the right-hand side. For instance, in our form example, the query string had the form firstname=Henry&lastname=Walker

    Because the user often wants to supply attribute values that contain spaces, slashes, question marks, or other special characters that would wreak havoc if attached to URLs, CGI requires that such characters be encoded. The conventional encoding is to replace each space with a plus sign and each special character with a sequence of three characters beginning with a percent sign. The CGI program is expected to decode the strings recovered from the query string. This is usually done with the help of some ``library routine'' -- a procedure that someone else has written. In this lab, you'll find it convenient to use the extract-attributes procedure in http://www.walker.cs.grinnell.edu/public_html/cgi-bin/cgi-utilities.scm. This Scheme code, written by John Stone, takes a query string as argument and returns a list of pairs, with the car in each pair being a fully decoded attribute and the corresponding cdr being its fully decoded value:

    
    (extract-attributes "firstname=Henry&lastname=Walker")
    ===> (("firstname" . "Henry") ("lastname" . "Walker"))
    
    In this form of an association list, a program can extract specific information for key values with the assoc procedure, as discussed in our previous lab on pairs and association lists.

    Other processing for program fac-directory.ss combines ideas of processing files and generating html documents, as described in previous labs.

    1. Copy the html form ~walker/public_html/cgi-bin/fac-directory.html , the script ~walker/public_html/cgi-bin/fac-directory.cgi script and the Scheme program ~walker/public_html/cgi-bin/fac-directory.ss to your account, and share each file (chmod 755). Then try running your copies of the html form and script from your Web browser.

    2. Review the source of the program fac-directory.ss. Then discuss (in paragraph form) how the program works.

      • What are the main sections of the program?
      • How is an entry in the directory read?
      • What does the readline procedure do, and how is that task accomplished?
      • Procedure read-directory contains a let, a let*, and a named let. Why are each of these sections needed?
      • Why is a let* expression used at the end of the program? This let* prints a few lines to the screen and then calls read-directory.

    3. Modify the program fac-directory.ss to allow only the partial specification of a name. In particular, if a user enters both a first and last name (in fac-directory.html), then the program will respond in its current way. However, if the user enters only a last name, then the program will return all people who have the given last name.

    4. Modify the interface fac-directory.html and the program fac-directory.ss to retrieve all people with a given telephone number. That is, fac-directory.html should be revised so that it asks the user for a telephone number; program fac-directory.ss then should return all entries in the directory which match that number. (Note, this reverse lookup is very common in various Web-based directories.)

    Work to be turned in:

    For steps 3, 4, 8, 11, and 12, only a printout of the relevant files are needed. You need not show a run of the program (as any run will show up in your Web browser rather than in a window that you can record).


    This document is available on the World Wide Web as

    http://www.math.grin.edu/~walker/courses/153.sp00/lab-cgi-programming.html
    

    created November 3, 1998
    last revised January 11, 2000