[Catalyst] Session trouble
I'm bringing this over from a discussion on IRC with nothingmuch. All up-to-date as of yesterday (fresh install on new machine). I set a flag in the session that adjusts how long cookies persist. Then override this method in my application: sub calculate_session_cookie_expires { my $c = shift; return $c-session-{remember_me} ? $c-session_expires : $c-NEXT::calculate_session_cookie_expires; } If I wait a while when the session expires (but the cookie hasn't expired yet) I get this behavior: 1) session expired. 2) request comes in with expired session id in the cookie. 3) session/cookie cleared 4) new session created 5) cookie set in headers 6) session data cleared. 7) session data requested -- but session data already clear 8) so, create new session id 9) write session to store, but using new session id, not one set in cookie header. Here's a Cat application to duplicate (which I've been able to do on two machines). The trick to make it fail is to have an invalid cookie. You can generate a few requests and see that the same cookie is sent each time. Then edit your browser's cookie to make it invalid (change a single digit). Then reload /bar and watch how a new cookie is generated each time. (Note: If the cookie is an invalid *format* you get: [error] Caught exception in Foo-bar Tried to set invalid session ID '7xxx0da4dfba9790d232f9dfc479ecc23bc0c2d83db' at /usr/local/share/perl/5.8.8/Catalyst/Action.pm line 47 which is another problem. Seems like should just ignore it and set a new cookie.) package Foo; use strict; use warnings; use Catalyst::Runtime; use Catalyst ( 'Session', 'Session::State::Cookie', 'Session::Store::FastMmap', 'Cache::FastMmap', ); __PACKAGE__-config( name = 'Foo' ); __PACKAGE__-setup; __PACKAGE__-config-{session} = { cookie_expires = 0, # Session cookie expires = 604800, cookie_name = 'my_cookie', }; sub bar : Local { my ( $self, $c ) = @_; $c-session-{stuff} = 'keep this'; $c-res-body('in bar'); } sub calculate_session_cookie_expires { my $c = shift; warn App::calculate_session_cookie_expires\n; my $x = $c-session-{foo}; # force a reload of the session. return $c-NEXT::calculate_session_cookie_expires; } sub finalize_body { my $c = shift; warn join( \n, '','-- finalize_body -', $c-req-path, 'Request:', $c-req-headers-as_string, 'Response:', $c-res-headers-as_string, ); return $c-NEXT::finalize_body( @_ ); } 1; Here's an annotated dump of a single request in the session code. Note also how many sessions are created. Request Cookie: my_cookie=810906f7a29c3f46f8b61dcf564f426c5209b254 # Now try and fetch the expired session: Session::_load_session: get_session_id returned: 810906f7a29c3f46f8b61dcf564f426c5209b254 Store::get_session_data: fetched [expires:810906f7a29c3f46f8b61dcf564f426c5209b254]: [undef] Session::_load_session_expires: expires = 0 810906f7a29c3f46f8b61dcf564f426c5209b254. # Session is expired so purge it: calling delete_session() State::Cookie::update_session_cookie: setting cookie { expires = 0, value = 810906f7a29c3f46f8b61dcf564f426c5209b254, } Session::_clear_session_instance_data Session::_load_session_expires: after calling delete_session # And create a new session: Session::session(): creating session Session::generate_session_id = 6d30ea44e84f658ae647f249bd7237e8a117740b # Now my overridden calculate_session_cookie_expires() is called: App::calculate_session_cookie_expires # Which triggers a session fetch, but there is no session data yet: Store::get_session_data: fetched [expires:6d30ea44e84f658ae647f249bd7237e8a117740b]: [undef] Session::_load_session_expires: expires = 0 6d30ea44e84f658ae647f249bd7237e8a117740b. # So it's considered expired and deletes the session again: calling delete_session() State::Cookie::update_session_cookie: setting cookie { expires = 0, value = 6d30ea44e84f658ae647f249bd7237e8a117740b } Session::_clear_session_instance_data Session::_load_session_expires: after calling delete_session # And yet another session is created and the cookie is set: Session::session(): creating session Session::generate_session_id = 4cc5a1526a6958df043edfcd77de025ece5e6334 # But it's the previous session id: State::Cookie::update_session_cookie: setting cookie { expires = undef, value = 6d30ea44e84f658ae647f249bd7237e8a117740b, } Session::prepare_action start for path: login # And when the data is finally stored it's using the latest session id, but not the same one used for the cookie: Store::store_session_data: setting [session:4cc5a1526a6958df043edfcd77de025ece5e6334] [HASH(0x9d937e8)] Store::store_session_data: setting [expires:4cc5a1526a6958df043edfcd77de025ece5e6334] [1184906823] --- Finalize body --- # And here's the cookie in the response
Re: [Catalyst] Command-line utility using Controller - examples?
On Friday 13 July 2007 14:42:51 Brandon Black wrote: However, wanting to invoke controller code from the commandline is a bad design smell usually. Domain logic should be packaged up independently in your Model layer (in something Catalyst-agnostic, which your Catalyst Model class encapsulates thinly). Or, if you -really- -actually- need controller logic in an external script, please explain what are you actually trying to achieve and we can think of a nice solution :) -- Bogdan Lucaciu http://www.wiz.ro ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Command-line utility using Controller - examples?
On 7/12/07, Ronald J Kimball [EMAIL PROTECTED] wrote: I need to write a utility script using Controller modules that will run from the command line. I haven't been able to find any examples of how to do this. Does anyone have a quick example I could use as inspiration? Probably the easiest way to invoke controller code from the commandline would be to use wget against your server. However, wanting to invoke controller code from the commandline is a bad design smell usually. Domain logic should be packaged up independently in your Model layer (in something Catalyst-agnostic, which your Catalyst Model class encapsulates thinly). The View should handle everything specific to HTML rendering, and the Controller should really be a very thin translation layer that maps HTTP inputs into View updates and Model calls. In a design laid out like that, your question would become How do I write a utility script that will invoke some of my Model code, and the answer would be use your non-Catalyst underlying Model class directly from the script and call whatever you need to call. -- Brandon ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Command-line utility using Controller - examples?
On Fri, Jul 13, 2007 at 06:42:51AM -0500, Brandon Black wrote: The View should handle everything specific to HTML rendering, and the Controller should really be a very thin translation layer that maps HTTP inputs into View updates and Model calls. In a design laid out like that, your question would become How do I write a utility script that will invoke some of my Model code, and the answer would be use your non-Catalyst underlying Model class directly from the script and call whatever you need to call. In some cases it's handy for the application to handle these tasks. I suspect that's one reason C::P::Scheduler is around. One case might be sending emails triggered by a cron job that include a self referencing url back to the application. Note, I said handy, not required. Probably better to write out a base URL when the app starts and then have the cron job use that. But, the infrastructure that Catalyst provides can make doing this in the application tempting. It's up to you if you want to give up those request cycles to other things than web requests. -- Bill Moseley [EMAIL PROTECTED] ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] TT2 + CP::Authentication + DBIC gotcha
apv wrote: This does not: [% vote = Catalyst.user.votes({word = w.id}) IF Catalyst.user_exists %] [% IF vote %] You rated this “[% vote.rating %]” [% END %] and yields for all cases (and columns): You rated this Try [% SET vote = Catalyst.user.votes({word = w.id}) IF Catalyst.user_exists %] (http://search.cpan.org/~abw/Template-Toolkit-2.19/lib/Template/Manual/Syntax.pod#Capturing_Block_Output) -- Bernhard Graf ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] TT2 + CP::Authentication + DBIC gotcha
On 7/13/07, apv [EMAIL PROTECTED] wrote: [% vote = Catalyst.user.votes({word = w.id}) IF Catalyst.user_exists %] Just FYI, you should never do this type of construct in perl. It will break in bizarre ways. I doubt that's the issue with TT, but don't get in the habit. my $vote = $foo if ($bar); # --- bad! - Perrin ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] C::P::Session installation error
On Thu, Jul 12, 2007 at 12:51:53AM +0300, Octavian Rasnita wrote: Hi, I have tried to install C::P::Session using the cpan shell, and it gave the following error: Without prove -v output we can't help you. Please stop posting just the 'make test' output. -- Matt S Trout Need help with your Catalyst or DBIx::Class project? Technical DirectorWant a managed development or deployment platform? Shadowcat Systems Ltd. Contact mst (at) shadowcatsystems.co.uk for a quote http://chainsawblues.vox.com/ http://www.shadowcatsystems.co.uk/ ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] TT2 + CP::Authentication + DBIC gotcha
Perrin Harkins wrote: On 7/13/07, apv [EMAIL PROTECTED] wrote: [% vote = Catalyst.user.votes({word = w.id}) IF Catalyst.user_exists %] Just FYI, you should never do this type of construct in perl. It will break in bizarre ways. I doubt that's the issue with TT, but don't get in the habit. my $vote = $foo if ($bar); # --- bad! What's wrong with that? I find it a lot more readable than my $vote; if ($bar) { $vote = $foo; } Matt ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Use block if, not postfix if [was: Re: [Catalyst] TT2 + CP::Authentication + DBIC gotcha]
On Fri, Jul 13, 2007 at 04:33:59PM +0100, Matt Lawrence wrote: What's wrong with that? I find it a lot more readable than my $vote; if ($bar) { $vote = $foo; } Check chapter 6 in PBP for the reasoning I'd parrot here if I could be bothered to type it all myself. -- Chisel Wright e: [EMAIL PROTECTED] w: http://www.herlpacker.co.uk/ It's just a motivational meeting. I don't care if I miss it. ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] TT2 + CP::Authentication + DBIC gotcha
On Friday 13 July 2007 10:33:59 am Matt Lawrence wrote: Perrin Harkins wrote: my $vote = $foo if ($bar); # --- bad! What's wrong with that? I find it a lot more readable than my $vote; if ($bar) { $vote = $foo; } Only the fact that it makes perl do Bad Things :) my $foo if CONDITION triggers a bug that lets perl violate the expectation for the duration of a lexical variable. If the CONDITION is false, $foo doesn't get undef. It gets a value that's completely unexpected -- unless you're using it for hack value, but don't do that either :) Andrew ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] TT2 + CP::Authentication + DBIC gotcha
On 7/13/07, Matt Lawrence [EMAIL PROTECTED] wrote: Perrin Harkins wrote: my $vote = $foo if ($bar); # --- bad! What's wrong with that? I find it a lot more readable than my $vote; if ($bar) { $vote = $foo; } It doesn't work this way, but suppose you wrote this: if ($bar) { my $vote = $foo } Now see why it's wrong? The way you wrote it is kind of ambiguous for the way we think of postfix operators. If you want something one line, how about this: my $vote = $foo ? $bar : undef; ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] TT2 + CP::Authentication + DBIC gotcha
stephen joseph butler wrote: On 7/13/07, Matt Lawrence [EMAIL PROTECTED] wrote: Perrin Harkins wrote: my $vote = $foo if ($bar); # --- bad! What's wrong with that? I find it a lot more readable than my $vote; if ($bar) { $vote = $foo; } It doesn't work this way, but suppose you wrote this: if ($bar) { my $vote = $foo } Now see why it's wrong? The way you wrote it is kind of ambiguous for the way we think of postfix operators. If you want something one line, how about this: my $vote = $foo ? $bar : undef; I can't replicate this behaviour. As far as I can tell, the postfix if is identical to the block if I wrote above. perl -Mstrict -wle 'my $foo = 1 if 0; print defined $foo ? $foo : undef' undef Has the bug been fixed? Matt ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
RE: [Catalyst] TT2 + CP::Authentication + DBIC gotcha
stephen joseph butler wrote: If you want something one line, how about this: my $vote = $foo ? $bar : undef; Which might be rendered in TT as: [% vote = foo ? bar : '' %] Since we don't have an explicit undef in TT (yet), I tend to use an empty string; it seems to carry almost all the same implications and works for most cases. Note that using the ?: operator also eliminates the need for the explicit SET directive, the lack of which was the source of the OP's problem. And it's less typing, too! --Jason ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] TT2 + CP::Authentication + DBIC gotcha
On Fri, Jul 13, 2007 at 05:31:53PM +0100, Matt Lawrence wrote: stephen joseph butler wrote: On 7/13/07, Matt Lawrence [EMAIL PROTECTED] wrote: Perrin Harkins wrote: my $vote = $foo if ($bar); # --- bad! What's wrong with that? I find it a lot more readable than my $vote; if ($bar) { $vote = $foo; } It doesn't work this way, but suppose you wrote this: if ($bar) { my $vote = $foo } Now see why it's wrong? The way you wrote it is kind of ambiguous for the way we think of postfix operators. If you want something one line, how about this: my $vote = $foo ? $bar : undef; I can't replicate this behaviour. As far as I can tell, the postfix if is identical to the block if I wrote above. perl -Mstrict -wle 'my $foo = 1 if 0; print defined $foo ? $foo : undef' undef Has the bug been fixed? No, because people use the if 0 construct as a way to create a static. cain$ re.pl $ sub foo { my $foo if 0; $foo++; } $ foo(); 0 $ foo(); 1 $ foo(); 2 $ However in 5.10 you -will- get a warning using this construct since it almost always indicates buggy code; the number of people who actually -need- a static rather than just a lexically closed-over var is vanishingly small and they can explicitly turn off the behaviour themselves. -- Matt S Trout Need help with your Catalyst or DBIx::Class project? Technical DirectorWant a managed development or deployment platform? Shadowcat Systems Ltd. Contact mst (at) shadowcatsystems.co.uk for a quote http://chainsawblues.vox.com/ http://www.shadowcatsystems.co.uk/ ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] TT2 + CP::Authentication + DBIC gotcha
Matt S Trout wrote: On Fri, Jul 13, 2007 at 05:31:53PM +0100, Matt Lawrence wrote: stephen joseph butler wrote: On 7/13/07, Matt Lawrence [EMAIL PROTECTED] wrote: I can't replicate this behaviour. As far as I can tell, the postfix if is identical to the block if I wrote above. perl -Mstrict -wle 'my $foo = 1 if 0; print defined $foo ? $foo : undef' undef Has the bug been fixed? No, because people use the if 0 construct as a way to create a static. cain$ re.pl $ sub foo { my $foo if 0; $foo++; } $ foo(); 0 $ foo(); 1 $ foo(); 2 $ Eurgh. I've never seen that before, but it's horrible. Matt ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] TT2 + CP::Authentication + DBIC gotcha
On 7/13/07, Matt Lawrence [EMAIL PROTECTED] wrote: Matt S Trout wrote: On Fri, Jul 13, 2007 at 05:31:53PM +0100, Matt Lawrence wrote: stephen joseph butler wrote: On 7/13/07, Matt Lawrence [EMAIL PROTECTED] wrote: I can't replicate this behaviour. As far as I can tell, the postfix if is identical to the block if I wrote above. perl -Mstrict -wle 'my $foo = 1 if 0; print defined $foo ? $foo : undef' undef Has the bug been fixed? No, because people use the if 0 construct as a way to create a static. cain$ re.pl $ sub foo { my $foo if 0; $foo++; } $ foo(); 0 $ foo(); 1 $ foo(); 2 $ Eurgh. I've never seen that before, but it's horrible. Matt As anecdotal evidence to its insidious behavior, I've personally been involved in a 5 man debugging effort that took 13 days (not full days, but probably an average of 3-4 hours a day * 5 people * 13 days) to finally find the bug. Which was simply my $foo = $bar if $baz; The reason why it was so hard to track down was because ot he wonderful undefined behavior. Ahh, good times. Never use that construct, for it will hurt you. At least we were all on billable hours ;) -Jay -- J. Shirley :: [EMAIL PROTECTED] :: Killing two stones with one bird... http://www.toeat.com ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] TT2 + CP::Authentication + DBIC gotcha
On Fri, Jul 13, 2007 at 05:31:53PM +0100, Matt Lawrence wrote: stephen joseph butler wrote: On 7/13/07, Matt Lawrence [EMAIL PROTECTED] wrote: Perrin Harkins wrote: my $vote = $foo if ($bar); # --- bad! What's wrong with that? I find it a lot more readable than my $vote; if ($bar) { $vote = $foo; } It doesn't work this way, but suppose you wrote this: if ($bar) { my $vote = $foo } Now see why it's wrong? The way you wrote it is kind of ambiguous for the way we think of postfix operators. If you want something one line, how about this: my $vote = $foo ? $bar : undef; I can't replicate this behaviour. As far as I can tell, the postfix if is identical to the block if I wrote above. perl -Mstrict -wle 'my $foo = 1 if 0; print defined $foo ? $foo : undef' undef Has the bug been fixed? No, because people use the if 0 construct as a way to create a static. cain$ re.pl $ sub foo { my $foo if 0; $foo++; } $ foo(); 0 $ foo(); 1 $ foo(); 2 $ However in 5.10 you -will- get a warning using this construct since it almost always indicates buggy code; the number of people who actually -need- a static rather than just a lexically closed-over var is vanishingly small and they can explicitly turn off the behaviour themselves. What about: my $vote = $bar and $foo; Seems to pass the test above and is vaguely readable. Is it similarly evil? ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] TT2 + CP::Authentication + DBIC gotcha
On 7/13/07, J. Shirley [EMAIL PROTECTED] wrote: As anecdotal evidence to its insidious behavior, I've personally been involved in a 5 man debugging effort that took 13 days (not full days, but probably an average of 3-4 hours a day * 5 people * 13 days) to finally find the bug. Which was simply my $foo = $bar if $baz; The reason why it was so hard to track down was because ot he wonderful undefined behavior. I had a similar experience, which is why I always mention when I see it in other people's code now. It's a real problem and very hard to track down if you haven't heard of it before. - Perrin ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] TT2 + CP::Authentication + DBIC gotcha
On Jul 13, 2007, at 12:13 PM, Perrin Harkins wrote: On 7/13/07, J. Shirley [EMAIL PROTECTED] wrote: As anecdotal evidence to its insidious behavior, I've personally been involved in a 5 man debugging effort that took 13 days (not full days, but probably an average of 3-4 hours a day * 5 people * 13 days) to finally find the bug. Which was simply my $foo = $bar if $baz; The reason why it was so hard to track down was because ot he wonderful undefined behavior. I had a similar experience, which is why I always mention when I see it in other people's code now. It's a real problem and very hard to track down if you haven't heard of it before. I have the same experience every few years, and I've never been able to understand why this can't simply be detected and at least flagged as an error or warning in the Perl compiler. Does anyone know? It's one of the few things about Perl that gets me angry. :) Jon ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] TT2 + CP::Authentication + DBIC gotcha
Perrin Harkins wrote: On 7/13/07, J. Shirley [EMAIL PROTECTED] wrote: As anecdotal evidence to its insidious behavior, I've personally been involved in a 5 man debugging effort that took 13 days (not full days, but probably an average of 3-4 hours a day * 5 people * 13 days) to finally find the bug. Which was simply my $foo = $bar if $baz; The reason why it was so hard to track down was because ot he wonderful undefined behavior. I had a similar experience, which is why I always mention when I see it in other people's code now. It's a real problem and very hard to track down if you haven't heard of it before. [disclaimer: not a paid spokesmodel ... ] A while ago, I tossed a code that did things like that into Komodo. I set a break point after the my $variable = expression if (condition); line and didn't see the $variable in the list. I went back to look at the condition, and realized what happened. Nowadays I simply put all the variable creation in a separate section near the beginning. Joe -- [EMAIL PROTECTED] ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/