Bradley C Bailey wrote:
Richard,
Hope someone can help with this. I'm having a major headache with
authentication and sessions.
[..]
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.
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?
But I'm also trying to use CAP::Flash, and find the flash message
never gets written to the session (even though flash->dump shows it's
present in the flash object), unless I use flash->flush in teardown().
But then the message gets converted to 'keep' and never goes away.
All this suggests to me there is something wrong with the way
CGI::Session / CAP::Session is working, but I can't put my finger on
anything obvious, after several days trying. Does anyone recognise
this behaviour or can explain it?
Probably related to the same issue as above, with objects not going out
of scope and getting cleaned up.
Yes, I assumed it was related.
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.
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.
Also, just curious, if you take CAP::Flash completely out of the picture
does your session problem go away?
No, just the same - I still need to call flush() in teardown.
--
Richard Jones
##### CGI::Application community mailing list ################
## ##
## To unsubscribe, or change your message delivery options, ##
## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp ##
## ##
## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ##
## Wiki: http://cgiapp.erlbaum.net/ ##
## ##
################################################################