Perl CGI cookies - How to get and set cookies in Perl CGI programs

In Part 1 of this series, we provided some background information about cookies, discussing the problem of state maintenance in web applications. We discussed how cookies can help solve this problem, and outlined the drawbacks and limitations of cookies. We even discussed a few examples of how you might use cookies in a customizable web site or e-commerce site.

In this article, we'll dive into the heart of the matter and demonstrate Perl code you can use to set cookies from your Perl programs, and then retrieve the values of those cookies later in later programs. Along the way, we'll use the CGI.pm Perl module to accomplish this task, because it greatly simplifies the process.

Perl CGI - Setting cookie values

Using CGI.pm, creating cookies that you can store on your client's computers is very simple. Listing 1 below shows the steps necessary to create a cookie from a Perl program.

In the first step, you just create a CGI object, just as you normally would when using the CGI.pm module.

In the second step, you'll define the cookie properties by calling the cookie method. In this example, the name of the cookie is MY_COOKIE, while the value of the cookie is "BEST_COOKIE=chocolatechip". You create a cookie just like this, by specifying the name and value of the cookie when using the cookie method:

$cookie = $query->cookie(-name=>'MY_COOKIE',
    -value=>'BEST_COOKIE=chocolatechip',
    -expires=>'+4h',
    -path=>'/');

In your applications you'll probably want to create cookies with names like "SITE-ID" or "USER-ID", and then store a value in the cookie like "12345", or perhaps use something more complicated like "UID12345:NITEMS3:AGE=30". As you can see from this example, what you put in your cookie is entirely up to you.

As you can see from the documentation in the code of Listing 1, the rest of the parameters (besides the name and value) for the $query->cookie method are optional, but in many cases you'll want to set these values to gain more control over your cookies.

Once you've defined your cookie in step two of the process, just add the cookie information to the header of your HTML page in step three with this statement:

print $query->header(-cookie=>$cookie);

This statement prints the header information to your visitor's browser, and includes the information about the cookie you just created. If the browser will allow cookies to be saved to your visitors computer, the cookie information will be saved to their disk drive for later retrieval. (Note that it's possible with many current browsers to turn off, or disable, cookies. You'll need to account for this possibility in your programs, as we'll discuss shortly.)

Steps four and five in this example are trivial. In your applications, you'll perform some type of real work here, perhaps displaying a custom web page based on the User ID, or printing custom web page information for your shopping cart application.

Perl CGI - Our example Perl set cookie script

#!/bin/perl
#
#  PROGRAM:	cookie-set.cgi
#
#  PURPOSE:	Demonstrate how to SET a cookie through a Perl/CGI program
#		uisng the CGI.pm module.
#
#  Copyright DevDaily Interactive, Inc., 1998. All Rights Reserved.
#

#------------------------------#
#  1. Create a new CGI object  #
#------------------------------#

use CGI;
$query = new CGI;


#------------------------------------------------------------------------------#
#  2. Create the desired cookie using the cookie() method.
#     Do this before calling the header() method, because the cookie must be
#     incorporated into the HTTP header.
#
#  Note: Valid parameters for the cookie() call include:
#  -----------------------------------------------------
#
#	-domain		a partial or complete domain name for which the
#				cookie is valid. Like '.devdaily.com'
#				for the entire domain (www.devdaily.com,
#				smtp.devdaily.com, etc.), or 'www.devdaily.com'
#				to refer to one server.
#	-expires	(optional) The expiration date for this cookie.
#				+60s	60 seconds from now
#				+20m	20 minutes from now
#				+5h	5 hours from now
#				+1d	1 day from now
#				-3d	3 days ago
#				now	immediately
#				+6M	6 months from now
#				+1y	1 year from now
#				Monday, 28-Dec-98 12:30:00 GMT
#					expire at this specific date & time
#	-name		the name of the cookie (req'd)
#	-path		(optional) If you specify this attribute, the 
#				browser will check it against your script's URL
#				before returning the cookie.
#				The default is set to '/'.
#	-secure		(optional) The cookie will only be sent if the CGI
#				request is occurring on a secure channel.
#	-value		(req'd) The value of your cookie. This can be a 
#				scalar value, array reference, or hash
#				reference.
#------------------------------------------------------------------------------#

$cookie = $query->cookie(-name=>'MY_COOKIE',
			 -value=>'BEST_COOKIE=chocolatechip',
			 -expires=>'+4h',
			 -path=>'/');


#--------------------------------------------------------------#
#  3. Create the HTTP header and print the doctype statement.  #
#--------------------------------------------------------------#

print $query->header(-cookie=>$cookie);


#--------------------------------------------------#
#  4. Give the page a title and a simple header.   #
#     (Not really needed in this simple example.)  #
#--------------------------------------------------#

print $query->start_html('My cookie-set.cgi program');
print $query->h3('The cookie has been set');


#-------------------------#
#  5. End the HTML page.  #
#-------------------------#

print $query->end_html;

Listing 1 (above): This program demonstrates how you can create a cookie on a client's computer using Perl and the CGI.pm module.

Perl CGI - Reading the value of a cookie (get cookie)

Creating a cookie on your visitor's computer is fun, but it doesn't help too much unless you can also read it. Fortunately, reading the value of a cookie that has already been set is just as easy as setting the cookie. In fact, you use the same cookie method to retrieve the cookie value.

In Listing 2 we've taken a five-step approach to reading the value of a cookie. In the first three steps we do the things we've done in many of our CGI.pm examples: (1) create a new CGI object, (2) print the page header, and (3) start printing the output of our HTML page.

In step four of our process, we attempt to retrieve the value of the cookie with this statement:

$theCookie = $query->cookie('MY_COOKIE');

With Perl and CGI.pm, this is how you say "give me the value of the cookie named 'MY_COOKIE', and assign it to the variable named $theCookie".

If the cookie exists, it will be printed in the next statement:

print "<BLOCKQUOTE>\n";
print $theCookie;
print "</BLOCKQUOTE>\n";

In our example, the user will see this output in their browser:

BEST_COOKIE=chocolatechip

If for some reason the cookie wasn't set -- a condition for which you should always test -- the user won't see any output in their browser. In that case the BLOCKQUOTE statements will still be printed to the browser, but they won't be visible to the user unless the user decides to view the page source.

In real world applications, you'll almost always test the values of your cookies before taking any action based on their value. Other than a simple example like this, I can't imagine why you would not test the value of a cookie before using it. A slightly more sophisticated example might look like this:

if ("$theCookie") {
   print "<BLOCKQUOTE>\n";
   print $theCookie;
   print "</BLOCKQUOTE>\n";
} else {
   print "Can't find my cookie!\n";
}

Here, if $theCookie is not empty, it will be printed between the BLOCKQUOTE's; otherwise, we'll just tell the user that we can't find our cookie. (Sorry, I just returned from my holiday vacation, and that's all the sophistication I have to offer today. ;)

#!/bin/perl
#
#  PROGRAM:	cookie-get.cgi
#
#  PURPOSE:	Demonstrate how to GET a cookie through a Perl/CGI program
#		using the CGI.pm module.
#
#  Copyright DevDaily Interactive, Inc., 1998. All Rights Reserved.
#

#------------------------------#
#  1. Create a new CGI object  #
#------------------------------#

use CGI;
$query = new CGI;


#--------------------------------------------------------------#
#  2. Create the HTTP header and print the doctype statement.  #
#--------------------------------------------------------------#

print $query->header;


#----------------------------------------------------#
#  3. Start the HTML doc, and give the page a title  #
#----------------------------------------------------#

print $query->start_html('My cookie-get.cgi program');


#----------------------------------------------------------------------#
#  4. Retrieve the cookie. Do this by using the cookie method without  #
#     the -value parameter.                                            #
#----------------------------------------------------------------------#


print $query->h3('The cookie is ...');
$theCookie = $query->cookie('MY_COOKIE');

print "

    \n"; print $theCookie; print "

\n";

#-------------------------#
#  5. End the HTML page.  #
#-------------------------#

print $query->end_html;

Listing 2 (above): This program demonstrates how you can read the value of a cookie that has already been created on a visitor's computer.

Perl cookies - Final thoughts

I hope you enjoyed this two-part series about using cookies in your Perl programs with the CGI.pm module. Lincoln Stein, the creator of the CGI.pm module, has certainly made this process very easy, and he deserves much credit for it.

As you've seen, cookies can be used to help you solve the problem of state maintenance. Now, when users visit your customizable web site, or use your shopping cart application, you can keep track of who they are and what they want.

As a final note, another cool aspect of cookies is that you can obtain their value from other languages, like JavaScript. Depending on your programming prowess, you can set cookies using one language and retrieve them with another language.

Links

If you missed the first article in this series, click here to read that background information about the problem of state maintenance.