Easy Tutorial
❮ Cpp Increment Decrement Operators Cpp Return Pointer From Functions ❯

C++ Web Programming

What is CGI?

Web Browsing

To better understand the concept of CGI, let's click on a hyperlink, browse to a specific web page or URL, and see what happens.

However, in this setup, whenever a file in the directory is requested, instead of sending the file back, the HTTP server executes it as a program and sends the output generated by the execution back to the browser for display.

The Common Gateway Interface (CGI) is a standard protocol that allows applications (called CGI programs or CGI scripts) to interact with the web server and the client. These CGI programs can be written in Python, PERL, Shell, C, or C++.

CGI Architecture Diagram

The diagram below demonstrates the architecture of CGI:

Web Server Configuration

Before you start CGI programming, ensure that your web server supports CGI and is configured to handle CGI programs. All CGI programs executed by the HTTP server must be in a pre-configured directory. This directory is called the CGI directory and is conventionally named /var/www/cgi-bin. Although CGI files are C++ executables, by convention, their extension is .cgi.

By default, the Apache web server is configured to run CGI programs in /var/www/cgi-bin. If you want to specify another directory to run CGI scripts, you can modify the following section in the httpd.conf file:

<Directory "/var/www/cgi-bin">
   AllowOverride None
   Options ExecCGI
   Order allow,deny
   Allow from all
</Directory>

&lt;Directory "/var/www/cgi-bin">
Options All
</Directory>

Here, we assume that the web server is configured and running successfully, allowing you to run any CGI program, such as Perl or Shell.

First CGI Program

Consider the following C++ program:

Example

#include <iostream>
using namespace std;

int main ()
{
   cout << "Content-type:text/html\r\n\r\n";
   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>Hello World - First CGI Program</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";
   cout << "<h2>Hello World! This is my first CGI program</h2>\n";
   cout << "</body>\n";
   cout << "</html>\n";

   return 0;
}

Compile the above code, name the executable file cplusplus.cgi, and save it in the /var/www/cgi-bin directory. Before running the CGI program, use the chmod 755 cplusplus.cgi UNIX command to modify the file mode, ensuring the file is executable. Accessing the executable file will display the following output:

Hello World! This is my first CGI program

The above C++ program is a simple program that writes its output to the STDOUT file, which is displayed on the screen. It is important to note that the first line of output Content-type:text/html\r\n\r\n is sent back to the browser and specifies the content type to be displayed in the browser window. Understanding the basic concepts of CGI is essential for writing more complex CGI programs in Python. C++ CGI programs can interact with any external system, such as RDBMS.

HTTP Headers

This is an HTTP header part, which is sent to the browser to better understand the page content. The format of HTTP header information is as follows:

HTTP Field Name: Field Content

For example:
Content-type: text/html\r\n\r\n

There are also other important HTTP headers that are frequently used in your CGI programming.

Header Description
Content-type: MIME string, defining the format of the returned file. For example, Content-type:text/html.
Expires: Date The date when the information becomes invalid. The browser uses it to determine when a page needs to be refreshed. A valid date string should be in the format 01 Jan 1998 12:00:00 GMT.
Location: URL This URL is the one that should be returned, not the requested URL. You can use it to redirect a request to any file.
Last-modified: Date The last modification date of the resource.
Content-length: N The length of the data to be returned, in bytes. The browser uses this value to indicate the estimated download time of a file.
Set-Cookie: String Sets a cookie via string.

CGI Environment Variables

All CGI programs can access the following environment variables. These variables play a very important role when writing CGI programs.

Variable Name Description
CONTENT_TYPE The data type of the content. Used when the client sends additional content to the server, such as file upload functionality.
CONTENT_LENGTH The length of the query information. Only available for POST requests.
HTTP_COOKIE Returns the set cookies in key & value pairs.
HTTP_USER_AGENT The user agent request header field, which provides information about the user who initiated the request, including the browser's name, version, and additional platform-specific information.
PATH_INFO The path of the CGI script.
QUERY_STRING The URL-encoded information sent with the GET method, including parameters after the question mark in the URL.
REMOTE_ADDR The IP address of the remote host making the request. This is useful for logging and authentication.
REMOTE_HOST The fully qualified name of the host making the request. If this information is not available, you can use REMOTE_ADDR to get the IP address.
REQUEST_METHOD The method used to make the request. The most common methods are GET and POST.
SCRIPT_FILENAME The full path of the CGI script.
SCRIPT_NAME The name of the CGI script.
SERVER_NAME The hostname or IP address of the server.
SERVER_SOFTWARE The name and version of the software running on the server.

The following CGI program lists all CGI variables.

Example

#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;

const string ENV[ 24 ] = {                 
        "COMSPEC", "DOCUMENT_ROOT", "GATEWAY_INTERFACE",   
        "HTTP_ACCEPT", "HTTP_ACCEPT_ENCODING",             
        "HTTP_ACCEPT_LANGUAGE", "HTTP_CONNECTION",         
        "HTTP_HOST", "HTTP_USER_AGENT", "PATH",            
        "QUERY_STRING", "REMOTE_ADDR", "REMOTE_PORT",      
        "REQUEST_METHOD", "REQUEST_URI", "SCRIPT_FILENAME",
        "SCRIPT_NAME", "SERVER_ADDR", "SERVER_ADMIN",      
        "SERVER_NAME","SERVER_PORT","SERVER_PROTOCOL",     
        "SERVER_SIGNATURE","SERVER_SOFTWARE" };   

int main ()
{

   cout << "Content-type:text/html\r\n\r\n";
cout << "<html>\n";
cout << "<head>\n";
cout << "<title>CGI Environment Variables</title>\n";
cout << "</head>\n";
cout << "<body>\n";
cout << "&lt;table border = \"0\" cellspacing = \"2\">";

for ( int i = 0; i < 24; i++ )
{
    cout << "<tr><td>" << ENV[ i ] << "</td><td>";
    // Attempt to retrieve the value of the environment variable
    char *value = getenv( ENV[ i ].c_str() );  
    if ( value != 0 ){
      cout << value;                                 
    }else{
      cout << "Environment variable does not exist.";
    }
    cout << "</td></tr>\n";
}
cout << "</table><\n";
cout << "</body>\n";
cout << "</html>\n";

return 0;
}

C++ CGI Library

In real-world scenarios, you need to perform many operations through a CGI program. Here is a CGI library specifically written for C++ programs, which we can download from ftp://ftp.gnu.org/gnu/cgicc/ and install following these steps:

$ tar xzf cgicc-X.X.X.tar.gz 
$ cd cgicc-X.X.X/ 
$ ./configure --prefix=/usr 
$ make
$ make install

Note: The libcgicc.so and libcgicc.a libraries will be installed in the /usr/lib directory, and you need to execute the following copy command:

$ sudo cp /usr/lib/libcgicc.* /usr/lib64/

to ensure that the CGI program can automatically find the libcgicc.so dynamic link library.

You can click C++ CGI Lib Documentation to view the related library documentation.

GET and POST Methods

You may have encountered situations where you need to pass some information from the browser to the web server, and finally to the CGI program. Typically, the browser uses two methods to pass this information to the web server, which are GET and POST methods.

Using GET Method to Pass Information

The GET method sends the encoded user information appended to the page request. The page and the encoded information are separated by the ? character, as shown below:

http://www.test.com/cgi-bin/cpp.cgi?key1=value1&key2=value2

The GET method is the default method for passing information from the browser to the web server, and it generates a very long string in the browser's address bar. Do not use the GET method when passing passwords or other sensitive information. The GET method has a size limit, with a maximum of 1024 characters in a request string.

When using the GET method, the information is passed using the QUERY_STRING http header, which can be accessed in the CGI program using the QUERY_STRING environment variable.

You can pass information by simply concatenating key-value pairs after the URL, or by using the GET method of the HTML <FORM> tag.

Simple URL Example: GET Method

Here is a simple URL that uses the GET method to pass two values to the cpp_get.cgi program.

/cgi-bin/cpp_get.cgi?first_name=ZARA&last_name=ALI

The following example generates the cpp_get.cgi CGI program, which processes the input provided by the web browser. Accessing the passed information is easy using the C++ CGI library:

Example

#include <iostream>
#include <vector>  
#include <string>  
#include <stdio.h>  
#include <stdlib.h> 

#include <cgicc/CgiDefs.h> 
#include <cgicc/Cgicc.h> 
#include <cgicc/HTTPHTMLHeader.h> 
#include <cgicc/HTMLClasses.h>  
using namespace std;
using namespace cgicc;

int main ()
{
   Cgicc formData;

   cout << "Content-type:text/html\r\n\r\n";
   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>Using GET and POST Methods</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";

   form_iterator fi = formData.getElement("first_name");  
   if( !fi->isEmpty() && fi != (*formData).end()) {  
      cout << "First Name: " << **fi << endl;  
   }else{
      cout << "No text entered for first name" << endl;  
   }
   cout << "<br/>\n";
   fi = formData.getElement("last_name");  
   if( !fi->isEmpty() && fi != (*formData).end()) {  
      cout << "Last Name: " << **fi << endl;  
   }else{
      cout << "No text entered for last name" << endl;  
   }
   cout << "<br/>\n";

   cout << "</body>\n";
   cout << "</html>\n";

   return 0;
}

Now, compile the above program as follows:

$g++ -o cpp_get.cgi cpp_get.cpp -lcgicc

This will generate cpp_get.cgi, and place it in your CGI directory and try to access it using the following link:

/cgi-bin/cpp_get.cgi?first_name=ZARA&last_name=ALI

This will produce the following result:

First Name: ZARA 
Last Name: ALI

Simple Form Example: GET Method

Here is a simple example that uses an HTML form and a submit button to pass two values. We will use the same CGI script, cpp_get.cgi, to process this input.

<form action="/cgi-bin/cpp_get.cgi" method="get">
First Name: <input type="text" name="first_name">  <br />

Last Name: <input type="text" name="last_name" />
<input type="submit" value="Submit" />
</form>

Here is the actual output of the above form, please enter the first name and last name, then click the submit button to see the result.

Passing Information Using POST Method

A more reliable way to pass information to a CGI program is the POST method. This method packages the information in exactly the same way as the GET method, but instead of sending it as a text string after a ? in the URL, it sends it as a separate message. This message is sent to the CGI script in the form of standard input.

We will use the same cpp_get.cgi script to process the POST method. Let's take the same example as above, using an HTML form and a submit button to pass two values, but this time using the POST method instead of GET, as shown below:

<form action="/cgi-bin/cpp_get.cgi" method="post">
First Name: <input type="text" name="first_name"><br />
Last Name: <input type="text" name="last_name" />

<input type="submit" value="Submit" />
</form>

Passing Checkbox Data to CGI Program

Checkboxes are used when more than one option is required to be selected.

Here is an example HTML code for a form with two checkboxes:

<form action="/cgi-bin/cpp_checkbox.cgi" 
         method="POST" 
         target="_blank">
<input type="checkbox" name="maths" value="on" /> Maths
<input type="checkbox" name="physics" value="on" /> Physics
<input type="submit" value="Select Subject" />
#include <iostream>
#include <vector>  
#include <string>  
#include <stdio.h>  
#include <stdlib.h> 

#include <cgicc/CgiDefs.h> 
#include <cgicc/Cgicc.h> 
#include <cgicc/HTTPHTMLHeader.h> 
#include <cgicc/HTMLClasses.h> 

using namespace std;
using namespace cgicc;

int main ()
{
   Cgicc formData;
   bool maths_flag, physics_flag;

   cout << "Content-type:text/html\r\n\r\n";
   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>Checkbox Data to CGI Program</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";

   maths_flag = formData.queryCheckbox("maths");
   if( maths_flag ) {  
      cout << "Maths Flag: ON " << endl;  
   }else{
      cout << "Maths Flag: OFF " << endl;  
   }
   cout << "<br/>\n";

   physics_flag = formData.queryCheckbox("physics");
   if( physics_flag ) {  
      cout << "Physics Flag: ON " << endl;  
   }else{
      cout << "Physics Flag: OFF " << endl;  
   }
   cout << "<br/>\n";
   cout << "</body>\n";
   cout << "</html>\n";

   return 0;
}

Passing Radio Button Data to CGI Program

When only one option needs to be selected, we use radio buttons.

The following HTML code example is a form with two radio buttons:

<form action="/cgi-bin/cpp_radiobutton.cgi" 
         method="post" 
         target="_blank">
<input type="radio" name="subject" value="maths" 
                                    checked="checked"/> Maths 
<input type="radio" name="subject" value="physics" /> Physics
<input type="submit" value="Select Subject" />
</form>

The following C++ program generates the cpp_radiobutton.cgi script, which processes the input given by the web browser through radio buttons.

Example

#include <iostream>
#include <vector>  
#include <string>  
#include <stdio.h>  
#include <stdlib.h> 

#include <cgicc/CgiDefs.h> 
#include <cgicc/Cgicc.h> 
#include <cgicc/HTTPHTMLHeader.h> 
#include <cgicc/HTMLClasses.h> 

using namespace std;
using namespace cgicc;

int main ()
{
   Cgicc formData;

   cout << "Content-type:text/html\r\n\r\n";
   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>Radio Button Data to CGI Program</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";

   form_iterator fi = formData.getElement("subject");  
   if( !fi->isEmpty() && fi != (*formData).end()) {  
      cout << "Subject: " << **fi << endl;  
   }else{
      cout << "No subject selected" << endl;  
   }
   cout << "<br/>\n";
   cout << "</body>\n";
   cout << "</html>\n";

   return 0;
}
form_iterator fi = formData.getElement("subject");  
if( !fi->isEmpty() && fi != (*formData).end()) {  
   cout << "Radio box selected: " << **fi << endl;  
}

cout << "<br/>\n";
cout << "</body>\n";
cout << "</html>\n";

return 0;
}

Passing Text Area Data to CGI Program

When you need to pass multi-line text to a CGI program, we use the TEXTAREA element.

The following HTML code example is a form with a TEXTAREA box:

<form action="/cgi-bin/cpp_textarea.cgi" 
         method="post" 
         target="_blank">
<textarea name="textcontent" cols="40" rows="4">
Please enter text here...
</textarea>
<input type="submit" value="Submit" />
</form>

The following C++ program generates the cpp_textarea.cgi script, which processes the input given by the web browser through the text area.

Example

#include <iostream>
#include <vector>  
#include <string>  
#include <stdio.h>  
#include <stdlib.h> 

#include <cgicc/CgiDefs.h> 
#include <cgicc/Cgicc.h> 
#include <cgicc/HTTPHTMLHeader.h> 
#include <cgicc/HTMLClasses.h> 

using namespace std;
using namespace cgicc;

int main ()
{
   Cgicc formData;

   cout << "Content-type:text/html\r\n\r\n";
   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>Passing Text Area Data to CGI Program</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";

   form_iterator fi = formData.getElement("textcontent");  
   if( !fi->isEmpty() && fi != (*formData).end()) {  
      cout << "Text Content: " << **fi << endl;  
   }else{
      cout << "No text entered" << endl;  
   }

   cout << "<br/>\n";
   cout << "</body>\n";
   cout << "</html>\n";

   return 0;
}

Passing Drop-Down Box Data to CGI Program

When there are multiple options available but only one or two can be selected, we use drop-down boxes.

The following HTML code example is a form with a drop-down box:

<form action="/cgi-bin/cpp_dropdown.cgi" 
                       method="post" target="_blank">
<select name="dropdown">
&lt;option value="Maths" selected>Math</option>
<option value="Physics">Physics</option>
</select>
<input type="submit" value="Submit"/>
</form>

The following C++ program generates the cpp_dropdown.cgi script, which processes the input given by the web browser through the drop-down box.

Example

#include <iostream>
#include <vector>  
#include <string>  
#include <stdio.h>  
#include <stdlib.h> 

#include <cgicc/CgiDefs.h> 
#include <cgicc/Cgicc.h> 
#include <cgicc/HTTPHTMLHeader.h> 
#include <cgicc/HTMLClasses.h> 

using namespace std;
using namespace cgicc;

int main ()
{
   Cgicc formData;

   cout << "Content-type:text/html\r\n\r\n";
   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>Passing Drop-Down Box Data to CGI Program</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";

   form_iterator fi = formData.getElement("dropdown");  
   if( !fi->isEmpty() && fi != (*formData).end()) {  
      cout << "Selected: " << **fi << endl;  
   }

   cout << "<br/>\n";
   cout << "</body>\n";
   cout << "</html>\n";

   return 0;
}
#include <iostream>
using namespace std;
using namespace cgicc;

int main ()
{
   Cgicc formData;

   cout << "Content-type:text/html\r\n\r\n";
   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>Passing Drop-Down Box Data to CGI Program</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";

   form_iterator fi = formData.getElement("dropdown");  
   if( !fi->isEmpty() && fi != (*formData).end()) {  
      cout << "Value Selected: " << **fi << endl;  
   }

   cout << "<br/>\n";
   cout << "</body>\n";
   cout << "</html>\n";

   return 0;
}

Using Cookies in CGI

HTTP is a stateless protocol. However, for a commercial website, it needs to maintain session information among different pages. For example, a user id is registered and remains the same for the entire session. How can we maintain the user's session information across all web pages?

In many instances, using cookies is the most efficient method for remembering and tracking preferences, purchases, commissions, and other information required for better visitor experience or site statistics.

How It Works

The server sends some data to the visitor's browser in the form of a cookie. If the browser accepts the cookie, it is stored as a plain text record on the visitor's hard drive. Now, when the visitor arrives at another page on the site, the cookie is available for retrieval. Once a cookie has been retrieved, the server can read the information stored in it.

A cookie is a plain text data record of 5 variable-length fields:

Setting Cookies

Sending cookies to the browser is very simple. These cookies are sent along with the HTTP headers before the Content-type field. Suppose you want to set UserID and Password as cookies, the steps to set cookies are as follows:

Example

#include <iostream>
using namespace std;

int main ()
{
   cout << "Set-Cookie:UserID=XYZ;\r\n";
   cout << "Set-Cookie:Password=XYZ123;\r\n";
   cout << "Set-Cookie:Domain=www.w3cschool.cc;\r\n";
   cout << "Set-Cookie:Path=/perl;\n";
   cout << "Content-type:text/html\r\n\r\n";

   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>Cookies in CGI</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";

   cout << "Setting cookies" << endl;  

   cout << "<br/>\n";
   cout << "</body>\n";
   cout << "</html>\n";

   return 0;
}

From this example, we learned how to set cookies. We use the Set-Cookie HTTP header to set cookies.

Here, some attributes of setting cookies are optional, such as Expires, Domain, and Path. It is important to note that cookies are set before the line "Content-type:text/html\r\n\r\n" is sent. Compile the above program to generate setcookies.cgi, and try setting cookies using the following link. It will set four cookies on your computer:

/cgi-bin/setcookies.cgi

Retrieving Cookies

Retrieving all set cookies is quite simple. Cookies are stored in the CGI environment variable HTTP_COOKIE, and they are in the following format:

key1=value1;key2=value2;key3=value3....

The following example demonstrates how to retrieve cookies.

Example

#include <iostream>
#include <vector>  
#include <string>  
#include <stdio.h>  
#include <stdlib.h> 

#include <cgicc/CgiDefs.h> 
#include <cgicc/Cgicc.h> 
#include <cgicc/HTTPHTMLHeader.h> 
#include <cgicc/HTMLClasses.h>

using namespace std;
using namespace cgicc;

int main ()
{
   Cgicc cgi;
   const_cookie_iterator cci;

   cout << "Content-type:text/html\r\n\r\n";
   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>Cookies in CGI</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";
   cout << "&lt;table border = \"0\" cellspacing = \"2\">";

   // Get environment variables
   const CgiEnvironment& env = cgi.getEnvironment();

   for( cci = env.getCookieList().begin();
        cci != env.getCookieList().end(); 
        ++cci )
   {
      cout << "<tr><td>" << cci->getName() << "</td><td>";
      cout << cci->getValue();                                 
      cout << "</td></tr>\n";
   }
   cout << "</table><\n";

   cout << "<br/>\n";
   cout << "</body>\n";
   cout << "</html>\n";

   return 0;
}

Now, compile the above program to generate getcookies.cgi, and try using the following link to retrieve all available cookies on your computer:

/cgi-bin/getcookies.cgi

This will produce a list showing the four cookies set in the previous section as well as any other cookies on your computer:

UserID XYZ 
Password XYZ123 
Domain www.w3cschool.cc 
Path /perl

File Upload Example

To upload a file, the HTML form must set the enctype attribute to multipart/form-data. The input tag with the file type creates a "Browse" button.

<html>
<body>
   <form enctype="multipart/form-data" 
            action="/cgi-bin/cpp_uploadfile.cgi" 
            method="post">
   <p>File: <input type="file" name="userfile" /></p>
   <p><input type="submit" value="Upload" /></p>
   </form>
</body>
</html>

This code results in the following form:

File:

Note: The above example intentionally disables saving the uploaded file on our server. You can try the above code on your own server.

Below is the script cpp_uploadfile.cpp for handling file uploads:

Example

#include <iostream>
#include <vector>  
#include <string>  
#include <stdio.h>  
#include <stdlib.h>
#include <cgicc/CgiDefs.h>
#include <cgicc/Cgicc.h>
#include <cgicc/HTTPHTMLHeader.h>
#include <cgicc/HTMLClasses.h>

using namespace std;
using namespace cgicc;

int main ()
{
   Cgicc cgi;

   cout << "Content-type:text/html\r\n\r\n";
   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>File Upload in CGI</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";

   // Get the list of files to be uploaded
   const_file_iterator file = cgi.getFile("userfile");
   if(file != cgi.getFiles().end()) {
      // Send the data type in cout
      cout << HTTPContentHeader(file->getDataType());
      // Write the content in cout
      file->writeToStream(cout);
   }
   cout << "&lt;File upload successful>\n";
   cout << "</body>\n";
   cout << "</html>\n";

   return 0;
}

The above example writes the content to the cout stream, but you can open a file stream and save the uploaded file content to a file at the target location.

❮ Cpp Increment Decrement Operators Cpp Return Pointer From Functions ❯