COMMON GATEWAY INTERFACE CGI

CGI provides the communication interface between a gateway and a Web server. In addition to this chapter, you can read the notes for a more detailed description.

A script is a program written a C, C++, TCL, PERL (Practical Extraction and Report Language).

Web server is the middleware to receive request from the Web client and pass it to CGI script, and send information back to the Web Client.


CGI FOR WEB DATABASE

The CGI script can be interfaced to the database through the API (Application Program Interface).


Environment Variables

CGI environment variables:

AUTH_TYPE
CONTENT_TYPE
CONTENT_LENGTH
GATEWAY_INTERFACE
REQUEST_METHOD
SCRIPT_NAME
QUERY_STRING
SERVER_SOFTWARE
SERVER_NAME
SERVER_PROTOCOL
SERVER_PORT
HTTP_USER_AGENT
HTTP_ACCEPT
PATH_INFO
PATH_TRANSLATED
REMOTE_HOST
REMOTE_ADDR
REMOTE_USER
REMOTE_IDENT

Run this PERL script to display the environment variables and values available to a CGI script.

See the PERL script.


Request Method: GET and POST

The request method is specified in the environment variable REQUEST_METHOD.

GET: the query string sent is placed in the environment variable QUERY_STRING for CGI script to process.

POST: the query string is sent by a separate stream and becomes the standard input to the CGI script. Note: when POST is used, the environment variables are set: CONTENT_LENGTH, CONTENT_TYPE.


EXAMPLES OF CGI SCRIPT

PERL example:

A bulletin board service for a discussion group can be used by the group to exchange information. The html form submits the input information to the PERL program as follows:
<Form method=POST action="full_path_name/cgi-bin/club.cgi">
      Your name:    <input type="text" name="name" size="30"><br>
      Address:      <input type="text" name="address" size="50"><br>
      Tel. No:      <input type="text" name="tel" size="30"><br>
      Fax:          <input type="text" name="fax" size="30"><br>
      Email:        <input type="text" name="email" size="30"><br>
      Private message to host:<br>
      <textarea name="comm1" rows=5 cols=40></textarea><p>
      E-mail message to all members (also posted on bulletin board) :<br>
      <textarea name="comm2" rows=5 cols=40></textarea><p>
      Message posted on bulletin board only:
      <br>     <textarea name="comm3" rows=5 cols=40></textarea><p>
      <input TYPE="submit" VALUE="Submit"><input TYPE="reset" VALUE="Erase">

In the above, you need to replace full_path_name to where the cgi-bin is actually located. The cgi program is called club.cgi and it is in cgi-bin. It looks like this:

#!/usr/local/bin/perl
# The first line should be where perl resides on the local system.

$company = "company-name\@cs.pitt.edu";
$webmaster = "webmaster-name\@cs.pitt.edu";
# You can have a list of e-mail addresses in the memberlist.
$memberlist = "member-name\@cs.pitt.edu";

 ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)
                                                  = localtime(time);
      $mon = $mon + 1;

if ($ENV{'REQUEST_METHOD'} eq 'POST') {

# Get the input

    read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});

# Split the name-value pairs

    @pairs = split(/&/, $buffer);

# Load the FORM variables

    foreach $pair (@pairs) {
        ($name, $value) = split(/=/, $pair);
        $value =~ tr/+/ /;
        $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

        $FORM{$name} = $value;
    }

# Open the email message to send the data to webmaster
				
    if($FORM{comm1} ne "") {
    open (MESSAGE, "| /usr/bin/mail  $webmaster ");
# The mail utility is in /usr/bin/mail so you need to change that if different.

# Format email header information

    print MESSAGE "To: $company\n";
    if ($FORM{email} ne "") {
        print MESSAGE "Reply-To: $FORM{email}\n";
    }

# Write the actual email message

    print MESSAGE "Subject: Message from $ENV{'REMOTE_HOST'}\n\n";
    print MESSAGE "Name: $FORM{name}\n";
    print MESSAGE "Address: $FORM{address}\n";
    print MESSAGE "Telephone: $FORM{tel}\n";
    print MESSAGE "Fax:         $FORM{fax}\n";
    print MESSAGE "Email:   $FORM{email}\n";
    print MESSAGE "Message to Host:     $FORM{comm1}\n"; 
    close (MESSAGE);
    }

# Open the email message to send the data to a list of members
				
    if($FORM{comm2} ne "") {
    open (MESSAGE, "| /usr/bin/mail $memberlist ");

# Format email header information

    print MESSAGE "To: $company\n";
    if ($FORM{email} ne "") {
        print MESSAGE "Reply-To: $FORM{email}\n";
    }

# Write the actual email message

    print MESSAGE "Subject: Message from $ENV{'REMOTE_HOST'}\n\n";
    print MESSAGE "Name: $FORM{name}\n";
    print MESSAGE "Address: $FORM{address}\n";
    print MESSAGE "Telephone: $FORM{tel}\n";
    print MESSAGE "Fax:         $FORM{fax}\n";
    print MESSAGE "Email:   $FORM{email}\n";
    print MESSAGE "Message to All:     $FORM{comm2}\n";
    close (MESSAGE);
# Also post this message
# You need to change the full_path_name.
    open (MESSAGE, "> /full_path_name/t1");
    print MESSAGE "<p>\n";
    print MESSAGE "<b> Message from $ENV{'REMOTE_HOST'}</b><br>";
    print MESSAGE "<b> Name</b>: $FORM{name}<br>";
    print MESSAGE "<b> Email</b>:   $FORM{email}<br>";
    print MESSAGE "<b> Time/Date</b>:$hour:$min:$sec / $mon-$mday-$year,<br>";
    print MESSAGE "<b>Posted Message</b>:     $FORM{comm2}<br>";
    close (MESSAGE);
# The bulletin bu.html and two temporary files t1 and t2, are in local directory.
# We use local files t1 and t2 so that a new message appears at the top of bulletin.
    $ans=`cat /full_path_name/t1 /full_path_name/bu.html > /full_path_name/t2`;
    $ans=`cp /full_path_name/t2 /full_path_name/bu.html`;
    }

#    Post message to the bulletin board only
				
    if( $FORM{comm3} ne "") {
    open (MESSAGE, "> /full_path_name/t1");
    print MESSAGE "<p>\n";
    print MESSAGE "<b> Message from $ENV{'REMOTE_HOST'}</b><br>";
    print MESSAGE "<b> Name</b>: $FORM{name}<br>";
    print MESSAGE "<b> Email</b>:   $FORM{email}<br>";
    print MESSAGE "<b> Time/Date</b>:$hour:$min:$sec / $mon-$mday-$year,<br>";
    print MESSAGE "<b>Posted Message</b>:     $FORM{comm3}<br>";
    close (MESSAGE);
    $ans=`cat /full_path_name/t1 /full_path_name/bu.html > /full_path_name/t2`;
    $ans=`cp /full_path_name/t2 /full_path_name/bu.html`;
    }

# Thank the user and acknowledge the order
    &thank_you;

} 

else { 	
# Format an error message for the user

    print "Content-type: text/html\n\n";
    print "<HTML>\n";
    print "<HEAD>\n";
    print "<TITLE>Message Form Error</TITLE>\n";
    print "</HEAD>\n";
    print "<BODY>\n";
    print "<H1>Message Form Error</H1>\n";
    print "<HR>\n";
    print "<P>\n";
    print "Form input was not processed.  Please mail your ";
    print "remarks to $company\n";
    print "</BODY>\n";
    print "</HTML>\n";
}
sub thank_you {

    print "Content-type: text/html\n\n";
    print "<HTML>\n";
    print "<HEAD>\n";
    print "<TITLE>Thank You</TITLE>\n";
    print "</HEAD>\n";
    print "<BODY>\n";
    print "<H1>Thank You</H1>\n";
    print "<HR>\n";
    print "<P>\n";
    print "Your message have been emailed to host, or emailed to other members, or posted on the bulletin board.\n";
    print "</BODY>\n";
    print "</HTML>\n";
}


UNIX SHELL Example:

The following html form submits the input information to the CGI script hello.cgi:
<Form Method = "post" action = "cgi-bin/hello.cgi">
Input your name here:
<Input Type="text" Name = "your_name" size=20 value="">
<Input Type="submit" value="submit">
</Form>

This is what you see in the browser:
Input your name here:
The CGI script hello.cgi looks like this:

#!/bin/sh -f
# When the request method is POST,
# read the query string from the standard input.
read string
echo Content-type: text/html
echo ""
echo query string: $string
echo "<p>"
echo $string | awk -F= '{print "Hello", $2, "!"}' | sed 's/+/ /'

C Example:

This html form sends input information to the CGI script ind_info.cgi:
<Form method=GET action="cgi-bin/club.cgi">
      Your name:    <input type="text" name="name" size="30"><br>
      Address:      <input type="text" name="address" size="50"><br>
      Tel. No:      <input type="text" name="tel" size="30"><br>
      Fax:          <input type="text" name="fax" size="30"><br>
      Email:        <input type="text" name="email" size="30"><br>
                    <input TYPE="submit" VALUE="Submit">
                    <input TYPE="reset" VALUE="Erase">
<Form>

what you see in the browser is:

Your name:
Address:
Tel. No:
Fax:
Email:

The CGI script ind_info.cgi looks like this:


#include <stdio.h>
#include <stdlib.h>

/*from cgi2env.c*/
extern void cgi2env();
extern void http_head();

main()
{
   char *val;

   /* split Name-Value pairs into environment variables WWW_Name */
   cgi2env();

   http_head();  /* output header "Content-type: text/html\n\n" */
   val = getenv("WWW_name");
   printf("name = %s <br>\n", val);
   val = getenv("WWW_address");
   printf("address= %s <br>\n", val);
   val = getenv("WWW_tel");
   printf("telphone = %s <br>\n", val);
   val = getenv("WWW_fax");
   printf("fax = %s <br>\n", val);
   val = getenv("WWW_email");
   printf("email = %s <br>\n", val);
}


WRAPPER MIDDLEWARE FOR DISTRIBUTED DATABASES

To simplify the task of the access and integration of information from a variety of heterogeneous data sources, mediator systems are built. In a mediator system, wrappers serve as a middleware to encapsulate individual data sources so that all data sources present a common interface to the mediator.

Wrappers accept one input query and convert it into one or more queries/commands understandable by the encapsulated data source, and transform the native query results into a format understood by the mediator. The mediator thereby integrates these results and returns it to the user.

The figure below illustrates a mediator system in which data sources could be relational databases, object-oriented databases, legacy databases, web sites and so on.