CGI - Common Gateway Interface

1) A simple CGI script

CGI scripts do not run on any webserver. In SLIS, CGI scripts run on "ella". The following instructions are correct for ella. Other servers may be set up slightly differently. On ella you should create two directories: "www" and a subdirectory of "www" called "cgi". Both directories should be world readable and executable. All html files should be in the www directory, all cgi files in the cgi directory. The URL for the html files is
http://ella.slis.indiana.edu/~username/filename. The URL for cgi files is
http://ella.slis.indiana.edu/~username/cgi/filename
(Instead of putting the cgi files into the cgi directory they can also be located somewhere else. But then they must be given a ".cgi" extension.)

Exercises

1.1) Save some simple html code such as

<HTML>
<HEAD>
<TITLE> Hello World</TITLE>
</HEAD>
<BODY>
<H1>Greetings</H1>
</BODY>
</HTML>
as a file in your www directory on ella. Look at it through a browser.

1.2) Save some simple cgi code such as

#!/usr/bin/env python

import cgi
print "Content-Type: text/html\n"

print """
<HTML>
<HEAD>
<TITLE>Hello World</TITLE>
</HEAD>
<BODY>
<H1>Greetings</H1>
</BODY>
</HTML>
"""
in your cgi directory. Run it on the command-line to check the syntax. Change file permissions to executeable ("chmod 700 filename" or "chmod u+x filename"). Look at it through your browser.

2) Tips for dealing with an "Internal Server error":

1) The first line of the script must contain the python command (#!/usr/bin/env python). There must not be a blank line (or anything else) before the first line.
2) The line import cgi must be somewhere at the beginning.
3) The very first print statement of your script must be print "Content-Type: text/html\n"
4) The file permissions must be set to executable (chmod u+x filename).
5) The script should be executed on the command line to check the syntax before looking at it through the browser.

3) Processing forms with CGI

Normal HTML:

browserserver
user requests
html document
server finds HTML file
and sends page back

CGI:

browserserver
user requests
a form
server finds the HTML form
and sends it back to user
user fills out form
CGI application executes
program and sends results
back to user

Exercises

A sample form looks like this:

<form action="http://ella.slis.indiana.edu/~username/cgi/example" method="post">

<input type="radio" name="drink" value="tea" checked > Tea <br>
<input type="radio" name="drink" value="coffee" > Coffee <br>
<input type="radio" name="drink" value="hot chocolate" > Hot Chocolate <p>

<input type="submit" value="Place order">
</form>

3.1) Include the form in an html document on ella. Don't forget to change the URL of the form action so that it points to your cgi directory. (Other form elements can be found in this HTML forms tutorial)

This is the source code of a cgi file that processes the form:

#!/usr/bin/env python
#
######### don't change the following three lines: ###########
import cgi
print "Content-Type: text/html\n"
form = cgi.FieldStorage()

## add a form.getvalue for each of the names in your form: ##
drink = form.getvalue("drink")

########## start of HTML code ###########
print """
<html>
<head> <title>What would you like to drink</title> </head>
<body>
<h4>Your drink: </h4><p>
"""
############ end of HTML code #############

if drink == "tea":
    print "You requested tea."
elif drink == "coffee":
    print "You requested coffee."
elif drink == "hot chocolate":
    print "You requested hot chocolate."
else:
    print "You need to select a drink!"

########### start of HTML code ###########
print """
<p>Thank you for your visit. Please come again. <p>
</body></html>
"""
############# end of HTML code ##############

3.2) Save the cgi file. Run it on the command line to check for syntax errors.

3.3) Change the form method (in the html file) to "get". Reload the form in your browser. Then submit the form. Can you notice a difference in the address field of the browser?

3.4) Add a checkbox to the form (such as "Do you want milk? Yes/No") and a text area where customers can type in what kind of cake they would like to order. Change your cgi script so that it includes these in its reply, such as "you requested tea with milk", "sorry we are out of chocolate cake". The checkbox and text area must have distinct names in the form. You need a line with form.getvalue() in your cgi file for each name in your html form.

4) CGI without forms

The parameters that are passed to a CGI file do not need to come from a form. They can also be added to the URL in the following manner:
<A HREF="http://ella.slis.indiana.edu/~upriss/cgi/example?drink=tea">
If the form uses the "get" method, you can see the parameters. Several parameters can be passed to a CGI file. They are separated by a & symbol. No space is allowed after the "?". Blanks should be represented by "+".
<A HREF="http://ella.slis.indiana.edu/~upriss/cgi/example?drink=hot+chocolate">

Exercises

4.1) Try using your cgi file by adding the parameters to the URL. See what happens if the parameters are not tea or coffee or hot chocolate.

4.2) Write an HTML file that does not contain a form but contains three links that send URLs with attached parameters "tea", "coffee", "hot chocolate" to the cgi file. (In this manner you can write cgi files that communicate with other cgi files on the web.)

4.3) (optional) Choose a search engine on the web and analyse how they attach the search paramaters to the URL. Write a form that sends data to that search engine.

5) Optional: Debugging

While it is easy to catch syntax errors (because the script can be executed from the command line), it can be difficult to catch runtime errors, such as missing input, missing files etc. The following example shows how "try" can be put around a block of code. Any runtime errors in this block will be caught by python and will be displayed on the browser.

#!/usr/bin/env python
#
######### don't change the following six lines: ###########
import cgi
print "Content-Type: text/html\n"
form = cgi.FieldStorage()
import sys
import traceback
sys.stderr = sys.stdout

## add a form.getvalue for each of the names in your form: ##
drink = form.getvalue("drink")

########## start of HTML code ###########
print """
<html>
<head> <title>What would you like to drink? </title> </head>
<body>
<h4>Your drink: </h4><p>
"""
########## end of HTML code ###########

try:
    if drink == "tea":
       print "You requested tea."
    elif drink == "coffee":
       print "You requested coffee."
    elif drink == "hot chocolate":
       print "You requested hot chocolate."
    else:
       print "You must choose a drink"

except:
    print "\n\n<PRE>"
    traceback.print_exc()
    print "</PRE>"

########## start of HTML code ###########

print """
<p>Thank you for your visit. Please come again. <p>
</body></html>
"""
########## end of HTML code ###########

Change 'elif drink == "hot chocolate":' to 'elif drink1 == "hot chocolate":' and see what happens.