This tutorial will guide you through the basics of programming for the GET CGI data stream. It will also provide you with a base understanding of what is required to make your own GET METHOD CGI's. If you are unfamiliar with the CGI data stream, (see: the online CGI Primer).
You will explore the commonly used GET METHOD by stepping through a basic GUESTBOOK, also used in the POST tutorial.
Objectives:
We will start our guestbook tutorial by defining our objectives:
GET HTML FORM:
< HTML > < HEAD > < TITLE > Get Method CGI - Guestbook v1.0 < /TITLE > < /HEAD > < BODY > < CENTER > < FONT SIZE=+3 > Welcome to the < FONT COLOR="#FFFF00" > GET < /FONT > Guest Book < /FONT > < /CENTER > < HR SIZE=2 > < BR > < CENTER > Please take the time to add your name to our guestbook. < BR > < BR > This program demonstrates the GET METHOD CGI < BR > interface built into < FONT COLOR="#FFFFFF" > PlanetWide OS/2 Web Server v1.10 < /FONT >. < BR > < /CENTER > < BR > < CENTER > < FORM METHOD="GET" ACTION="/cgi-bin/guestbook" > < INPUT TYPE="hidden" NAME="FIELD1" VALUE="add" > < BR > Your First Name < INPUT TYPE="text" NAME="first_name" VALUE="" SIZE="15" MAXLENGTH="25" > < BR > < BR > Your Last Name < INPUT TYPE="text" NAME="last_name" VALUE="" SIZE="15" MAXLENGTH="25" > < BR > < BR > Email Address < INPUT TYPE="text" NAME="email" VALUE="" SIZE="25" MAXLENGTH="25" > < BR > < BR > < INPUT TYPE="submit" VALUE="Submit to Guestbook" > < INPUT TYPE="reset" VALUE="Clear Fields" > < /FORM > < /CENTER > < CENTER > < FORM METHOD="GET" ACTION="/cgi-bin/guestbook" > < INPUT TYPE="hidden" NAME="FIELD1" VALUE="view" > < BR > < INPUT TYPE="submit" VALUE="View Guestlist" > < /FORM > < /CENTER > < HR SIZE=2 > < FONT SIZE=-2 COLOR="#FFFFFF" > PlanetWide OS/2 Web server & copy; copyright 1997 Payne Mennie Computing Services. < /FONT > < /BODY > < /HTML >
Sample GET CGI - Guestbook:
/*------------------------------------------------- SAMPLE CGI - GUEST BOOK v1.1 USING GET METHOD. Written by Payne-Mennie Computing Services August 1997. -------------------------------------------------*/
Our guestbook has two functions: (1) Accept client data into the guestbook, and
(2) HTML form serves a dual purpose. Instead of writing two separate
CGI's; one to get the user information, and another to view the guestbook,
we include a hidden field in the form called FIELD1. Its purpose is to toggle
the desired function within a single CGI. ( Field1 may contain: add, or view.)
Our guestbook will recieve four pieces of data from an HTML form in a single data stream,
and act upon the data sent. The four pieces of data are as follows:
The CGI contains many functions built-into the C programming language,
and must have the appropriate header files included.
#include < direct.h > #include < stdio.h > #include < stdlib.h > #include < string.h > /* function to extract the contents of a field. */ /* function to add user entry to the guestlist. */ /* function to display the guestbook to the user. */ /* function to send MIME-TYPE header information to the client. */
char *get_field(char token[50]); void add_user_name(char first_name[50], char last_name[50], char email[50]); void show_guest_book(void); void header(void); /* global temporary variable. */ char temp2[100]; void main(void) { /* field arrays to store the data extracted from the input stream. */ char field1[50], field2[50], field3[50], field4[50], token1[50], token2[50], token3[50], token4[50], temp[100], buffer[100]; /* generic integer declarations. */ int count, i, len, length; char *cp; /* char pointer to collect the data stream contents */ /* set the current working directory(cwd) to /cgi-bin. */ chdir ("cgi-bin"); /* point the char*(pointer) at the QUERY_STRING environment variable which contains the complete data stream. */ cp=getenv("QUERY_STRING"); len=strlen(cp); /* fill the input buffer[] with the input data stream */ for(i=0;i < len;i++) buffer[i]=cp[i]; buffer[i]=0;
Data sent to the CGI from the client is unreadable and must
be massaged to extract the data from the stream. We can make
the task easier by converting all field separators('&') to blank
spaces.
length=strlen(buffer); for(i=0;i < length;i++) {
if (buffer[i]=='&') temp[i]=32; else temp[i]=buffer[i]; } /* parse fields from input buffer. */ token1[0]=token2[0]=token3[0]=token4[0]=0; count=sscanf(temp, "%s %s %s %s", token1, token2, token3, token4); /* if only FIELD1 is present, check for 'view' in token-field1 */ if(count==1) { strcpy(field1,get_field(token1)); if(strcmpi(field1, "view")==0) show_guest_book(); } /* if all four fields names are present, check for the 'add' in token-field1. */
if(count==4) { strcpy(field1,get_field(token1)); if(strcmpi(field1, "add")==0) { strcpy(field2,get_field(token2)); strcpy(field3,get_field(token3)); strcpy(field4,get_field(token4)); } add_user_name(field2, field3, field4); } } /* end main(); */ /* convert extended %hex characters in field to viewable ASCII characters. Called by the get_field() function.*/ int atoi16(char *in) { static int i; sscanf(in,"%X",&i); return i; } /* end atoi16(); /*
Data sent to the CGI from the client is unreadable and must
be massaged to extract the data from the stream. For this
it is easiest to convert all field separators('&') to blank spaces
(as seen in main() ). Now we will parse the data stream into segments
for evaluation.
/* extract data from field=data and return it to parent function. */ static char *get_field(char token[50]) { int i, done; char *c; char temp3[100]; static char temp2[100]; i=0; done=0; temp2[0]=0; temp3[0]=0; c=strstr(token,"="); /* extract field contents */
while(!done) { temp2[i]=c[i+1]; if((temp2[i]==32)||(temp2[i]==NULL)) { done=1; temp2[i]=0; } else i++; } for (i=0;i < strlen(temp2);i++) { switch (temp2[i]) { case '+': temp2[i]=' '; break; case '%': strncpy(temp3,&temp2[i+1],2); temp3[2]=0; temp2[i]=atoi16(temp3); strcpy(&temp2[i+1],&temp2[i+3]); break; } } return(temp2); } /* end getfield() */ /* show the guestbook. send the header/guestlist/tail to client via stdout */ void show_guest_book(void) { FILE *fp; char buffer[255]; int done; /* send default header HTML */ header(); /* send mime header information */ printf("%cHTML%c\r\n",60,62); printf("%cHEAD%c\r\n",60,62); printf("%cTITLE%c\r\n",60,62); printf("The POST Guest Book guestlist & copy; copyright 1997 Payne-Mennie Computing Service.\r\n"); printf("%c/TITLE%c\r\n",60,62); printf("%c/HEAD%c\r\n",60,62); printf("%cBODY bgcolor=""#000099"" text=""#00FF66"" %c\r\n",60,62); printf("%cCENTER%c\r\n",60,62); printf("%cFONT SIZE=+2%cVisitors to the\r\n",60,62); printf("%cFONT COLOR=""#FFFF00""%c GET %c/FONT%c\r\n",60,62,60,62); printf("Guest Book%c/FONT%c",60,62); printf("%c/CENTER%c\r\n",60,62); printf("%cBR%c\r\n",60,62); printf("%cHR SIZE=2%c",60,62); printf("%cBR%c\r\n",60,62); printf("%cBR%c\r\n",60,62); printf("%cBR%c\r\n",60,62); printf("%cTABLE%c%cTR%c%cTH align=left%c\r\n",60,62,60,62,60,62); printf("%cFONT size=-1 color=""#FFFFFF""%c\r\n",60,62); printf("%cOL%c\r\n",60,62); /* send guestlist body or default message */ if((fp=fopen("guestlist.htm","rt"))==NULL) printf("No users have signed the book yet! Why don't you be the first!? \r\n"); else { done=0; while(!done) { if(fgets(buffer,255,fp)==NULL) { done=1; fclose(fp); } else printf("%s\r\n",buffer); } } /* send default tail HTML */ printf("%c/OL%c\r\n",60,62); printf("%c/FONT%c\r\n",60,62); printf("%c/TABLE%c\r\n",60,62); printf("%c/BODY%c\r\n",60,62); printf("%c/HTML%c\r\n",60,62); } /* end - show_guest_book() */
Once FIELD1 has been evaluated and the add funtcion
has been determined, we add first_name, last_name,
and email to the output file in the /webserv-directory/cgi-bin/
directory.
/* add user information to the guestlist.htm file. */ void add_user_name(char first_name[50], char last_name[50], char email[50]) { FILE *fp; /* determine if the required fields have been filled (first_name, last_name). */ if( (first_name[0]==0) && (last_name[0]==0) ) { header(); /* send mime header information */ printf("Press your back button and be sure to enter your information into the fields.%cBR%c\r\n",60,62); } else { /* open the guestlist.htm output file. */ if((fp=fopen("guestlist.htm","a"))==NULL) { header(); /* send mime header information */ printf("Sorry, SUBMIT again. The guestbook was in use.\r\n"); } else { header(); /* send mime header information */ fprintf(fp,"%cLI%c %s %s %cFONT COLOR=""#EEEE00""%c %s %c/FONT%c %cBR%c\r\n",60,62,first_name, last_name,60,62,email,60,62,60,62); fclose(fp); printf("%s %s, You have been added to our guestbook. Thanks!\r\n",first_name, last_name); } } }/* end add_user_name(); */
/* MIME-Type header */ void header(void) { printf("Content-Type: text/html\r\n"); printf("\r\n"); }
This concludes the GET CGI Guestbook tutorial. If you require more
information about the CGI interface, visit the following internet links.
See this link at Yahoo for links to CGI resources. If this link is not available,
start at the main site and search for CGI.
Visit this site for a vast amount of CGI programming information.
Visit this link for more about Handling FORMS from your CGI programs.
Here is an online tutorial for C programmers.
Although our sample CGI's were written in C, the REXX command language and other interpreted languages may achieve a similar result.