How to build a C/C++ web application using CGI C++ library for Debian Linux deployment

C/C++ means performance. If you are already a C/C++ programmer you may want to leverage your expertise to build a speedy website. If you are just learning C++, visit this link for additional resource. The goal of this blog is to demonstrate how to build a C++-CGI based web application. This is Part 1 of a multipart C++/cgi blog series.

Our environment

Our server is Debian Linux 6 running Apache2. We use libcgicc as our CGI C++ library.

Configure apache2 for our c++ web application


    Alias /cpp-cgi/ "/opt/cpp-cgi/"
    <Directory "/opt/cpp-cgi/">
        AllowOverride None
        AddHandler cgi-script .cgi
        Options +ExecCGI 
    </Directory>

Insert the above directive to any of your existing virtual hosts. Our application directory is in /opt/cpp-cgi/. In Debian 6, apache2 configuration files are located in /etc/apache2/site-available.

This setup would allow us to execute static HTML content as well as C++/cgi programs and other cgi based scripts. We use cgi extension (AddHandler cgi-script .cgi) for our executable cgi files. You can make up any extension desired. Use ScriptAlias instead of Alias if you want to run just cgi programs/scripts in this directory.

Update apache2.

   # check your setup just in case you have mistyped something
   apache2ctl -t
   # Now reload if all are OK
   /etc/init.d/apache2 reload
    

Install cgicc and other build tools

  
  # update Debian repositories
  apt-get update
  # install
  apt-get install build-essential libcgicc5 libcgicc5-dev libcgicc-doc

The above will install all the necessary build tools including c++/g++. In Debian 6, libcgcc in installed in standard directories which are /usr/lib and /usr/include.

The C++ code

For this demonstration, we use JQuery plugin Slimbox2 for our content. Please refer to inline comments for some explanation of the code.


#include "cgicc/CgiDefs.h"
#include "cgicc/Cgicc.h"
#include "cgicc/HTTPHTMLHeader.h"
#include "cgicc/HTMLClasses.h"

#include <iostream>
#include <vector>
#include <string>

using namespace std;
using namespace cgicc;

int main (int argc, char **argv) {

  try {

     // contants used below
     const string apptitle="Demo Cgi/C++ Web Application";
     const string description = 
        "Part 1 - Cgi/C++ Web Application Introduction";
     const string jquery=
        "http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"; 
     const string slimboxjs="./js/js/slimbox2.js"; 
     const string slimboxcss ="./js/css/slimbox2.css"; 
     const string sample_img= 
         "http://kahimyang.info/resources/mariano.jpg";

     // Generates text/html mimeType
     cout << HTTPHTMLHeader ();

     // Generates doctype declaration using strict.dtd
     cout << HTMLDoctype(HTMLDoctype::eStrict);

     cout << html().set ("xmlns","http://www.w3.org/1999/xhtml");
     
     // open head tag
     cout << head() << title (apptitle);
     cout << meta().set ("name","robots").
          set("content","ALL");
     cout << meta().set ("name","language").
          set("content","English");
     cout << meta().set ("name","description").
          set("content",description);
     
     cout << script ().set ("type","text/javascript").
          set ("src",jquery) << script(); 
     cout << script ().set ("type","text/javascript").
          set ("src",slimboxjs) << script();
    
     cout << cgicc::link ().set("tyle","text/css").set("rel","stylesheet").
          set ("href","layout.css");
     cout << cgicc::link ().set("tyle","text/css").set("rel","stylesheet").
          set ("href",slimboxcss);

     // close head tag
     cout << head (); 
     
     // open body tag	
     cout << body() << endl;   
     
     cout << cgicc::div().set ("id","container");

     // atomic don't need to be explicitly closed
     cout << h1 (description); 
     
     // image inside an anchor tag and our Slimbox lightbox
     cout << a(img().set("src",sample_img)).set ("href",sample_img).
          set("rel","lightbox");
     
     cout << h2 ("Click on image to enlarge");

     cout << cgicc::div ();

     // close body tag
     cout << body();   

     cout << html();
     cout << endl;
     

  }
  catch (...) {
    // All exceptions
  }

  return 0;
}

cgicc html classes are either atomic or non atomic. Atomic classes do not have on/off state. The meta class (for example) need not be paired with another meta() call. A closing "/>" is appended by the library. Non atomic classes like div() must be paired with another div() call to close the tag.

There are cases where cgicc classes clashes with other library classes/functions used in your project. In this case you need to qualify the class with the cgicc namespace as used above (cgicc::link).

To learn more about libcgicc visit the library documentation here.

The above file is named main.cpp. The command below will build the executable with libcgicc statically linked.


    g++ -o main.cgi main.cpp /usr/lib/libcgicc.a
    

If your project becomes bigger a Makefile would make managing your project a lot easier. If you are using a Linux desktop, use Netbeans or Eclipse for better control of your project.

Output of this demo can be found here http://demo.kahimyang.info/cgi-cpp/cpp/main.cgi.

That's it. Good luck.

If you like the article, please share.
(Site URL pattern has changed as a result social actions counter was reset.)



Comment icon   Comments (Newest first)