cvsuser 02/11/01 11:57:35 Modified: App-Context/lib/App/Session Cookie.pm Log: got cookie sessioning back on its feet, including padding Base64 data to avoid a warning Revision Changes Path 1.4 +42 -10 p5ee/App-Context/lib/App/Session/Cookie.pm Index: Cookie.pm =================================================================== RCS file: /cvs/public/p5ee/App-Context/lib/App/Session/Cookie.pm,v retrieving revision 1.3 retrieving revision 1.4 diff -u -w -r1.3 -r1.4 --- Cookie.pm 15 Oct 2002 21:58:49 -0000 1.3 +++ Cookie.pm 1 Nov 2002 19:57:35 -0000 1.4 @@ -1,6 +1,6 @@ ############################################################################# -## $Id: Cookie.pm,v 1.3 2002/10/15 21:58:49 spadkins Exp $ +## $Id: Cookie.pm,v 1.4 2002/11/01 19:57:35 spadkins Exp $ ############################################################################# package App::Session::Cookie; @@ -14,7 +14,7 @@ use Data::Dumper; use Storable qw(freeze thaw); use Compress::Zlib; -use MIME::Base64; +use MIME::Base64 (); # note: We may want to apply an HMAC (hashed message authentication code) # so that users cannot fiddle with the values. @@ -166,15 +166,17 @@ =cut sub html { - my ($self, $options) = @_; - my ($sessiontext, $sessiondata, $html, $headers, $cookieoptions); + my ($self) = @_; + my ($sessiontext, $sessiondata, $html, $headers, $cookieoptions, $sessiontemp, $initconf); $sessiondata = $self->{store}; - $sessiontext = encode_base64(Compress::Zlib::memGzip(freeze($sessiondata))); + $sessiontext = MIME::Base64::encode(Compress::Zlib::memGzip(freeze($sessiondata))); + $sessiontemp = $sessiontext; + $initconf = $self->{context}->initconf(); my ($maxvarsize, $maxvarlines); # length of a MIME/Base64 line is (76 chars + newline) - # the max length of a cookie should be 2000 chars + # the max length of a cookie should be 2000 chars (although the Netscape spec is 4k per cookie) $maxvarlines = 25; $maxvarsize = $maxvarlines*77; # 1925 chars $headers = ""; @@ -205,11 +207,12 @@ $self->{context}->set_header($headers); } - if ($options && $options->{showsession}) { + if ($initconf && $initconf->{showsession}) { # Debugging Only my $d = Data::Dumper->new([ $sessiondata ], [ "sessiondata" ]); $d->Indent(1); $html .= "<!-- Contents of the session. (For debugging only. Should be turned off in production.)\n"; + $html .= $sessiontemp; $html .= $d->Dump(); $html .= "-->\n"; } @@ -284,16 +287,38 @@ session state data. To retrieve the state data, the text is therefore decoded, gunzipped, and thawed (a la Storable). +Notes on length of cookies: See + + http://developer.netscape.com/docs/manuals/js/client/jsref/cookies.htm + +An excerpt is included here. + +The Navigator can receive and store the following: + + * 300 total cookies + * 4 kilobytes per cookie, where the name and the OPAQUE_STRING + combine to form the 4 kilobyte limit. + * 20 cookies per server or domain. Completely specified hosts + and domains are considered separate entities, and each has + a 20 cookie limitation. + +When the 300 cookie limit or the 20 cookie per server limit is exceeded, +Navigator deletes the least recently used cookie. When a cookie larger +than 4 kilobytes is encountered the cookie should be trimmed to fit, +but the name should remain intact as long as it is less than 4 kilobytes. + TODO: encrypt and MAC =cut sub init { my ($self, $args) = @_; - my ($cgi, $sessiontext, $store); + my ($cgi, $sessiontext, $store, $length, $pad); - $cgi = $args->{cgi} if (defined $args); + $self->{context} = $args->{context}; $store = {}; + $cgi = $args->{cgi} if (defined $args); + $cgi = $self->{context}->request()->{cgi} if (!defined $cgi); if (defined $cgi) { $sessiontext = $cgi->cookie("app_sessiondata"); if ($sessiontext) { @@ -305,9 +330,16 @@ $sessiontext .= $textchunk; $i++; } + $sessiontext =~ s/ /\+/g; + $length = length($sessiontext); + $pad = 4 - ($length % 4); + $pad = 0 if ($pad == 4); + $sessiontext .= ("=" x $pad) if ($pad); +#print "length(sessiontext)=", length($sessiontext), "\n"; $sessiontext =~ s/(.{76})/$1\n/g; $sessiontext .= "\n"; - $store = thaw(Compress::Zlib::memGunzip(decode_base64($sessiontext))); +#print "Session::Cookie->init(): sessiontext = [\n$sessiontext\n]\n"; + $store = thaw(Compress::Zlib::memGunzip(MIME::Base64::decode($sessiontext))); } } $self->{context} = $args->{context} if (defined $args->{context});