Using Cookies without CGI.pm

Top Japanese page




Overview

Set or read Cookie without using CGI.pm. When you want to use CGI.pm, refer to Using Cookies with CGI.pm.

Flow

  1. Encode the character to be stored in the Cookie
  2. Make expiration date to match the cookie format
  3. Issue a cookie
  4. Output http header of the cookie
  5. When read, read $ENV{HTTP_COOKIE}
  6. Decode the input value

A sample code

 my $text = 'Cookie example';
 
 #Cookie setting
 my $cook = &cookie_encode($text);
 my $date_gmt = &cookdate(1);
 
 print "Set-Cookie: mycookie=$cook; expires=$date_gmt\n";
 print "Content-Type: text/html\n\n";
 
 #Cookie read
 my $readcookie = $ENV{'HTTP_COOKIE'};
 $readcookie = &cookie_decode($readcookie);
 
 sub cookie_encode {
     my $a = shift;
     $a =~ s/([\W])/sprintf("%%%02X", ord($1))/eg;
     return $a;
 }
 
 sub cookdate {
     my $expire = shift;
 
     my ($secg,$ming,$hourg,$mdayg,$mong,$yearg,$wdayg,$ydayg,$isdstg) = 
        gmtime(time + $expire * 86400);
    
     $yearg = $yearg + 1900;
     
     if ($yearg < 10)  { $yearg = "0$yearg"; }
     if ($secg < 10)   { $secg  = "0$secg";  }
     if ($ming < 10)   { $ming  = "0$ming";  }
     if ($hourg < 10)  { $hourg = "0$hourg"; }
     if ($mdayg < 10)  { $mdayg = "0$mdayg"; }
     
     my $youbi = ('Sunday', 'Monday', 'Tuesday', 'Wednesday',
                 'Thursday', 'Friday', 'Saturday') [$wdayg];
     
     my $month = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul',
                 'Aug', 'Sep', 'Oct', 'Nov', 'Dec') [$mong];
     
     my $date_gmt = "$youbi, $mdayg\-$month\-$yearg $hourg:$ming:$secg GMT";
     
     return($date_gmt);
 }
 
 sub cookie_decode {
     my $a = shift;
     $a =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("C", hex($1))/eg;
     return $a;
 }

Description of the code

 my $text = 'Cookie example';

In this example, save 'Cookie example' into cookie.

 #Cookie setting
 my $cook = &cookie_encode($text);

Do an URI encode of the input text. Unless doing this, Japanese character will be broken. With Apache 1.3, it works without doing this.

 my $date_gmt = &cookdate(1);

Make a date form to be used by cookie header.

 print "Set-Cookie: mycookie=$cook; expires=$date_gmt\n";

Issue a cookie. In this example, the cookie name is mycookie. At this point, the process hasn't been completed yet. It must issue Content-Type header.

 print "Content-Type: text/html\n\n";

Issue the http header. The other header could be inserted in between cookie and Content-Type.

 #Cookie raed
 my $readcookie = $ENV{'HTTP_COOKIE'};

Read the cookie.

 $readcookie = &cookie_decode($readcookie);

Decode the read cookie. The cookie is in $readcookie.

 sub cookie_encode {
     my $a = shift;
     $a =~ s/([\W])/sprintf("%%%02X", ord($1))/eg;
     return $a;
 }

URI encode routine.

 sub cookdate {
     my $expire = shift;
 
     my ($secg,$ming,$hourg,$mdayg,$mong,$yearg,$wdayg,$ydayg,$isdstg) = 
        gmtime(time + $expire * 86400);
    
     $yearg = $yearg + 1900;
     
     if ($yearg < 10)  { $yearg = "0$yearg"; }
     if ($secg < 10)   { $secg  = "0$secg";  }
     if ($ming < 10)   { $ming  = "0$ming";  }
     if ($hourg < 10)  { $hourg = "0$hourg"; }
     if ($mdayg < 10)  { $mdayg = "0$mdayg"; }
     
     my $youbi = ('Sunday', 'Monday', 'Tuesday', 'Wednesday',
                 'Thursday', 'Friday', 'Saturday') [$wdayg];
     
     my $month = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul',
                 'Aug', 'Sep', 'Oct', 'Nov', 'Dec') [$mong];
     
     my $date_gmt = "$youbi, $mdayg\-$month\-$yearg $hourg:$ming:$secg GMT";
     
     return($date_gmt);
 }

Expiratoin data generation routine.

 Thursday, 18-Jan-2007 06:53:17 GMT

The output will be as above.

 sub cookie_decode {
     my $a = shift;
     $a =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("C", hex($1))/eg;
     return $a;
 }

Decode routine.