Figure 20.34b – Output of JavaScript program

 

WHAT IS CGI (COMMON GATEWAY INTERFACE)

CGI stands for Common Gateway Interface and is a simple protocol (standard) to establish a communication (interaction) between your Web page (located anywhere) via a browser and your program that resides on a Web server. The CGI program (e.g. C++, or Perl) processes data submitted by a form and performs requested tasks such as searching. After submitting a form, the browser uses HTTP to make a request for the URL of a CGI program. The Web server receives the request and executes the CGI program with the data that is passed. The output of the CGI program is usually in the form of a web page which is sent back through the Web server to the requesting browser. An example of CGI usage is a database program that runs on the Internet and lets individuals manipulate the database through the web.

Note that a CGI program is executable and resides in a special directory under the direct control of a Webmaster, commonly known as /cgi-bin, so that the Web server is directed to execute the CGI program rather than just display it to the browser.

 

 

WRITING A CGI IN C++

 

A CGI takes information from forms on a Web page, processes it, and sends a page back to the user. A CGI program written in C++ is nothing more than just another C++ program that accepts a string as its input and breaks down the input string into tokens (words) and identifies and processes the input based on the requested task. CGI is language independent and the languages Perl and Python or even a script language such as Unix shell can be used to write a CGI program. One caution, do not try to use Java to write a CGI; instead, use Java Servlets. The language Perl, because of its sophisticated pattern matching (regular expressions), has been the language of choice for writing CGI programs. However, you can stick to C/C++ and write a CGI, rather than using other languages.

 

In summary, in order to write a simple CGI program in C++, use the input routines of C++ cin or getline( ) to take the data as if it were on a standard input (stdin) with the understanding of how the inputs are separated from each other (e.g. by & or by ; ). After that, a CGI program is another C++ program and when all processing is done, at the end, the CGI program has to communicate to the web page or create a new one. The CGI communicates back to the web page through the standard output (stdout) such as cout with embedded HTML tags inside the quotations. Note that the CGI program takes input from the HTML form and encodes it (URL encoding) by making a single string, since URL does not allow spaces. Instead of spaces, separators (delimiters) such as & (ampersand) and = (equal sign) are used. In the following example, the string with two input data such as the first name and last name are separated with & is sent to the CGI and the program has to strip the f= and save the values correspondingly. For simplicity, we are using one letter for the name of the field.

f=John&f=Doe

 

 

C++ CGI PROGRAM

 

The following HTML file consists of a form with one input data and we want to send the input and get a response by echoing the input back. At first, an HTML file is created and, in the form tag, the action is specified by indicating the name of the executable CGI program (e.g. ebrahimi.cgi) which resides in the /cgi-bin directory. The method of sending the data to the CGI program is POST where the data is sent via the program’s standard input in contrast to the other method GET where the data is sent through a program variable name known as environment variable. For the sake of simplicity, the field’s name is chosen as one character (e.g. f ) which with the = sign makes two characters (e.g. f =). One job of the CGI is to strip off these two characters and save the rest (e.g. value). The following CGI program takes the encoded URL, strips the first two characters, and saves the rest of the string into another string (e.g. str2), which is echoed back to the user. 

 

Note that the "Content-type: text/html\n\n" in

cout<<"Content-type: text/html\n\n";

will inform the server that the CGI program is about to send data to the user in the form of an HTML page. Make sure to include the newline (\n).

 

If you need to convert the above C++ program to C language for the reason of speed, you only need to change cin to scanf(“%s”,  ) and cout to printf( “%s”, ) and make sure to include #include <stdio.h>.


 

Text Box: <html>
<form action=cgi-bin/ebrahimi.cgi method="post">
<input type=text name=f size=10>
<input type=submit value=submit>    
</form>
</html>      

  

 

 

 

 

 

 


 

   Figure 20.35a – HTML form to take in user input

Text Box: #include <iostream>
using namespace std; 
int main(){
   char str[100];
   char str2[100];
   cin>>str;
   int i=2;
   int n=0;
   for(i=2; str[i]!=0 ;i++)
   {
    str2[n]=str[i];
    n++;
   }//REMOVE FIRST TWO CHARACTERS FROM POST
   str2[n++]=0;//SET THE END OF THE STRING TO NULL
 
   cout<<"Content-type: text/html\n\n";
   cout<<str2;
              return 0;
}//MAIN

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

                                   

 

  Figure 20.35b – CGI program to take in a string and display it

 

 

COMPILING A CGI PROGRAM

 

The following compiles a CGI program under Linux (GNU c++ compiler known as g++). However, the executable code is redirected to a file with the extension .cgi. The command chmod (change mode) makes the executable code accessible to the public (read, no write, execute), but you can have all access permissions (read, write, execute).

 

g++ -o  ebrahimi.cgi  ebrahimi.cpp

 

chmod 755  ebrahimi.cgi

 

Other operating systems may work differently than a Unix-like OS, but the concept would be the same. Note that one reason to place the CGI program in a specific directory like /cgi-bin is for security reasons and to make it easier for the system administrator to manage. 

A C++ CGI PROGRAM WITH TWO INPUT DATA

 

The following C++ CGI program uses two input with the hope that you will understand how to write a multiple input program using the same strategy. The strategy is that every data has a field name followed by =, its value, and a separator (&) before the next field’s name. The program has to skip two characters to get to the value of the first input and, after that, three characters must be skipped between values. For example: f=John&f=Doe

Note that the below program is just for you to understand the concept and you may want to generalize it so it can work with any input and any size field name.

Text Box: <html>
<form action=cgi-bin/ebrahimi.cgi method="post">
First Name: <input type=text name=f size=10><br>
Last Name: <input type=text name=f size=10><br>
<input type=submit value=submit>
</form>
</html>

  

 

 

 

 

 

 

 


 

  Figure 20.36a – HTML form to take in two inputs

Text Box: #include <iostream>
using namespace std;
int main() {
   char str[100];
   char fname[100];
   char lname[100];
   cin>>str;
   int i=2;
   int n=0;
   for(i=2;str[i]!='&';i++){
    fname[n]=str[i];
    n++;}
   fname[n++]=0;
   n=0;
   for(i+=3;str[i]!=0;i++) {
    lname[n]=str[i];
    n++;}
   lname[n++]=0;
   cout<<"Content-type: text/html\n\n";
   cout<<"<HTML><B>Your Name: </B>";
   cout<<fname<<" "<<lname;
   cout<<"</HTML>";
    return 0;}//MAIN

  

 


 

           

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  Figure 20.36b – CGI program to take in two strings and display them

 

 

Your Name: John Doe

 

  Figure 20.36c – Output as HTML page

 

 

C++ CGI DATABASE

 

The following program demonstrates how you simply can make a web application where users can interact with your program from anywhere using C++ with CGI capabilities. To make the program short, other database functions such as display, update, and deletion are omitted. The program creates a simple database with simple file handling without using other databases such as Access or SQL tools. The program follows a similar strategy of extracting the variables from the input (URL encoding). The variables need to be separated (i+=3), this extraction could be put into a function. For the sake of simplicity, each function is a separate form in HTML; you may want to try to put it into a single form. For each function, there is a separate CGI program in the cgi-bin directory. As an exercise, you can write those functions and optimize the code and even include object-oriented design.

Text Box:                 empdatabase.html
<HTML>
<BODY BGCOLOR=ffdeaa>
<CENTER><BR><B>Employee Database</B></CENTER><BR>
<HR WIDTH=65%>
<CENTER>Please select from the following choices:<BR><BR>
<FORM ACTION="insertrecord.html">
                <INPUT TYPE="submit" VALUE="1. Insert a Record          "></FORM> 
<FORM ACTION="cgi-bin/displayall.cgi">
                <INPUT TYPE="submit" VALUE="2. Display all Records  "></FORM> 
<FORM ACTION="search.html">
                <INPUT TYPE="submit" VALUE="3. Search Database      "></FORM>
<FORM ACTION="cgi-bin/update.cgi">
                <INPUT TYPE="submit" VALUE="4. Update Record          "></FORM>
<FORM ACTION="cgi-bin/delete.cgi">
        <INPUT TYPE="submit" VALUE="5. Delete a Record       "></FORM> 
</CENTER></BODY>
</HTML>

  

 

 

 

 

 

 

 

 


 

            Figure 20.37a – HTML for the database menu

                                                                                                   


 

 

Text Box: insertrecord.html
<HTML>
<BODY BGCOLOR=ffdeaa>
<CENTER>
<BR><B>Insert Record to Employee Database</B><BR><BR>
<HR WIDTH=65%><BR>
<FORM ACTION="cgi-bin/insertrec.cgi" METHOD="post">
<B>First Name: <INPUT TYPE=text NAME=f SIZE=15><BR><BR>
Last Name: <INPUT TYPE=text NAME=f SIZE=15><BR><BR>
Salary per hour: <INPUT TYPE=text NAME=f SIZE=5 value=0.00><BR><BR>
Hours worked: <INPUT TYPE=text NAME=f SIZE=5><BR><BR>
<INPUT TYPE=submit VALUE="Submit Record"></FORM>
</CENTER></BODY>
</HTML>
 
Text Box:

  

 

 

 

 

 

 

 

 

 

 

 

 

 


 

            Figure 20.37b – HTML for inserting a record

 

 

 

 

 

 

 


  

Text Box:                 insertrec.cpp
#include<iostream>
#include <fstream>
#include <string.h>
using namespace std;
struct employee{                 char fname[30], lname[30];
                                double salary, hoursworked, netpay;};
int main(){
                char str[150], fnamef[20], lnamef[20], salaryf[10], hoursworkedf[10];
                cin>>str;
                int i=2, n=0;
                for(i;str[i]!='&';i++){ fnamef[n]=str[i];  n++; }//FOR
                fnamef[n++]=0; n=0;
                for(i+=3;str[i]!='&';i++){
                                lnamef[n]=str[i];
                                n++; }//FOR
                lnamef[n++]=0;  n=0;
                for(i+=3;str[i]!='&';i++){ salaryf[n]=str[i];  n++; }//FOR
                salaryf[n++]=0;  n=0;
                for(i+=3;str[i]!=0;i++){ hoursworkedf[n]=str[i];  n++; }//FOR
                hoursworkedf[n++]=0;
                ofstream record("employee.txt",ios::app);
                record<<fnamef<<" "<<lnamef<<" "<<salaryf<<" "<<hoursworkedf<<endl;
                record.close();
                cout<<"Content-type: text/html\n\n";
                i=0;  employee emp[100];
                ifstream record2( "employee.txt", ios::in);
                cout<<"<BODY BGCOLOR=ffdeaa>";
                cout<<"<BR><CENTER><B>Employee Database: Display All Records</B><BR>";
                cout<<"<BR><HR WIDTH=65%><BR>";
                cout<<"<TABLE BORDER=5><TR><TD><B>First Name</B></TD>";
        cout<<"<TD><B>Last Name</B></TD>";
        cout<<"<TD><B>Salary</B></TD>";
        cout<<"<TD><B>HrsWorked</B></TD>";
        cout<<"<TD><B>Net Pay:</B></TD>";
        cout<<"</TR>";    
while(record2>>emp[i].fname>>emp[i].lname>>emp[i].salary>>emp[i].hoursworked){
                emp[i].netpay=emp[i].salary*emp[i].hoursworked;
                cout<<"<TR><TD>"<<emp[i].fname<<"</TD><TD>";
                cout<<emp[i].lname<<"</TD><TD>"<<emp[i].salary<<"</TD><TD>";
                cout<<emp[i].hoursworked<<"</TD><TD>"<<emp[i].netpay<<"</TD></TR>";
                }//WHILE
cout<<"</TABLE><br><br>";
cout<<"</CENTER></BODY>"; 
record2.close();
              return 0;
}//MAIN

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

           

 

 

Figure 20.37c – CGI program to insert a record into the database and display all


 

Text Box:                 search.html
<HTML>
<BODY BGCOLOR=ffdeaa>
<CENTER>
<BR><B>Search Employee Database</B><BR><BR>
<HR WIDTH=65%><BR>
<FORM ACTION="cgi-bin/search.cgi" METHOD="post">
<B>Enter Employee's Last Name: </B>
<INPUT TYPE=text name="f" SIZE=15>
<INPUT TYPE=submit VALUE="Search"></FORM>
</CENTER>
</BODY>
</HTML>

  

 

 

 

 

 

 

 

 

 

 

 


 

            Figure 20.37d – HTML to take in search name

 

  

 

 

 

 

 


 

 

Text Box: search.cpp
#include<iostream>
#include <fstream>
#include <string.h>
using namespace std;
struct employee{
                char fname[30], lname[30];
                double salary, hoursworked, netpay; };
int main(){
                char buff[100], buff2[100];
                cin>>buff;
                cout<<"Content-type: text/html\n\n";
                int i=2;
                while(buff[i]!=0){
                                buff2[i-2]=buff[i];
                                i++;}//WHILE
                buff2[i-2]=0;
                cout<<"<BODY BGCOLOR=ffdeaa>";
                cout<<"<CENTER><BR><B>Search results</B><BR><HR WIDTH=65%><br><br>";
                employee emp[100];
                ifstream record("employee.txt", ios::in);
                i=0;         
int k=-1;
                while(record>>emp[i].fname>>emp[i].lname>>emp[i].salary>>emp[i].hoursworked)
                {i++;}
                for(int j=0;j<i;j++){
                                if(strcmp(buff2,emp[j].lname)==0)
                                                k=j; }//FOR
                if(k!=-1){
        emp[k].netpay=emp[k].salary*emp[k].hoursworked;
        cout<<"<TABLE BORDER=5>";
                cout<<"<TR><TD>First Name:</TD><TD>"<<emp[k].fname<<"</TD></TR>";
        cout<<"<TR><TD>Last Name:</TD><TD>"<<emp[k].lname<<"</TD</TR>";
        cout<<"<TR><TD>Salary:</TD><TD>"<<emp[k].salary<<"</TD></TR>";
        cout<<"<TR><TD>Hrs Worked:</TD><TD>"<<emp[k].hoursworked<<"</TD></TR>";
        cout<<"<TR><TD>Net Pay:</TD><TD>"<<emp[k].netpay<<"</TD></TR></TABLE>";}
                else {cout<<"Record not found"<<"<br>";}
cout<<"</CENTER></BODY></HTML>";   
              return 0;
}//MAIN
 

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

           

 

Figure 20.37e – CGI program to search for a record and display it

Text Box: