Valid XHTML 1.1

Firefox Download Button

Developing Web Applications with the WebApp/CGI++ Library

Carlos Moreno


Introduction

In the "classical" approach to write CGI programs, we would directly use cout statements to produce the HTML code that is dynamically generated by the CGI application.  This approach has a number of disadvantages:  the main one is the fact that the same person that is writing the CGI application (presumably a person with programming expertise) will be the person designing the web pages and writing the HTML code.  Also, the HTML code is embedded in the C++ programs (or Perl scripts, or C, etc.), which makes the program extremely hard to understand and hard to maintain.  If the visual design of the pages must be changed, then we would have to do it manually, with countless and painful modifications, making the task almost impossible.

PHP (and the like) does not do a particularly good job either.[1] With that style of scripting, the chaos occurs in the opposite sense: now the HTML contains the programs.

The WebApp/CGI++ Library aims at separating the programming and the graphical design as much as possible, providing a convenient approach to developing and maintaining complex web applications.

Intended audience

I expect that readers of this documentation (and thus, users of the WebApp/CGI++ library) are C++ programmers with at least intermediate level skills. (After all, if you were just starting with programming and wanted to do web programming, most likely you would have bitten into the hype around PHP or similar scripting languages).

However, if you do not have experience with C++ but still want to take this route, you can check out my introductory tutorials to C++ (under Notes/Tutorials on C++ Topics, in the order in which the tutorials are listed).

The CGI++ Library

As mentioned above, the WebApp/CGI++ Library provides a convenient approach, allowing you to isolate the design of the web pages from the process of writing the web applications. The key idea is the fact that most web applications respond with a pre-defined HTML document with fields that have to be dynamically generated. This allows you to design your web pages with "fill in the blank" fields that the web application will complete.

The "fill in the blank" fields are defined using empty anchor tags (we must assign a unique name to each anchor tag, so that the web application can refer to individual fields). For example, a page used to reply with a login failed message could contain the following HTML fragment:

Sorry <a name="user_name" />, the password you entered (<a name="user_password" />) is incorrect.

The web application will replace those anchor tags with the appropriate values (presumably obtained from the form where the userentered the values that were sent to the web application).

There are several ways for the user to send information (parameters) to the web application.  The most commonly used are HTML forms.  Forms can be included in an HTML document using the <form> tag. An example of a form to request user ID and password is shown below:

<form action="/cgi-bin/login.cgi" method="post">
  User Name: <input type="text" name="userID" /> <br />
  Password: <input type="password" name="passwd" /> <br />
  <input type="submit" />
</form>

In this form, the action attribute indicates what CGI application will be invoked when the user clicks on the submit button. In this case, the browser will point directly to login.cgi (on the same site, since no absolute URL is indicated) and will pass the query according to the information that the user entered. If the user enters "John Smith" as name and "C++" as password, then the query sent to the CGI application will be userID=John+Smith&passwd=C%2B%2B . Notice the URL encoding. The & character separates the different fields of the query. Spaces are replaced by a + sign, and non alphanumeric characters are replaced by an "escape sequence" consisting of a % sign followed by the code (e.g., the ASCII code) of the character in hexadecimal format.

The CGI application normally should read the query string and split it into the various parameters (separated by the & sign) and then split each parameter into two strings: the name of the parameter, and the contents. In the previous example, the first parameter's name is "userID", and the content is "John Smith";  for the second parameter the name is "passwd", and the content is "C++".

When using the CGI++ Library, you don't have to worry about these details, nor the URL-decoding (replacing the special sequences by the original character, and the + signs by spaces).  Instead, you instantiate an object of type CGI_parameters, which represents an array with all the decoded parameters.  The fragment below illustrates this:

CGI_parameters request;

    // declare variable request (of type CGI_parameters)

In the example above, the array form will contain two elements, one element, request["userID"], containing "John Smith", and one element (request["passwd"]), containing "C++".

When using this data type CGI_parameters, as well as any other facility fromthe CGI++ library, you must include the header cgi++/all, followed by the directive using namespace cgipp; (that is, unless you prefer to explicitly qualify all CGI++ keywords and functions with cgipp:::

#include <cgi++/all>
using namespace cgipp;

Actually, #including <cgi++/all> is overkill — in this case, #including <cgi++/cgi> would suffice. However, <cgi++/all> is the convenience #include that saves you from having to remember each and every one of the #includes for the various facilities. You can always #include this one with the only drawback that the compilation time will unnecessarily increase in some cases (albeit, just a small fraction of a second).

The forms shown below illustrate the example discussed in this section (username and password), showing the operation with both POST and GET methods:

Using POST method:
 
Username:
Password:
 
Using GET method:
 
Username:
Password:
 
  (notice the address bar of your browser after you click on Submit)

 

For a more complete example, showing different types of input fields (including radio buttons and check boxes) click here

Generating the HTML Document (reply)

We can declare variables that will hold the pre-made HTML contents and allow the application to fill in the blanks by replacing the anchor tags with the appropriate contents.

In the example shown above, we may have a pre-made HTML document with the reply in case the login process succeeds (i.e., the user is registered and the password supplied matches).  If this document is called welcome.html, we could use the following statement to create a variable that holds the HTML reply and allows us to complete the missing pieces:

HTMLstream reply ("welcome.html");

This creates a variable called reply, and fills its contents by reading from the file welcome.html.  Notice that in this case, the file welcome.html must be in the same directory as the executable CGI application (/cgi-bin directory).  Don't get confused:  remember that we normally place the HTML files in a separate directory;  but welcome.html is not really an HTML document (not from the web server's point of view).  It is merely a text file that the CGI application will use to read the pre-made HTML text that has to be sent back to the client's browser.

Once we create this HTMLstream variable, we can use the set_field() method to "fill in the blanks".  The set_field() method receives two parameters:  the first one is the field to be set (it must correspond to one of the anchor tags), and the second one is the value to be placed in the given field — that is, the value that will replace the anchor tag in the HTML template.

I will now show a complete version of the example presented above.  The example assumes that there is a PostgreSQL database with a table called "users" that contains two fields: the user's name and the password.

#include <cgi++/all>
using namespace cgipp;

#include <pqxx/pqxx>
using namespace pqxx;

int main()
{
    try // see note below
    {
        CGI_parameters request;

        connection conn("host=www.domain.com dbname=users");
        nontransaction users_db (conn);

            // code to check if the user exists in the database
        string sql = "select name from users where name = '" + request["userID"]
                + "' and password = '" + request["passwd"] + "'";

        result users = users_db.exec(sql);
        if (users.size() == 1)    // if we got one match
        {
            HTMLstream reply ("welcome.html");
            reply.set_field ("user_name", request["userID"]);
            reply.send();
        }
        else    // if there was no match         {
            HTMLstream reply ("login_failed.html");
            reply.set_field ("user_name", request["userID"]);
            reply.set_field ("user_password", request["passwd"]);
            reply.send();
        }

    }
    catch (const exception & e) // see note below
    {
        HTMLstream::send_error_page (e.what());
    }

    return 0;
}

The file welcome.html could contain, among other things, the following fragment:

Welcome back <a name="user_name" />, thanks for visiting our online store.

The file login_failed.html would contain a fragment similar to the following:

Login failed.  Either your user name (<a name="user_name" />) is not registered
in our database, or the password that you supplied (<a name="user_password" />)
is incorrect.

NOTE:  The sections highlighted in red in the above example make use of exceptions, a feature of C++ you may not be familiar with.  In any case, they will help you find problems with your CGI programs in some cases. All you have to do (even if you're not familiar with C++ exceptions) is to enclose all the code of your CGI applications (the ones that you create with the CGI++ Library, that is) in a "try - catch" block like the one shown in the above example  (all the code highlighted in red).

HTML Tables

The CGI++ Library allows you to dynamically create and add tables in your HTML reply.  To insert a table in an HTML reply, you create a variable to represent the table (a variable of type HTMLtable ), fill the values, and then use set_field to replace the appropriate anchor tag with the HTML code corresponding to the table.

The example below shows how to create and insert a table that contains the usernames and passwords from the users database:

#include <cgi++/all>
using namespace cgipp;

#include <pqxx/pqxx>
using namespace pqxx;

int main()
{
    try
    {
        connection conn("host=www.domain.com dbname=users");
        nontransaction users_db (conn);

        result users = users_db.exec("select * from users");

        HTMLtable pwd_table;

        for (result::size_type row = 0; row < users.size(); row++)
        {
            pwd_table.tr();    // could also be  pwd_table.add_row();
            pwd_table.td (users[row]["name"]);
                // could also be  pwd_table.add_cell (users[row]["name"]);
            pwd_table.td (users[row]["password"]);
        }

        HTMLstream reply ("pwd_listing.html");
        reply.set_field ("passwords", pwd_table);
        reply.send();
    }
    catch (const exception & e)
    {
        HTMLstream::send_error_page (e.what());
    }

    return 0;
}

Class HTMLtable also provides a method th() to add heading cells (th tags, as in <th> ... </th>) — in the above example, we could have placed the following code right before the for loop:

pwd_table.tr();
pwd_table.th ("Username");
pwd_table.th ("Password");

This example assumes that a "template" HTML page called pwd_listing.html exists, with an anchor tag named "passwords"  (in the position where we want the table).

The declaration of the HTMLtable may optionally include an initializer;  a string containing the table attributes, as shown in the following example:

HTMLtable table ("width=\"600\" border=\"1\"" cellpadding=\"5\"");

Also, the tr() and td() (or add_row() and add_cell()) may optionally include a parameter containing the row or cell attributes, as shown in the following example:

table.tr ("valign=\"top\"");
table.td ("Cell data", "align=\"center\"");

Images and other HTML tags

The CGI++ Library provides a convenient tool to include images and several other tags that are dynamically generated — for instance, if you have an image for which the file name and some of the attributes (such as width and height, or the title, or alternate text) is obtained from a database, it would be inconvenient to put the image tag as part of the HTML template with several anchor tags in it. Also, if the image is part of the contents of a dynamically generated table, then generating the image tag "manually" (e.g., with string concatenation) is very inconvenient.

HTMLimg can be used in these situations;  it generates the HTML code for the image tag, given the parameters.  The example below illustrates its use:

    HTMLimg img("image.jpg");

Alternatively, if we know the width and height and we want to set those image attributes, we could declare it directly as:

    HTMLimg img("image.jpg", 300, 200);

The above creates an image tag with the following content:

    <img src="image.jpg" width="300" height="200" />

In the declaration/initialization statement, we can only specify the image file name, the width, and the height. If we want to set other attributes, we can do it with the set method, as shown below:

HTMLimg img("image.jpg", 300, 200);
img.set ("title", "Image 1");
img.set ("border", "0");

The above example would produce an image tag with the content shown below:

<img src="image.jpg" width="300" height="200" title="Image 1" border="0" />

The img object (variable) can be used directly with a set_field to "fill-in a blank" of an HTML template, or with a td method to put it directly inside a table cell, or we could simply use its str method to obtain a string with the tag's content:

HTMLimg img("image.jpg", 300, 200);
HTMLtable table;
table.tr();
table.td ("Some title");
table.td (img);

The above fragment would produce a table with the following content:

<table>
  <tr>
    <td>Some title</td><td><img src="image.jpg" width="300" height="200" /></td>
  </tr>
</table>

Class HTMLimg also includes methods set_width(), set_height(), and set_size() — the latter receives parameters width, height (in that order)
 

Other tags that can be generated dynamically (that is, without having to assemble the string with HTML code in the program) are: anchor tags with href attribute (informally speaking, hyperlink tags), div, span, strong, em, and pre.

In all cases, like with HTMLimg, you can use the method set() to specify the attributes. Each of the specific tags may include methods that are specific to the particular tag (as, for example, HTMLimg includes methods set_width() and set_height()), as well as specific set of parameters in the constructor (initialization).

The fragment of code shown below illustrates the use of these classes (in the examples, it is assumed that reply refers to a previously-declared HTMLstream object, and table referes to a previously-declared HTMLtable object):

HTMLhref doc_link ("Click here to see documentation");
    // This one is an enclosing tag (i.e., it has an opening
    // and a closing tag, enclosing some text) in these cases,
    // initialization is done with the enclosed text


doc_link.set_href ("documentation.html");
reply.set_field ("link", doc_link);
    // This one would produce a fragment of HTML code
    // as follows: <a href="documentation.html">Click here to see documentation</a>


HTMLdiv div (" .... .... ", "some_css_class");
reply.set_field (div); // or, table.td (div); ... etc.
    // This one would produce a fragment of HTML code
    // as follows: <div class="some_css_class"> .... .... </div>


    // HTMLspan works identical to HTMLdiv

    // In all cases, it's not really necessary to create an
    // object (a variable) and use it later; you can also
    // create the object "on-the-fly" and use it directly,
    // as illustrated below:


table.tr();
table.td (HTMLstrong("some bold text"));
    // As opposed to:
    //HTMLstrong bold_text("some bold text");
    //table.td (bold_text);


table.td (HTMLem("some italics text"));
    // Needless to say, these two examples above produce
    // table cells including <strong>-enclosed text and
    // <em>-enclosed text, respectively

Populating Select Fields (pull-down lists)

You can place empty select fields in your HTML template, and fill it dynamically, using HTMLstream facility add_option.  This method receives four parameters — the last two being optional.  The parameters are:  the name of the select field (as it appears in the HTML template), the option to be added (a string with the item as it is going to be displayed), a string with the value attribute (i.e., what will be sent when submitting the form), and a boolean flag indicating if the option is selected by default (if omitted, false is assumed).

The following example fills a select field named department with the values stored in two vectors, dept_ids, and dept_names (presumably coming from a database table).  In the example, the variable id contains the value of the ID of the department that should be initially selected when displaying the HTML reply page.

Notice that the department names is what will be shown to the user, but the department ID is what will be sent when the user presses the submit button.

vector<string> dept_ids;
vector<string> dept_names;

    // ... read dept_ids and dept_names from the database

HTMLstream reply ("employee_info.html");
for (int i = 0; i < dept_ids.size(); i++)    // assume equal sizes
{
    if (dept_ids[i] == id)
    {
        reply.add_option ("department", dept_names[i], dept_ids[i], true);
    }
    else
    {
        reply.add_option ("department", dept_names[i], dept_ids[i]);
    }

    // could have been simply:
    // reply.add_option ("department", dept_names[i], dept_ids[i], dept_ids[i] == id);

}

The effect of the above code  (assuming, for example, that the vectors contain three elements each, with values "DPT1", "DPT2", "DPT3" for the IDs and "Development", "Quality Assurance", Sales" for the names;  and assuming that the variable id contains the value "DPT2") would be the following:  if the HTML template employee_info.html contains the following fragment:

<select name="department">
</select>

Then it would be transformed into:

<select name="department">
  <option value="DPT1">Development</option>
  <option value="DPT2" selected>Quality Assurance</option>
  <option value="DPT3">Sales</option>
</select>
Firefox Download Button

Session-aware Web Applications — Web_app

The CGI++ library provides a mechanism that greatly simplifies dealing with sessions. This is achieved through the use of cookies, either as a behind-the-scenes detail, or explicitly manipulating cookies

A cookie is a client-side mechanism that allows the server to store information onthe browser's machine, and retrieve it at a later time (this is a rather simplified definition of cookies).

Suppose you use a Web application to allow users to login (i.e., your application validates user and password to either grant or refuse access). Ok, then what? Your application finishes, and all the information is gone. How will your other CGI applications know at a later time that the request comes from the same "session" (the same user, or more specifically, the same browser) that successfully logged in a few seconds or a few minutes ago?

The problem described in the example above could be solved using cookies, by storing a cookie that identifies the user. Whenever the user (the same browser) requests any other document or CGI from the same server, the values of the cookies will be sent, and the server will know which user it is.

But we have to be careful: cookies may open a "back door" that could compromise the security and privacy of the client's information. For instance, in the previous example, we could store the username and password in two different cookies in the client's machine. But remember that cookies can be viewed from the browser. If some user logs in to your site from a publicly available computer (e.g., a "cyber-cafe"), someone could later view the values of the cookies and see private information (passwords) from other people. Even with our own home computer — kids or friends could have access to our computer and view information they're not supposed to see.

A better solution in this example would be the following: when the server needs to start a session, it generates a unique, random sequence of characters (a "key"), and stores it locally, in a file or database; that unique key is then sent as the value of a cookie to the client's machine. That key will be a weird random sequence of characters, so there will be no problem with anyone else seeing it. But because the server is keeping record of that key, no other person from another browser will be able to connect and pretend they're a different user from a different session — the server should clean up those keys, or somehow embed information to make sure that the key expires after a certain amount of time. Thus, if someone reads that key from someone else's machine and then, a few hours or days later tries to use it, it won't be valid, because the server already removed that key, when it expired.

So, how do we do that with the CGI++ Library?

The CGI++ Library provides a very convenient way to deal with Web Applications requiring sessions — Server_data, part of the Web_app facility, deals with storing data on the server and keeping track of the session to retrieve this data at a later time (only if the request comes from the same web browser); the interesting detail being that it is all done as a behind-the-scenes detail, complately transparent for the programmer!

The idea with this Web_app facility is that it allows us to design a web application as a whole, as if it was one master/global class representing the whole application, and each CGI being one method of such web application class. Server_data can be seen as the tool that provides data member definitions for this web application class, and as such, all methods (all CGIs that are part of this global class) have access to them

Each session would be seen as an object, or an instantiation of this class — only CGIs running as part of a given session will have access to the data saved by other CGIs corresponding to the same session, in the same way that an object of a class does not have access to the data members of other objects of the same class.

Class Web_app provides the basic/generic functionality, and we in general derive (inherit) from this class to create our specific web application class. For example, if we want to create an online system for, say, students in a College to manage their personal information, courses, grades, etc., we could think of this system as a single object of a class named Students_poa (poa stands for Personal Online Assistant)

This class would have several methods: for example, a login method, implemented through a CGI application that receives and verifies the student's data, and grants access by setting some data member — we recall that data members will be transparently stored on the server, and recovered for use of any other methods of the same object (the same session), such as a method update_student_data, implemented through another CGI that needs to verify that a successful login has taken place for the same student for which the information is being updated. The data member used to flag the login condition could be simply the student ID: if the data member is empty, then no login has taken place, and if not, then we know that a successful login for the student with this ID has taken place, initiating a session, or equivalently, instantiating a new object of class Students_poa corresponding to this student's session

The fragment below shows the definition of class Students_poa, presumably done in a file students_poa.h:

#ifndef STUDENTS_POA_H
#define STUDENTS_POA_H

#include <cgi++/web_app>
    // Could place a using cgipp::Web_app or using namespace cgipp;
    // to avoid using cgipp::Web_app below


class Students_poa : public cgipp::Web_app
{
    // Typically, you will want to put just a few protected members:

protected:
        // Almost unconditionally, you will want to override the following two:
    string application_uuid() const
    {
        return "studentspoa200902011650";
            // Must be changed whenever you change the structure of the
            // data stored on the server (i.e., whenever you add, remove, or
            // modify any Server_data definition)

            // Using a prefix followed by date/time seems convenient enough

    }

    string session_cookie_name() const
    {
        return "studentspoa";
            // This is the name of the cookie (which will contain the session ID,
            // that long weird random sequence of characters) that will be visible
            // on the browser --- you will want to put something meaningful, but
            // in no way anything including any secret information about the server.

    }

        // Optionally, you may want to customize error pages
        // by overriding the "on_exception" methods:

    void on_cgipp_exception (const cgipp::cgipp_exception & e)
    {
        // Produce some HTML output (e.g., using HTMLstream) and
        // possibly post a log entry based on information carried by e

    }

    void on_session_expired (const cgipp::session_expired & e)
    {
        // Same as above
    }

        // You may (want to) override the following:
    int session_timeout() const // In seconds
    {
        return 10*60;    // 10 minutes, override default from Web_app
    }

        // And of course, any data members (server data) that you may need:

    Server_data<string> d_student_ID;
        // or Server_data<int>, etc., depending on what information needs to be kept track of
};

#endif

With this definition, we now create methods of class Students_poa (CGI applications) by creating a class representing the particular CGI application, overriding the on_execute method, and instantiating an object of this class and calling its execute method, as shown in the example below, the login method for class Students_poa, presumably defined in a file student_login.c++:

#include "students_poa.h"

class Login : public Students_poa
{
private:
    void on_execute();
};

int main()
{
    Login login;
    login.execute();

    return 0;
}

void Login::on_execute()
{
    const string & username = request["username"];
    const string & password = request["password"];
        // Class Web_app makes the request data directly available through the member request
        // (in this case, it is assumed that the form has a fields named username and password)


    // Verify the data (presumably through SQL), and if the login is accepted,
    // read any related data (such as student ID corresponding to this user/pwd)
    // and save it:


    d_student_ID = read_database("student_ID");
        // This is just a simplified example --- read_database is supposed to
        // retrieve this info from the database (you will use whatever sequence
        // of code you may require to get such data after having done the validation)

        // Or, if the login failed, then do not set d_student_ID, and produce some
        // HTML output indicating the error condition (with a try again form, etc.)

}

To give a more complete view of this example, the fragment below shows part of the method update_student_data, implemented through another CGI application that will access the data member (server data) d_student_ID to verify:

#include "students_poa.h"

class Update_data : public Students_poa
{
private:
    void on_execute();
};

int main()
{
    Update_data update;
    update.execute();

    return 0;
}

void Update_data::on_execute()
{
    const string & student_ID = d_student_ID;
        // It could be a good idea to do this before any processing, since
        // this causes an invalid_session exception to be thrown (sooner rather
        // than later) if the session has not been initiated

    // ... Do any required processing, reading request[" ... "] for all the fields
    // that this action requires --- the verification that the student_ID is the
    // one for the data being saved is implicit (by the data member d_student_ID);
    // if a stricter validation is required, you would use additional data in the
    // form that invokes this CGI (e.g., you could prompt again for the password,
    // and validate that it matches the student stored in d_student_ID)

Explicitly using Cookies to implement sessions

In situations where for some reason we want or need to explicitly deal with cookies to implement the session functionality, we do so by using the Cookies and set_cookie() facilities from the CGI++ Library. Cookies works very similar to the way CGI_parameters works to get the HTML form parameters:

Cookies cookies;
    // Now get the values from specific cookies:

string user_id = cookies["user_id"];

Remember that the browser sends automatically the cookies that were created by the same server. The cookie in the fragment of code above was presumably created by a previous CGI application, with a fragment similar to the following:

HTMLstream reply ("user_logged_in.html");
reply.set_field (" .... ", form[" ... "]);

// ...

reply.set_cookie ("user_id", form["user_id"]);
reply.send();

When the reply is sent and received by the browser, it [the browser] will set up a cookie called "user_id", whose value is the value of form["user_id"] (presumably what the user had indicated when filling the HTML form in the previous page).

Set_cookie may optionally receive extra parameters to indicate the server to which the cookie belongs, the path in which they would be valid, and the expiration date, as indicated below:

reply.set_cookie ("user_id", form["user_id"],
                  "/cgi-bin",
                  "www.mochima.com",
                  "Monday, 20-Jan-2003 23:59:59 GMT");
    // The parameters are: cookie name, value, path, domain, expiration

The expiration date can be conveniently obtained using the CGI++ Library's function cookie_exp_date. The function receives the number of days the cookie will be valid (i.e., expiration date will be "now" plus the specified number of days). It optionally takes three extra parameters: hours, minutes, and seconds, as shown in the examples below:

reply.set_cookie ("user_id", form["user_id"],
                  "/cgi-bin", "www.mochima.com", cookie_exp_date (30));
    // Expires 30 days from now

reply.set_cookie ("user_id", form["user_id"],
                  "/cgi-bin", "www.mochima.com", cookie_exp_date (1,12));
    // Expires a day and a half from now (1 day + 12 hours)

reply.set_cookie ("user_id", form["user_id"],
                  "/cgi-bin", "www.mochima.com", cookie_exp_date (0,0,1,30));
    // Expires a minute and a half from now (0 days + 0 hours + 1 minute + 30 seconds)

By default (if those extra parameters are omitted, as in the first example above), the cookie is sent only to the same server, and it expires when the browser is closed. This is particularly useful when we want to keep track of a session, since it has the advantage of keeping a certain level of privacy for any information you store in cookies (since the cookies disappear as soon as they close the browser). Naturally, it would not be useful for user identification purposes (e.g., web sites that you visit and address you by name).

A Note on Cookies and Hidden Fields

In some cases, the use of cookies may not be necessary.  In particular, if we only want to send some non-editable information from one CGI to the next (i.e., the result of one CGI has to embed in the HTML reply some information to be sent to the next CGI, without giving the user the choice of modifying the information), we may use hidden fields instead.  

A hidden field is simply an input field inside a form, that is not shown to the user — and thus, the user can not modify the value.  Because it is an input field, it is sent when the user submits the form.  The contents is indicated with the value attribute.  An example of a hidden field may look like:

<form action="/cgi-bin/example.cgi" method="post">
  <input type="hidden" name="hidden_code" value="contents of the hidden field" />
  <input type="submit" value=" Go " />
</form>

The value of the field is sent, as if it were a text field, or a password field.  The difference is that the field is not displayed, and thus the user can not modify it.

Notice that the idea of a hidden field is not to "keep secrets" from the user:  the hidden field is not secret at all!  (you can view the contents by selecting "View Source" in your browser).  It is simply a mechanism to pass information that the user doesn't want or doesn't need to see.

An example of use of hidden fields is the results of a search page.  Suppose an initial page allows users to search books (or any other product) in an online store.  You want to send a reply that contains a list of the matches, showing just the title, with a button next to it to view the details.  Well, you could do that with one form per item in the list.  Inside the form, you put the title (and maybe the author) of the book, and a hidden field with the ID of the book, such that when the user presses the submit (view) button, the CGI receiving the request will receive the ID of the book.

The CGI++ library does not provide any specific facilities to handle hidden fields, but you can put an anchor tag and use set_field to fill-in whatever information you need to pass.  For example, you would implement the above (the book ID example) with a template that contains the following fragment:

<form action="/cgi-bin/example.cgi" method="post">
  <input type="hidden" name="bookID" value="<a name='bookID' />" />
  <input type="submit" value=" Go " />
</form>

(notice the single-quote, to avoid complaints from your HTML editor, who might think that the tag is broken if you use double quotes — it will think that the opening double quote for the anchor tag isthe one that closes the value attribute)

The code (the CGI program) would contain the following statements:

string book_id = .... ;

HTMLstream reply ( ... );

// ...
reply.set_field ("bookID", book_id);

Multi-value Input Fields

The CGI++ Library mechanism for reading data from forms includes multi-value fields (such as a select input field with the multiple attribute, or multiple checkboxes with the same name).

Access to these parameters, however, can only be done through iterators. Class CGI_parameters provides a const_iterator type that allows client code to iterate over all the parameters, reading them as pairs name and value, as shown in the example below:

CGI_parameters request;

for (CGI_parameters::const_iterator param = request.begin();
                                    param != request.end();
                                    ++param)
{
    // Now dereference the iterator to obtain the information:
    // param->name() and param->value() give you name and value

}

If we want to iterate over a multi-value field for which we know the name (for instance, a select input field called hobbies tha allows selection of multiple items), we would still use a const_iterator, but now, begin() and end() are invoked with a parameter, indicating the field with the multiple values that we want to iterate over, as illustrated in the example below:

CGI_parameters request;

for (CGI_parameters::const_iterator param = request.begin("hobbies");
                                    param != request.end("hobbies");
                                    ++param)
{
    // Now dereference the iterator to obtain the values
    // Notice that we can dereference directly with * to
    // obtain the value, since it is implicit that for all
    // of the elements iterated over, the name of the
    // parameter is "hobbies":

    // *param gives you the value of the parameter.

    // We can still use param->value(), and even param->name(),
    // except that it's not really necessary.

}

    // We could obtain a single string with all the items
    // concatenated (by default separated by a space, or by a
    // string specified via the method separator()) with:


request.separator(" -- ");
const string items = request["hobbies"];
    // Could return a srting containing music -- sports -- photography -- skiing

If necessary, we could use CGI_parameters' method count() to determine the number of parameters. If count() is given an argument, then it would return the number of parameters with that name:

const int num_parameters = request.count();
const int num_hobbies = request.count("hobbies");

A Few Extra Facilities

Aditionally to the HTMLstream and the facilities related to form parameters reading and decoding, there are a many other facilities in several areas:

  • General tools:
    • String manipulation (trimming, case-conversion for various character encodings)
    • Current date and time
    • Sending e-mail
    • Environment information (such as remote IP or browser)
  • Encoding (hex and base-64 encoding and decoding)
  • Filtering/Sanitizing for security purposes (SQL injection and cross-site scripting counter-measures)
  • Cryptography:
    • Cryptographic-quality random string generation (based on /dev/urandom)
    • Cryptographic hashes (SHA-256, SHA-384, SHA-512 plus the highly non-recommended MD5, SHA-1, and also SHA-224)
    • Public-key cryptography and Digital signatures (RSA only)
    • Symmetric-key encryption (AES and the non-recommended Triple-DES)
  • Access to remote documents (by URL)
     

Examples of use of these are shown below. For more detailed information, you can inspect the header files, installed by default in the directory /usr/include/cgi++ (files tools, cgi, encodings, case, crypto, and url):

// General tools:

cout << upper(lastname) << ", " << lower(firstname) << endl;
    // If we have a string with a non-ASCII character encoding
    // (for instance, iso-8859-1, or latin1), we could do:
    // upper<iso88591>(name), or, equivalently, upper<latin1>(name)


cout << trim(str) << endl;
    // trim leading and trailing spaces --- ltrim and rtrim
    // to trim on the left (leading) or on the right (trailing),
    // respectively


    cout << current_date() << ", " << current_time() << endl;
    // could output: 2008-01-22, 17:15:23

string amount_due = currency_str (invoice_total);

send_e_mail ("user@domain.com",                              // Destination (To:)
             "Automated reply <orders@online_store.com>",    // Sender (From:)
             "Order confirmation",                           // Subject
             "Dear customer,\n\n"                            // Body of the message
             "Your order at Online Store Inc. for a total of $" + amount_due +
             "\nhas been accepted, and will be shipped soon\n\n"
             "Thank you for shopping with us!");

const string browser = http_user_agent();

const string remote_ip = remote_addr();

You can optionally include two extra parameters to send_e_mail:  one, a vector of strings, with the list of CC's, and a second (optional as well), a vector of strings, with the list of BCC's.

Sample code for cryptographic features (including random strings generation):

#include <cgi++/crypto>
#include <cgi++/encodings>
using namespace cgipp;

// ...

    // Public-key cryptography:

RSA_private_key privkey ("key_file.key");
RSA_public_key pubkey ("public_key_file.key");

Ciphertext cipher = pubkey.encrypt ("Hello there!");
cout << "Ciphertext: " << hex_encoded(cipher) << endl;

cout << "Decrypted: " << privkey.decrypt (ciphertext) << endl;

    // Files generated (e.g.) with OpenSSL's command-line tool:
    // Private key: openssl genrsa -out key_file.key 2048
    // Public key: openssl rsa -pubout -in key_file.key -out public_key_file.key

    // Hash functions:


string hash = sha256 ("Some text to be hashed");
    // or sha512, or sha1, or md5 (sha1 and md5 not recommended)

    // Random number generation (cryptographic quality):


string rnd_id = ascii_random_string (30);
    // random string of 30 characters
    // ascii_ to generate alphanumeric characters only

    // Demo for symmetric-key encryption coming later (though in
    // web applications, public-key tends to be more useful, but
    // still).
Firefox Download Button

Downloading and Installing the WebApp/CGI++

Before using the CGI++ Library, you have to download it and install it to your system.  This requires that you have superuser (root) access to your system, as the installation process copies files to the system directories (/usr/include and /usr/lib, among others).

In addition to the obvious requirements (like C++ compiler and related packages), the following packages are required:

  • OpenSSL development packages version 0.9.8 or later (sudo apt-get install libssl-dev on Ubuntu/Debian, yum install openssl-devel — executed as root — on Fedora/RedHat/CentOS)
  • CURL development packages (sudo apt-get install libcurl3-dev on Ubuntu/Debian, yum install curl-devel on Fedora/RedHat/CentOS)

The CGI++ Library may be downloaded from http://www.mochima.com/downloads/cgi++.tgz .  Once downloaded and saved to a (temporary) directory, follow the steps shown below:

On Ubuntu/Debian:

[...user]$ tar xvzf cgi++.tgz
[...user]$ cd cgi++
[...user]$ sudo make

On Fedora/Redhat/CentOS:

[...user]$ tar xvzf cgi++.tgz
[...user]$ cd cgi++
[...user]$ su -
      <Enter root password>
      cd to the directory where the files were extracted
[...user]# make
[...user]# exit
 

Compiling your Applications

After installation is complete (assuming you didn't get any error messages), you compile your applications as follows:

[...user]$ c++ -o login.cgi login.cpp -lcgi++

Footnotes

  1. Actually, PHP and the like do a much better job than “classical” CGI applications; just not good enough, from the point of view of separating logic from display.   
  Firefox Download Button