toohoo has asked for the wisdom of the Perl Monks concerning the following question:

Hello dear Perl Monks,

I did search for a small Perl Cookies example. I've found this one: http://www.bignosebird.com/notebook/cookies.shtml

But this seems not to work at my side. I did correct the shebang to my system. I wanted to test it for short in a Win7 XAMPP installation. Other scripts work.

To be correct: The scripts run but it seems that I am unable to set a cookie. Otherways after setting it I should be able to read it again.

Should I copy and paste the code here?

Thanks in advance and regards, Thomas

  • Comment on searching for small Cookies example but found does not work

Replies are listed 'Best First'.
Re: searching for small Cookies example but found does not work
by tobyink (Canon) on Jul 27, 2018 at 14:08 UTC

    One gotcha with cookies: after you set a cookie, you need to wait until the next HTTP request before you can read it. This isn't a Perl-specific thing; it's just how cookies work. Some higher level frameworks for writing websites may abstract getting and setting cookies enough that they can hide this quirk, but if you're dealing with things at the level of printing HTTP headers, then you'll need to cope with this limitation.

Re: searching for small Cookies example but found does not work
by hippo (Archbishop) on Jul 27, 2018 at 14:24 UTC
    I've found this one: http://www.bignosebird.com/notebook/cookies.shtml

    That's very perl4ish. Not to say it won't work but is there any reason for you not to use a maintained module such as CGI::Cookie to do this instead? Especially when the documentation comes with a fully-written example script for you.

      Hello,

      to be true I did not get it running. But thanks for the hint, maybe I should dive a little bit deeper into this.

      regards

      Extension:

      I did find HTTP::Cookies - with this there was no success.

Re: searching for small Cookies example but found does not work
by Anonymous Monk on Jul 27, 2018 at 11:21 UTC
    Should I copy and paste the code here?

    yes but delete the parts that dont have anything to do with your q, see SSCCE

      Hello,

      I will post the examples here. Please be not angry, if I miss some rule. If I did not post it right, then plkease feel free to remove it.

      cookie-set.pl

      #-------------------EXAMPLE OF SETTING A COOKIE----------------------- +---- #!/usr/bin/perl require "/usr/local/apache/cgi-bin/cookie.pl"; $cookie=&set_cookie("login","testuser",0,"/","www.domain.com"); print "$cookie\n"; print "Content-type: text/html\n\n"; print "Have we a cookie?????\n";

      cookie-get.pl

      #-------------------EXAMPLE OF GETTING A VALUE FROM A COOKIE---------- +---- #!/usr/bin/perl require "/usr/local/apache/cgi-bin/cookie.pl"; print "Content-type: text/html\n\n"; $cookie=&get_cookie("login"); if ($cookie ne "") { print "you have been authenticated as $cookie\n"; } else { print "Somebody toss me a freakin' cookie...."; }

      cookie-del.pl

      #-------------------EXAMPLE OF REMOVING A COOKIE---------------------- +---- #!/usr/bin/perl require "/usr/local/apache/cgi-bin/cookie.pl"; $cookie=&remove_cookie("login","/","www.domain.com"); print "$cookie\n"; print "Content-type: text/html\n\n"; print "Have we removed a cookie?????\n";

      cookie.pl

      #-------------------ROUTINE FILE STARTS HERE-------------------------- +---- # # This routine takes (name,value,minutes_to_live,path,domain) as argum +ents # to set a cookie. # # 0 minutes means a current browser session cookie life # sub set_cookie() { my ($name,$value,$expires,$path,$domain) = @_; $name=&cookie_scrub($name); $value=&cookie_scrub($value); $expires=$expires * 60; my $expire_at=&cookie_date($expires); my $namevalue="$name=$value"; my $COOKIE=""; if ($expires != 0) { $COOKIE= "Set-Cookie: $namevalue; expires=$expire_at; "; } else { $COOKIE= "Set-Cookie: $namevalue; "; #current session cookie if + 0 } if ($path ne ""){ $COOKIE .= "path=$path; "; } if ($domain ne ""){ $COOKIE .= "domain=$domain; "; } return $COOKIE; } # # This routine removes cookie of (name) by setting the expiration # to a date/time GMT of (now - 24hours) # sub remove_cookie() { my ($name,$path,$domain) = @_; $name=&cookie_scrub($name); my $value=""; my $expire_at=&cookie_date(-86400); my $namevalue="$name=$value"; my $COOKIE= "Set-Cookie: $namevalue; expires=$expire_at; "; if ($path ne ""){ $COOKIE .= "path=$path; "; } if ($domain ne ""){ $COOKIE .= "domain=$domain; "; } return $COOKIE; } # # given a cookie name, this routine returns the value component # of the name=value pair # sub get_cookie() { my ($name) = @_; $name=&cookie_scrub($name); my $temp=$ENV{'HTTP_COOKIE'}; @pairs=split(/\; /,$temp); foreach my $sets (@pairs) { my ($key,$value)=split(/=/,$sets); $clist{$key} = $value; } my $retval=$clist{$name}; return $retval; } # # this routine accepts the number of seconds to add to the server # time to calculate the expiration string for the cookie. Cookie # time is ALWAYS GMT! # sub cookie_date() { my ($seconds) = @_; my %mn = ('Jan','01', 'Feb','02', 'Mar','03', 'Apr','04', 'May','05', 'Jun','06', 'Jul','07', 'Aug','08', 'Sep','09', 'Oct','10', 'Nov','11', 'Dec','12' ); my $sydate=gmtime(time+$seconds); my ($day, $month, $num, $time, $year) = split(/\s+/,$sydate); my $zl=length($num); if ($zl == 1) { $num = "0$num"; } my $retdate="$day $num-$month-$year $time GMT"; return $retdate; } # # don't allow = or ; as valid elements of name or data # sub cookie_scrub() { my($retval) = @_; $retval=~s/\;//; $retval=~s/\=//; return $retval; } # usual kluge so require does not fail.... my $XyZ=1; #-------------------ROUTINE FILE ENDS HERE---------------------------- +----

      I put these scripts in the (existing-project)/cgi-bin directory. The other scripts in the project run successfully. If I run cookie-set.pl I get: Have we a cookie????? ... and nothing else.

        The code you've showed works for me. The only significant change I had to make was to remove the "www.domain.com" argument from the calls to set_cookie. Perhaps you left it at its default value instead of setting it to your real domain name?

        However, I very much second the comments made by the other monks! That is, use a library instead of hand-written code, and use the right line endings (CRLF). I'd add to that: Use strict and warnings. (Also, as an aside, don't use empty prototypes like sub set_cookie() and then call via &set_cookie, which avoids the prototypes. Instead, get rid of the prototype, as in sub set_cookie {..., and then call via the more modern calling style without the &.)

        print "$cookie\n"; print "Content-type: text/html\n\n"; print "Have we a cookie?????\n";

        If you mean you can't see the actual cookie printed it is because you print it before sending content-type headers... Try moving all print statements you want to appear on your browser after printing content-type headers. And btw that \n\n should have been \r\n or more accurately:

        ... For example, most networking protocols expect and prefer a CR+LF ("\015\012" or "\cM\cJ" ) 
        

        It is for these trivial mistakes that CGI can save you a lot of trouble if not time. Here is how to set a cookie on client's browser:

        use CGI; my $cgi = CGI->new; my $cookie = $cgi->cookie(-name => 'CookieName', -value => 'CookieVal +ue' ...); print $cgi->header( -cookie => $cookie, -type => 'text/html'); #print "just set a cookie on you<br>" print $cgi->start_html("just set a cookie on you<br>");
Re: searching for small Cookies example but found does not work
by Anonymous Monk on Jul 31, 2018 at 19:06 UTC
    Don't listen to these CGI concern trolls. Go ahead and parse cookies manually or use CGI. Do what works, not what some bossy developer tells you is theoretically correct because it gives them good feels, and circle-jerk upvotes.
      Mike you old shill, you said you'd stop posting. A lie, as always