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

So I am trying to put some cookies into a page out put with CGI::Application

Before doing the final out put, I do this:

$app->header_props(-type=>'charset',-expires=>'shift_jis',-cookie=> [$ +app->cookie->return_cookies]);

$app->cookie->return_cookies returns the following:

SET per_page=12; path=/; expires=1h keyword_not=cat; path=/; expires=1 +h keyword_or=tree; path=/; expires=1h keyword_combined=tree%20NOT%20c +at; path=/; expires=1h

For some reason , only the first cookies (per page) value are being set. A little while ago, all them were being set, and somewhere along the line, it stopped working. I'm sorry, I can't post more info about what I did to break it. I have NO IDEA. If I did I could fix it, but I have tried reverting to what I thought was the place where it used to work, and still no luck.

Does anyone see anything wrong with this snppet that should be setting the cookie value?

Replies are listed 'Best First'.
Re: Cookies with CGI::Application
by matija (Priest) on May 16, 2004 at 06:07 UTC
    Whenever I have trouble with cookies, I usualy check for a few standard problems:
    • Is the header the first thing you're printing? It must be absolutely the first. A debugging print will mess up the parsing of the headers.
    • Are the headers being printed in more than one place? Most (all?) header printing routines print a blank line at the end, and that terminates the headers.
Re: Cookies with CGI::Application
by PodMaster (Abbot) on May 16, 2004 at 06:14 UTC
    I'm sorry, I can't post more info about what I did to break it. I have NO IDEA. If I did I could fix it, but I have tried reverting to what I thought was the place where it used to work, and still no luck.
    That pretty much sums up you situation, only you can help yourself. All the possible advice you could get (barring understanding of how CGI/HTTP works) for debugging your black box is contained in CGI Help Guide and The Idiot's Guide to Solving Perl CGI Problems, so go read them and try things until you figure it out.

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

Re: Cookies with CGI::Application
by Belgarion (Chaplain) on May 16, 2004 at 05:46 UTC

    I think we're going to need a bit more information. If this was my code I would telnet into the web server and see what information is being sent back in response to a GET request. The "Set-Cookie" lines should be present. The question then becomes, what is in those lines. Also, in the above example you say that return_cookies returns:

    SET per_page=12; path=/; expires=1h keyword_not=cat; path=/; expires=1 +h keyword_or=tree; path=/; expires=1h keyword_combined=tree%20NOT%20c +at; path=/; expires=1h

    Is this a string it's returning? Or an array of strings? It would be really helpful if you could provide a Data::Dumper output of the return_cookies function. I don't belive the literal SET should be present in the cookie output.

    Are you using the CGI::Cookie module to handle your cookies, or did you roll your own?

      I have this routine which I use through the app to make cookies for certain things

      sub bake { my $cookie = shift; my @args = @_; use CGI; my $query = new CGI; # Make a new cookie my $new_cookie = $query->cookie(@args); # Get the cookies already baked my $cookies = $cookie->param('cookies'); my @new_cookies; push(@new_cookies, $new_cookie); push(@new_cookies, @$cookies) if $cookies; $cookie->param('cookies', ¥@new_cookies); }

      Then, to retrieve the cookies before I out put:

      sub return_cookies { my $cookie = shift ; my $cookies = $cookie->param('cookies'); $cookie->debug("SET @$cookies") if $cookies; return @$cookies if $cookies; }

      The strange thing is of course, that this particular part worked fine for a day. I did not touch it, but made several changed to the main app. This leads me to believe it is not a problem with the cookie setting/retreiving function, but someplace else. And since &return_cookies returns exactly what I expect, I am totally lost.

      I just discovered something strange. I am using CGI::Application so I have various run modes:

      sub top { my $app = shift; # Reset the cookies $app->cookie->bake(-name=>'site', -value=>$app->query->param('site +'), -expires=>'1h'); $app->cookie->bake(-name=>'keyword_or', -value=>'', -expires=>'-1h +'); $app->param('template', $app->get_template('top.html')); return ($app->output); } sub results { my $app = shift; # Do stuff to the keyword &manage_keyword($app) if ($app->query->param('do_search')); return ($app->output); } sub manage_keyword { my $app = shift; my $keyword_or = $app->query->param('keyword_or'); $keyword_combined ||= $app->query->cookie('keyword_or'); .... $app->cookie->bake(-name=>'keyword_or', -value=>"$keyword_or") if +$keyword_or; ..... }

      For some reason, even though the run_mode is results, the

      $app->cookie->bake(-name=>'keyword_or', -value=>'', -expires=>'-1h');

      in run_mode "top" seems to be deleting my cookie. If I comment that out, it works fine. Why the hang is it even paying attention to "top" ?

        &manage_keyword($app)

        This is just a newbie doubt:

        Is it correct to call a sub in this way?

        I see that &manage_keyword only gets its usual first parameter.

        I have also noticed that you use several variables with very similar names. Does it help?

        .{\('v')/}
        _`(___)' __________________________
Re: Cookies with CGI::Application
by drewbie (Chaplain) on May 16, 2004 at 19:43 UTC
    What is happening is that only cookie is actually sent to the browser, and I'd bet it's either the last or first one depending on how header_props is implemented. The solution is header_add() - you might have to upgrade your CGI::Application installation since it's a recent addition.
    header_add() # add or replace the 'type' header $webapp->header_add( -type => 'image/png' ); - or - # add an additional cookie $webapp->header_add(-cookie=>[$extra_cookie]); The header_add() method is used to add one or more headers to the +outgoing response headers. The parameters will eventuallly be passed +on to the CGI.pm header() method, so refer to the CGI docs for exact +usage details. Unlike calling header_props(), header_add() will preserve any exis +ting headers. If a scalar value is passed to header_add() it will rep +lace the existing value for that key. If an array reference is passed as a value to header_add(), values + in that array ref will be appended to any existing values values for + that key. This is primarily useful for setting an additional cookie +after one has already been set.
Re: Cookies with CGI::Application
by antirice (Priest) on May 18, 2004 at 14:30 UTC

    Yeah, I wish CGI::Cookie's constructor would error out or something when you try to do something like this. If you change your -expires option to "+1h" it will work as expected. (Notice how it's setting all the expires options to 1h?)

    antirice    
    The first rule of Perl club is - use Perl
    The
    ith rule of Perl club is - follow rule i - 1 for i > 1