[cgiapp] CAP::Authentication not working properly with CAP::Session

Bradley C Bailey cgiapp at brad.memoryleak.org
Thu Nov 20 18:06:46 EST 2008


Richard,

>>> In the CGI::Session docs there is a mention of session->flush, and if 
>>> I use this in teardown(), then sessions do start to work, providing I 
>>> use $self->session_delete after logout. Odd because I've never had to 
>>> use session->flush before.
>>
>> What kind of environment are you using?
> 
> Development = CA::Server. Production and periodic testing = 
> Apache/mod_perl. So both persistent. But I also get the same behaviour 
> with the test scripts running under Test::WWW::Mechanize::CGIApp, which 
>  I presume isn't persistent. And I run other cgiapps under mod_perl 
> without needing to call flush, and have tested them on the same dev 
> platform as my current app.

Is there any way you can write a minimal app, or pare down what you 
have, that can be used to reproduce this problem and send it to me so I 
can look at it further?


>> Sessions are supposed to automatically flush() when they go out of 
>> scope and are DESTROYed.  I have never had to explicitly call 
>> flush().  If you are using some kind of persistent environment (ie: 
>> mod_perl, FastCGI, ...) make sure something isn't keeping the session 
>> around.
> 
> How would I go about determining whether the session *is* being retained?

I don't have any great ideas here...


>> Flash->flush() is a bit different than session->flush().  If you 
>> really need to put this code in teardown(), first call 
>> flash->cleanup() then flash->flush().  cleanup() goes through and 
>> marks data for removal, flush() writes it to the session.  This is all 
>> supposed to happen during DESTROY() as though, so it should be 
>> unnecessary.
> 
> Well, I've more-or-less got flash working now without flush, but not 
> with CAP::Flash but CGI::Session::Flash. It uses a method in the base 
> controller (superclass) which just returns a new CGI::Session::Flash 
> object each time it's called. For setting ($self->flash->set) I found I 
> could stash the Flash object and return it for any subsequent calls, but 
> not for the get stage. That stage is done in the template (CAP::TT) with:
> 
> [% SET flash = c.flash %]
> [% FOREACH type IN [ 'INFO', 'WARNING', 'ERROR' ] %]
>   [% IF flash.has_key(type) %]
>     <p>[% flash.get(type) %]</p>, etc
> 
> You might recognise that - it's based on the CAP::Flash pod. This call 
> to c.flash *has* to return a new Flash object, not a stashed one.
> 
> I get the impression only 1 'get' call to the session flash is 
> permitted, after that it's cleared. So for example this doesn't work:
> 
> [% FOREACH type IN [ 'INFO', 'WARNING', 'ERROR' ] %]
>   [% IF c.flash.has_key(type) %]
>     <p>[% c.flash.get(type) %]</p>, etc
> 
> Only the first 'type' (INFO in this case) gets printed, even though in a 
> test script I put all 3 in.

That should work.  You should be able to call get() as many times as you 
want.  It does not change the data in any way.  If you put [% 
c.flash.dump %] in your template, does it show all the correct data?


> I don't know how much resource overhead I incur creating a new Flash 
> object for each 'set' and one for the 'get', but so far that is the only 
> way I could get flash working. I've still no idea why this way works and 
> CAP::Flash doesn't, but it's likely to be related to the general 
> sessions flakiness in my current app.

Should not be too much of a performance issue.  When a new flash object 
is created it just reads the parameters from the session which is 
already in memory.  It does not write anything back to the session until 
it gets destroyed.

I agree this is probably not a Flash issue, but want to make sure since 
I am the author of that.  Let me know if you can narrow your code down 
to something that is reproducible and I will look at it.

Regards,
Bradley C Bailey



More information about the cgiapp mailing list