Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Multiple Cookies with CGI::Application

by Nomis52 (Friar)
on Jul 27, 2002 at 12:29 UTC ( [id://185744]=perlquestion: print w/replies, xml ) Need Help??

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

I'm attempting to set multiple cookies using CGI::Application, this is running under mod_perl.

sub do_login { my $self = shift ; my $q = $self->query ; my $c1 = $q->cookie(-name=>'userID', -value=>'test123', ); my $c2 = $q->cookie(-name=>'sessionID', -value=>'blahblahblah', ); $self->header_type('header'); $self->header_props(-type=>'text/plain', -cookie=> [$c1,$c2], ); }

The problem is that only the last cookie in the array (in this case $c2) gets set. If I swap them to:

$self->header_props(-type=>'text/plain', -cookie=> [$c2,$c1], );

Then only $c1 is set. Finally :

$self->header_props(-type=>'text/plain', -cookie=> [$c2,$c1,$c2], );

Sets only $c2.

header_props() returns a hash with the attributes set. I've checked this and everything _seems_ to be fine. However if I pass this to the header() method from CGI, I get an '', which I think indicates something is wrong:(

The same script under 'traditional' cgi (no mod_perl) works fine

Any help would be much appricated, as I'm sure its something really simple I've missed

Replies are listed 'Best First'.
Re: Multiple Cookies with CGI::Application
by sedhed (Scribe) on Jul 28, 2002 at 03:05 UTC

    Well, if it's any consolation, you're doing everything right. Your array reference to header_props is getting passed nicely, and prints two cookies when CGI::App->run is called. (At least for me it does, from a command-line) I don't have a real fix for you, but I am interested in the results of the following: Try connecting to the script using a telnet client, so you can see what's really being sent to the browser.

    telnet localhost 80 GET /cgi-bin/script.pl HTTP/1.0

    Press enter twice. Should return two lines starting with "Set-Cookie: "

    HTTP/1.0 200 OK Content-Length: 2322 Connection: Close Server: GWS/2.0 Date: Sun, 28 Jul 2002 02:57:06 GMT Content-Type: text/html Cache-control: private Set-Cookie: cookie1=foobar; path=/ Set-Cookie: cookie2=helloagain; path=/ ...

    cheers!

Re: Multiple Cookies with CGI::Application
by Nomis52 (Friar) on Jul 28, 2002 at 03:20 UTC

    I been looking into this more since I've had some sleep :) From the CGI pod:

    To create multiple cookies, give header() an array reference:
    print $query->header(-cookie=>[$cookie1,$cookie2]);

    I've done this before to set mutliple cookies and its worked, so I assume that this part is ok.

    Delving deeper into the code, it seems the reason why I'm getting a '' from the header() method is because of the following in CGI.pm:

    if ($MOD_PERL and not $nph) { my $r = Apache->request; $r->send_cgi_header($header); return ''; }

    If I print the header out as it appears just before the if , it contains both cookies as seen below

    Status: 200 Ok
    Set-Cookie: sessionID=blahblahblah; path=/
    Set-Cookie: userID=test123; path=/
    Date: Sun, 28 Jul 2002 02:31:59 GMT
    Content-Type: text/plain; charset=ISO-8859-1
    

    If I telnet to the server the headers I receive are:

    HTTP/1.1 200 OK
    Date: Sun, 28 Jul 2002 03:17:15 GMT
    Server: Apache-AdvancedExtranetServer/1.3.23 (Mandrake Linux/4mdk) mod_ssl/2.8.7 OpenSSL/0.9.6c PHP/4.1.2
    Content-Type: text/plain; charset=ISO-8859-1
    Set-Cookie: userID=test123; path=/
    X-Cache: MISS from quigon.nomis52.com
    Transfer-Encoding: chunked
    

    So my belief is that something must be going astray when send_cgi_header() is called.

    This problem is driving me crazy.....

    Nomis52

      Okay Nomis52, I've done some testing on a local server, and it works for me, setting both cookies each time.

        Tested version info:
      • Apache 1.3.12
      • mod_perl 1.26
      • CGI 2.81
      • CGI::Application 2.5

      I tried multiple cookies using CGI.pm directly, and I tried the same using CGI::Application, all under mod_perl, and under each scenario I get both cookies without issue. I know you didn't want to hear that :)

      What happens when you try a very simple script like:

      #!/usr/bin/perl use CGI::Application; my $a = new CGI::Application; my $c1 = $a->query->cookie(-name=>'userID', -value=>'test123', ); my $c2 = $a->query->cookie(-name=>'sessionID', -value=>'blahblahblah', ); $a->header_props(-cookie => [$c1,$c2]); $a->run;
      C::A ought to give you a list of %ENV, one if which should be HTTP_COOKIE => 'userID=test123; sessionID=blahblahblah' in this case. Do you get that environment value okay, even when the cookies don't come through?

      Anyway, I'm thinking maybe a version issue somewhere along the line.

      Update: Below is the output from an HTTP session using the above code under mod_perl:

      [admin@bart][~]$ telnet localhost 80 Trying 127.0.0.1... Connected to localhost (127.0.0.1). Escape character is '^]'. get /perl/test3.cgi HTTP/1.0 HTTP/1.1 200 OK Date: Sun, 28 Jul 2002 05:08:17 GMT Server: Apache/1.3.12 (Unix) (Red Hat/Linux) PHP/3.0.15 mod_perl/1.26 Set-Cookie: userID=test123; path=/ Set-Cookie: sessionID=blahblahblah; path=/ Connection: close Content-Type: text/html; charset=ISO-8859-1 <P> Query Parameters:<BR> <OL> </OL> <P> Query Environment:<BR> <OL> <LI> DOCUMENT_ROOT => '<B>/home/httpd/html</B>' <LI> GATEWAY_INTERFACE => '<B>CGI-Perl/1.1</B>' <LI> MOD_PERL => '<B>mod_perl/1.26</B>' <LI> PATH => '<B>/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin</B>' <LI> QUERY_STRING => '<B></B>' <LI> REMOTE_ADDR => '<B>127.0.0.1</B>' <LI> REMOTE_PORT => '<B>1357</B>' <LI> REQUEST_METHOD => '<B>get</B>' <LI> REQUEST_URI => '<B>/perl/test3.cgi</B>' <LI> SCRIPT_FILENAME => '<B>/home/httpd/perl/test3.cgi</B>' <LI> SCRIPT_NAME => '<B>/perl/test3.cgi</B>' <LI> SERVER_ADDR => '<B>127.0.0.1</B>' <LI> SERVER_ADMIN => '<B>webmaster@lithocraft.com</B>' <LI> SERVER_NAME => '<B>bart.lithocraft.com</B>' <LI> SERVER_PORT => '<B>80</B>' <LI> SERVER_PROTOCOL => '<B>HTTP/1.0</B>' <LI> SERVER_SIGNATURE => '<B><ADDRESS>Apache/1.3.12 Server at bart.lit +hocraft.com Port 80</ADDRESS> </B>' <LI> SERVER_SOFTWARE => '<B>Apache/1.3.12 (Unix) (Red Hat/Linux) PHP/ +3.0.15 mod_perl/1.26</B>' <LI> UNIQUE_ID => '<B>PUN8Qc9c3QYAAC5MELk</B>' </OL> Connection closed by foreign host.

      cheers!

        Hmmm this doesn't look good, here's my output

        HTTP/1.1 200 OK
        Date: Sun, 28 Jul 2002 05:17:56 GMT
        Server: Apache-AdvancedExtranetServer/1.3.23 (Mandrake Linux/4mdk) mod_ssl/2.8.7 OpenSSL/0.9.6c PHP/4.1.2
        Content-Type: text/html; charset=ISO-8859-1
        Set-Cookie: sessionID=blahblahblah; path=/
        X-Cache: MISS from quigon.nomis52.com
        Transfer-Encoding: chunked
        
        

        If you reload it to see the cookies naturally only the last one is set

        <li> HTTP_COOKIE => '<b>sessionID=blahblahblah</b>'
        

        I tend to agree with you that this is an issue with my set-up, currently:

        • Apache 1.3.23
        • mod_perl 1.26
        • CGI 2.79
        • CGI::Application 2.4

        I'm going to give it a go on a debian box and see if thats any different.

        Well, I've tried it on a debian box and it works fine as expected. For what its worth:

        • Apache 1.3.26
        • mod_perl 1.26
        • CGI 2.752
        • CGI::Application 2.1

        Thanks for everyone's help

        Nomis52
Re: Multiple Cookies with CGI::Application
by acarvalh (Novice) on Jul 28, 2002 at 02:09 UTC
    Your problem lies in the basic fact that cookies are unique value pairs. You would need to pass in a scalar value rather than an array (either $c1 or $c2 or $c3 or the three concatenated together.

    Hope this helps. :-)

      Well, yes, kinda. Cookies are name=value pairs, when you get down to it. But using CGI.pm, one doesn't really use them directly that way.

      perldoc CGI says:

      The interface to HTTP cookies is the cookie() method: $cookie = $query->cookie(-name=>'sessionID', -value=>'xyzzy', -expires=>'+1h', -path=>'/cgi-bin/database', -domain=>'.capricorn.org', -secure=>1); print $query->header(-cookie=>$cookie);

      In the example, $cookie is actually a hashref, or more accurately, a CGI::Cookie object.

      Now to pass multiple cookies, you use a ref to an anonymous array, containing the cookie objects you wish to pass. CGI.pm continues:

      To create multiple cookies, give header() an array reference: $cookie1 = $query->cookie(-name=>'riddle_name', -value=>"The Sphynx's Questio +n"); $cookie2 = $query->cookie(-name=>'answers', -value=>\%answers); print $query->header(-cookie=>[$cookie1,$cookie2]);

      Hope this clarifies things a little.

      cheers!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://185744]
Approved by virtualsue
Front-paged by jptxs
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (5)
As of 2024-03-29 08:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found