Keeping Programs Trim with CGI_Lite

This article is an introduction to a second CGI module, CGI_Lite, that is not as feature rich as CGI but is much smaller in size and therefore more efficient for use in small-scale projects.

This month, we will look at CGI_Lite, a Perl 5 module written by Shishir Gundavaram. CGI_Lite is one of several modules available for CGI programmers; the best known of the bunch is CGI.pm, written by Lincoln Stein. Indeed, I have used CGI.pm in nearly every “At the Forge” column, as well as in many programs over the last few years, on many web sites.

While CGI.pm is useful and rich in features, it is also large, weighing in at a hefty 153KB. On my Red Hat 4.2 system with 40MB of RAM, starting Perl 5 and loading CGI.pm uses about 2.7 percent of the physical memory—over 1MB—before I have even allocated any data structures. On a popular Web server, it is easy to imagine how many CGI programs running simultaneously would lead to a heavy load, both on the CPU and on the server's memory, leading to a significant slow-down.

There are a number of solutions to this problem, including using a language other than Perl for CGI programs. This month, though, we will look at another solution: CGI_Lite.pm, a module that does less than CGI.pm but is much smaller and faster. CGI_Lite.pm takes a mere 17KB on disk, and when loaded into memory along with Perl 5, takes only 2.0 percent of the physical memory on my system, about 800KB. This is still a relatively large amount of memory, but given that invoking Perl 5 uses about 560KB, it strikes me as a reasonable trade-off.

CGI_Lite.pm is not a panacea; it leaves out a number of useful features that have made their way into CGI.pm over the years. However, if your CGI programs require only a limited set of features and you would like to keep your programs as trim as possible, you might want to consider using CGI_Lite in at least some of your programs.

Getting Started with CGI_Lite.pm

Before you can use CGI_Lite, you need to get a copy from CPAN (the Comprehensive Perl Archive Network), a set of FTP and web servers that make Perl code, documentation and utilities available to the public for free. As of this writing, the latest version of CGI_Lite is 1.8, meaning that you can retrieve it from the URL http://www.perl.com/CPAN/modules/by-module/CGI/CGI_Lite-1.8.tar.gz.

If CGI_Lite has been updated by the time you read this, you might need to change the numbers in the last part of the URL. Once you have retrieved the module, you can unpack it with the command:

tar -zxvf CGI_Lite-1.8.tar.gz

which uncompresses (-z) verbosely (-v) the file (-f). This action creates CGI_Lite-1.8 on my system. Then perform the standard Perl module installation as follows:

perl Makefile.PL
make
make install
Note that you may have to be logged in as root in order to install CGI_Lite on your system.

Once the module is installed, you can use it in any program by including the line:

use CGI_Lite;

at the top of your program.

Of course, including a module is the easy part—learning how to use it can be a bit more complicated. Let's see how to use CGI_Lite.pm by creating a simple program, one which expects to receive a user's first name from an HTML form. When the form is submitted, the program prints a short personalized greeting to the user. If you are wondering why we are starting with an HTML form and the POST method, rather than the simpler GET method, stay tuned—it is harder than you might think.

Listing 1. HTML Form with Single Text Field

Listing 1 is a simple HTML form, containing a single text field called firstname, that we can use for our test. When a user clicks on the submit button in this form, the firstname text field is sent via the POST method to the program called /cgi-bin/hello.pl. Listing 2 shows one way in which we might write hello.pl using CGI_Lite.pm.

Listing 2. Initial Version of Perl Program hello.pl

In short, this program executes the following actions:

  1. Imports the CGI_Lite module.

  2. Creates an instance of CGI_Lite.

  3. Retrieves the HTML form elements into a hash, also known as an “associative array”.

  4. Uses the value of the firstname form element to return a string to the user.

Dissecting hello.pl

Now that we have gotten an overall picture of what is happening in the above program, let's look at this in greater detail, with a bit of attention to some of the differences between CGI.pm and CGI_Lite.pm.

In CGI.pm, we can retrieve form elements using the param method. When invoked in a scalar context, param allows us to retrieve the value of a single HTML form element. For example, if we have defined $query to be an instance of CGI, we can place the value of the firstname field in the $firstname variable with the following statement:

my $firstname = $query->param("firstname");

If we invoke param in an array context, then we get a list of all form elements that were submitted to the program. For example, if we want to put the names of all HTML form elements into the array @names, we can do so with the following statement:

my @names = $query->param;
We can then iterate through @names to retrieve and print the value associated with each form element, as in:
my $element = "";
    foreach $element (@names)
    {
        print "<P>$element = ",
         $query->param($element), "</P>\n";
    }
We can accomplish this with CGI_Lite.pm, but in a slightly different way. CGI_Lite.pm has a single method for retrieving form elements, one which uses hashes rather than a mixture of scalars and arrays. To retrieve form elements, we use the method parse_form_data, which returns its results in a hash. Retrieving individual form elements is thus a two-step process. First we put all of the elements into the hash, and then we retrieve the one in which we are interested:
my %FORM = parse_form_data;
my $firstname = $FORM{"firstname"};
If we want to get a list of the form elements that were sent, we can use the keys function. Thus, to put the names of the form elements in the array @names, we can type:
my @names = keys %FORM;
We can even get them in alphabetical order, by prefacing keys with a call to sort:
my @names = sort keys %FORM;
We can print the names and values of all form elements by iterating through @names and retrieving the values in which we are interested:
my $element = "";
foreach $element (@names)
{
print ",<P>$element = ", $FORM{$element},
        "</P>\n";
}

______________________

Webinar
One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Learn More

Sponsored by Bit9

Webinar
Linux Backup and Recovery Webinar

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.

Learn More

Sponsored by Storix