CGI Programming for C Programmers


CGI (Common Gateway Interface) programs are programs that exist, and are run on, a web server. They are normally run by a client computer by clicking a button in their browser. CGI programs usually perform some task like a search, or storing information on the server, and also normally generate a dynamic HTML page in response to the user's request.

CGI programs are often written in PERL, but this document will address CGI programming using C/C++. This document will also describe a basic C library of routines I have written to simplify CGI programming, and also offer a demo of the library.

The basic (yet most challenging) parts of a CGI program involve input and output. These items are described here, and a basic understanding of HTML (Hyper Text Markup Language, the language used to create web pages) is assumed. At the end, a brief introduction to MGCGI is provided, which is a library of C routines I developed to help manage this site.


Input

As previously stated, input to the CGI originates as a user's response to a web page. The input to a CGI program includes the contents of fields from a web page, and various environment information about both the server, and the client.

To understand this, it's helpful to think of the web page as a form, with edit controls or fields. Each field is assigned a name, and a value. For example:

What's your favorite color?

The field above is an input field, whose name is FavoriteColor. The HTML code to create the above field would be (you can view the source for this document to verify this):

<INPUT NAME="FavoriteColor" TYPE="text" SIZE="25">

If this form were to send information to a server CGI program, then 'FavoriteColor' would be considered a variable name, and the CGI would be able to access it's value, which would be whatever a user typed in the edit box.

How a CGI program is run

A form (or web page) has 2 methods for sending information to a CGI program, called GET and POST. The HTML for a web page contains a FORM tag which indicates what type the page is, and which CGI program is to be run on the server. For example, this document contains the tag:

<FORM ACTION="CGIFavColor.cgi" METHOD=POST>

 Here, we are stating this form should run the CGIFavColor.cgi CGI program (the .cgi extension is required by my server), with a POST method. CGIFavColor is a C program on my server. Note that running the CGI depends on each server, for example you might need to set certain permissions for the CGI file, and require a certain extension.

Most commonly, a 'Submit' button is used to invoke the CGI. A submit button is a special HTML tag intended for just this purpose. For example:

The HTML code for this submit button would look like:

<INPUT NAME="RunTheCGI" TYPE="submit" VALUE="Submit Color">

The submit button, will invoke the CGI program specified by the FORM tag of the document. You can try the button above.

The submit button sends the form and it's data from the browser to the server. For this example page, the 'Favorite Color' field above will be sent to the CGI program with it's contents.

You can also have a link on a page run a CGI program. To do this, you specify the name of the CGI program as the link, for example(This example also shows how to pass a parameter to the CGI):

Favorite Color is black

The HTML tag for the above is:

<A HREF="../cgi-bin/CGIFavColor.cgi?FavColor=Black">Favorite Color is black</A>

The link method does not use (or need) the FORM tag to specify a CGI program to run.

You can also run a CGI program when a page is loaded (often used for web counters), by specifying the name of the CGI as an element, like an image. For example:

<IMG SRC="../cgi-bin/CGIFavColor.cgi">

This method would assume that the CGI program would output an image, like a GIF. Since the CGIFavColor CGI program in this example does not return a GIF, it is not demonstrated here. Now, when the tag is encountered by the browser, the CGI program is run, and it can do whatever it wants (like, increment a counter in a file), and then it returns (outputs) a GIF image.

GET vs. POST

The difference between the GET and POST is how the information from the form is sent to the CGI program, from the server.

A GET will provide the the user's input to the CGI program as an environment variable called QUERY_STRING. The CGI program would read this environment variable (using the C getenv() function) and parse it to get the user's input. A GET method will also show the input data to the user in the URL area of the browser, showing a string like www.somewhere.com/CGIFavColor.CGI?FavColor=Black. The GET method is acceptable for small amounts of data. Also, GET is the default method, when a CGI program is run via a link

A POST will provide the user's input to the CGI program, as if it were type at the keyboard, using the standard input device, or stdin. If POST is used, then an environment variable called CONTENT_LENGTH indicates how much data is being sent. You can read this data into a buffer, by doing something like:

char Buffer[512]={0};
int InputLength = atoi( getenv("INPUT_LENGTH") );
InputLength = min( InputLength, sizeof(Buffer)-1 ); /* Avoid buffer overflow */
fread( Buffer, InputLength, 1, stdin );

Your CGI program should inspect the REQUEST_METHOD environment variable to determine if the form was a GET or POST method, and take the appropriate action to retrieve the form.

For a listing and working demonstration of other CGI Environment variables, click here.

Parsing the Input

Once the input is received, it must be parsed. All field values will appear as one long string. Each value is separated by an & character. For example, a two-value string might look like: FavColor=Black&FavFood=Twinkies

Here, FavColor and FavFood would be the names of two input fields from the form, and Black and Twinkies would be what the user entered in those fields.

The server will also perform the following conversions:

You will need to un-do these conversions in your CGI program.

Once parsed, it's usually convenient to store the input parameters in either an array of strings, or a long string of values. You would probably also want a function that searches the stored parameters to retrieve their values.


Processing

Once the input is received and parsed, you now proceed to do whatever the CGI was intended to do. This is normal C/C++ programming, and you can open files, write data, read data, whatever you want.


Output

A CGI program outputs it's result by sending the data to the standard output device (stdout, or cout in C++). But, you must output in a specific format.

The most common format, is HTML text. But, the program can also output an image, sound, or any other file type that a browser will recognize. For the remainder of this document, I will describe the HTML format, since it is by far the most common (an exception being access counters, which often output an image).

A CGI program must begin it's output (again, for HTML) with the following string: Content-type: text/html, followed by 2 carriage returns. In C, this would be accomplished with:

printf( "Content-type: text/html\n\n");

Next, the CGI must output the entire web page, using HTML tags. The minimum required, would be the start and end BODY and HTML codes. You can insert anything you want between the start and end codes. For example:

printf("Content-type: text/html\n\n");
printf("<HTML><BODY>\n"); /* \n isn't needed, but makes source more readable */
printf("<P>Hey! This is my first CGI response!</P>\n"); /* <P> is an HTML paragraph tag */
printf( "</BODY></HTML>\n");

Basically, that's it. Output whatever you want as HTML tags. One important note is that some servers put a time-out period on programs, so they don't become a 'run away' process. Normally, if your program doesn't complete it's task, and output it's data in 10 seconds, it will be terminated by the server, and an error message returned by the server.

Don't forget that even error messages from the program, must appear in the format described above.


Environment Variables

For a listing and working demonstration of other CGI Environment variables, click here.


MGCGI

MGCGI is a library of CGI routines that I've developed used for the administration of this site. The routines all work, to the best of my knowledge, and if you find a bug, I'll do my best to fix it. There's no charge for using the routines, no end-user copyright notice, it's really free. All I ask, is that you not removed my name and copyright notice from the source code.

Basically, MGCGI contains routines for loading form input values, making them easily accessible, and simplifies the creation of response forms. It contains debugging abilities that permit you to use debug files for input and output, so you can test programs without putting them on a web site.

 

Compiling MGCGI

MGCGI is composed of 5 files: mgcgiin.c, mgcgiout.c, mgcgictl.c, mgcgimail.c, and mgcgi.h. These files should be compiled, and optionally put into a library or archive. If your using unix, you will want to uncomment the line #define UNIX in the mgcgi.h file. If you do not compile with UNIX, then Windows is the assumed target type (specific to email transmission).

Once you have the object modules, they may be linked with a standard C program. If your using C++ for your main program, you may wish to enclose the mgcgi.h file in an extern "C" { ...} statement.

 

MGCGI Basics

MGCGI provides the following functionality:

A basic example of handling a form, would be the program setup to handle this form (the Favorite color question, above). The source code for this program is:

#include "mgcgi.h"
void main( int argc, char**argv )
{
char Color[128]; /* Loads input form data */ MGCGILoadInput(); /* Starts output page data */
/* Retrieves a single value, for the FavColor Field */
MGCGIStartPage( NULL, "Favorite Color Response" );
/* Note: If the field were not found, MGCGIGetValue returns NULL */
strcpy( Color, MGCGIGetValue("FavColor") );
/* Add a horizontal rule to page */
MGCGIHRule( HA_CENTER );
/* MGCGIPrintPage is similar to printf, but sends output to web page */
if( strlen(Color) == 0 )
MGCGIPrintPage( "Hey, you left color blank!" );
else if( StrICmp( Color, "black" ) ==0 )
MGCGIPrintPage( "Cool, black is my favorite color also" );
else
MGCGIPrintPage( "%s is nice, but I prefer black.", Color );
MGCGIHRule( HA_CENTER );
/* Signal end of page */
MGCGIEndPage();
/* Terminate program, and shut down MGCGI library */
MGCGIExit();
}

 

The MGCGI files can be downloaded from here:mgcgi.zip. You will also find the CGI program 'feedback.c' there, which is the CGI program that the anonymous feedback form for this site uses.

Each function is commented for documentation, and I will work on real documentation if there's enough demand. In the meaintime, you can email me at mario@openroad.org with any questions or comments.

Return to the openroad.org homepage.