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";
}

______________________

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState