http://qs1969.pair.com?node_id=640878

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

Monks, I'm banging my head against the wall here. I just can't seem to set a cookie.

I'm using the following set up.

Apache/2.0.54 (Win32) mod_perl/2.0.1 Perl/v5.8.7
Within the httpd conf I've defined the following, to pick up any dynamic requests...
<Files ~ ".*"> SetHandler perl-script PerlHandler MyOrg::Apache::User PerlSendHeader On Options ExecCGI </Files>
I've got my own handler here because I'm picking up the the uri, and using it to run template toolkit against an appropriate file. This goes something like this (a bit cut down)...
sub handler { my $r = shift; # use the path_info to determine which template file to process my $file = $r->unparsed_uri; # validate the url as a content page my $tt_path = $nav->get_path_attribute("/$file", 'local_path'); $tt_path =~ s[^/][]; return -1 if ! $tt_path; # Decline this request if the path isn't +in the nav # set up and call the template my $template = Template->new({ PLUGIN_BASE => 'MyOrg::Template::Plugin', INCLUDE_PATH => "$websrc:$websrc\\lib", PRE_PROCESS => 'config', OUTPUT => $r, # direct output to Apache request }); my $params = { uri => $r->uri, navigation => $nav, }; $r->content_type('text/html'); $r->headers_out->add('Set-Cookie' => "CGISESSID=PLEASEWORK; path=/ +"); $template->process($tt_path, $params) || return fail($r, 500, $template->error()); ## 500 -> SERVER_ +ERROR return 0; # OK }
... with $nav being a pre-created object which looks after which uri's compile which templates (although, all this works nicely, so only provided here for context).

I've tried all sorts of things within this sub, but have settled on showing the simplest example of what, as far as I can understand, should work, but doesn't. Namely, it's that "headers_out" line. It doesn't set a cookie in my browser. I've set my browser to prompt me on and new cookie request, which is popping up new windows all the time, except when I visit my site. Any ideas where I'm going wrong anyone?

All help gratefully received. Thanks, Rob

---
my name's not Keith, and I'm not reasonable.

Replies are listed 'Best First'.
Re: Cookies, mod_perl and apache request handlers
by derby (Abbot) on Sep 25, 2007 at 11:46 UTC

    Hmmm ... from the example given, there's nothing glaringly wrong. Do you have any other handlers on the same uri? I wouldn't rely solely on being prompted by the browser. Install firebug and see exactly what's coming back. If firebug isn't an option, do the request outside of the browser (lwp-request or curl have options to display all the returned headers and status codes).

    -derby
      cheers derby, the firebug link was the push in the right direction that I needed!

      The header was being set fine, the 'problem' was because I handn't specified an 'expires' parameter, and my lack of understanding over how cookies are managed without it (IE wasn't bothering to write it to disk, which is where I was looking for it).

      My problem didn't really exist! Sorry guys.

      cheers for your help everyone.

      PS: If anyone is interested, I got it working with the following snippet. (which is probably not how it will stay, but is a good simple example.)

      my $session = new CGI::Session(undef, undef, {Directory=>'c:/temp/ +sessions'}); my $count = $session->param('count'); $session->param('count', $count + 1); my $cookie = $query->cookie( -name => $session->name, -value => $session->id ); $r->content_type('text/html'); $r->err_headers_out->add('Set-Cookie' => "$cookie; expires=Tue Jan + 01 00:00:01 2036 GMT"); $session->flush();
      ---
      my name's not Keith, and I'm not reasonable.
Re: Cookies, mod_perl and apache request handlers
by mwah (Hermit) on Sep 25, 2007 at 12:22 UTC
    * You did specify a mod_perl1 option

      PerlSendHeader On

    on a mod_perl2 environment. The mod_perl2 equivalent would be:

      PerlOptions +ParseHeaders

    which does something completely different from your intention
    (it's used by cgi-like stuff).

    * You probably forgot to *send* the header (not sure about that).

      $r->send_http_header;

    in which case the Apache/mod_perl would send its own
    (after finding out there is none).

    * You probably did something else in the context or apache
    config what we don't know ;-)

    Regards
    mwa
Re: Cookies, mod_perl and apache request handlers
by perrin (Chancellor) on Sep 25, 2007 at 10:47 UTC
      Thanks, but I'd already found and tried this, but with no joy.
      ---
      my name's not Keith, and I'm not reasonable.
        Then you're either sending out headers that are breaking it or sending a malformed cookie header. Use something like LiveHTTPHeaders to examine the output of your server.
Re: Cookies, mod_perl and apache request handlers
by shmem (Chancellor) on Sep 25, 2007 at 11:50 UTC
    Next steps: you could dump the $r object to STDERR via Data::Dump::Streamer and examine the server error log in order to see whether the cookie has actually been set. On the client side, grab the packets sent via wireshark, or use a tool like Firebug for Firefox to examine the headers you receive. If the cookie has been set by the server and hasn't been received by the client, it got lost on the way...

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}