Re: [Catalyst] Session trouble

2007-08-02 Thread Bill Moseley
I'm still having plenty of session trouble.  Maybe it's just related
to the dev server.

I'm implementing a remember me, but once a cookie is written (rather
is returned in the request) a new cookie is never sent.

Is there a way to force a cookie?

No, Session::DynamicExpiry doesn't help.

Also, and this is weird, when a cookie is supplied by the browser
besides the Session plugins not sending a cookie, the cookie still
gets setup but *after* the headers have already been sent.

In Engine::HTTP I added the warn line below:

if ( my $headers = delete $self-{_header_buf} ) {
DEBUG  warn write: Wrote headers and first chunk ( . 
length($headers . $buffer) .  bytes)\n;
$ret = $self-NEXT::write( $c, $headers . $buffer );

warn $headers, time, \n; sleep 2;  # WARN DEBUG
}

Then in a test application I have:

sub calculate_session_cookie_expires {
my $c = shift;

warn in calculate_session_cookie_expires , time, \n; sleep 1;

return time + 10;
}

Then I see that calculate_session_cookie_expires is called after the
headers have already been written:

HTTP/1.0 200 OK
Connection: close
Date: Thu, 02 Aug 2007 19:09:53 GMT
Content-Length: 15
Status: 200

1186081793
in calculate_session_cookie_expires 1186081795




Here's an entire test application:

package Foo;
use strict;
use warnings;
use Catalyst::Runtime;
use Catalyst (
'Session',
'Session::State::Cookie',
'Session::Store::FastMmap',
'Cache::FastMmap',
# 'Session::DynamicExpiry',
);
__PACKAGE__-config( name = 'Foo' );
__PACKAGE__-setup;


sub default : Private {
my ( $self, $c ) = @_;
$c-res-body( 'setting session' );
$c-session-{bar} = time; # Trigger session write
}



sub calculate_session_cookie_expires {
my $c = shift;

warn in calculate_session_cookie_expires , time, \n; sleep 1;

return time + 10;
}

1;





-- 
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] Session trouble

2007-07-23 Thread Jim Spath

Bill Moseley wrote:

On Mon, Jul 16, 2007 at 07:20:36PM +0300, Yuval Kogman wrote:

Hi,

no update yet, been terribly busy (the client is not being very nice
to us).

If you need comaint to release yourself let me know. You should have
commit access, right?


I can take another stab at it -- I had spent a few hours throwing
warn and cluck messages into the code to try and figure out what was
going on.  My eyes started to glaze over after a while.

I like how you refactored the plugins quite a bit.  But, I wish there
were comments in the code to give a little context.  That would make
debugging by people unfamiliar with the code easier.  I also find NEXT
makes it a bit more complicated when trying to follow stack traces.

Would you have a few minutes to at least verify if you can reproduce
the problem with the test application I sent?  I'd like to rule out any
thing that might be due to my environment.


What seems to be happening (and this was happening with a previous bit
of code from a week or two back) was that I was accessing the session
after it had been cleared/reset at the end of finalize (or something
like that).  So, that was creating a new sessionid and thus storing
the session data under a different id than the id used in the cookie.

This is the code that's getting me now:

sub calculate_session_cookie_expires {
my $c = shift;

return $c-session-{remember_me}
? $c-session_expires
: $c-NEXT::calculate_session_cookie_expires;
}

I think the quick fix would be to stuff the remember_me flag in the
stash earlier in the request and look at the stash instead of the
session (to avoid creating a new sessionid by calling $c-session).

I thought it might be a matter or moving
$c-_clear_session_instance_data later in the request cycle, but it
seems that's not really the problem.  I was seeing multiple sessions
created (and cleared) in the case of a request with a cookie with an
id for an expired session -- which doesn't seem right.


Oh, and to note again:  I think the behavior of dieing on invalid
session id format is not right.  The id should just be ignored in that
case and a new cookie sent.  If someone ends up with a bad cookie (or
the cookie format changes) could result in a lockout.


Hi,

We recently upgraded our Session modules and 
C::P::Session::DynamicExpiry no longer seems to function.


I was wondering if this could be related to the issues discussed in this 
email thread?


If so, is there any update?  If not, is some temporary way for me to get 
remember me functionality working again?


Thanks!
- Jim

___
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] Session trouble

2007-07-16 Thread Yuval Kogman
Hi,

no update yet, been terribly busy (the client is not being very nice
to us).

If you need comaint to release yourself let me know. You should have
commit access, right?

The upload from today was to fix the test that needs Cookie.

-- 
  Yuval Kogman [EMAIL PROTECTED]
http://nothingmuch.woobling.org  0xEBD27418


___
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] Session trouble

2007-07-16 Thread Bill Moseley
On Mon, Jul 16, 2007 at 07:20:36PM +0300, Yuval Kogman wrote:
 Hi,
 
 no update yet, been terribly busy (the client is not being very nice
 to us).
 
 If you need comaint to release yourself let me know. You should have
 commit access, right?

I can take another stab at it -- I had spent a few hours throwing
warn and cluck messages into the code to try and figure out what was
going on.  My eyes started to glaze over after a while.

I like how you refactored the plugins quite a bit.  But, I wish there
were comments in the code to give a little context.  That would make
debugging by people unfamiliar with the code easier.  I also find NEXT
makes it a bit more complicated when trying to follow stack traces.

Would you have a few minutes to at least verify if you can reproduce
the problem with the test application I sent?  I'd like to rule out any
thing that might be due to my environment.


What seems to be happening (and this was happening with a previous bit
of code from a week or two back) was that I was accessing the session
after it had been cleared/reset at the end of finalize (or something
like that).  So, that was creating a new sessionid and thus storing
the session data under a different id than the id used in the cookie.

This is the code that's getting me now:

sub calculate_session_cookie_expires {
my $c = shift;

return $c-session-{remember_me}
? $c-session_expires
: $c-NEXT::calculate_session_cookie_expires;
}

I think the quick fix would be to stuff the remember_me flag in the
stash earlier in the request and look at the stash instead of the
session (to avoid creating a new sessionid by calling $c-session).

I thought it might be a matter or moving
$c-_clear_session_instance_data later in the request cycle, but it
seems that's not really the problem.  I was seeing multiple sessions
created (and cleared) in the case of a request with a cookie with an
id for an expired session -- which doesn't seem right.


Oh, and to note again:  I think the behavior of dieing on invalid
session id format is not right.  The id should just be ignored in that
case and a new cookie sent.  If someone ends up with a bad cookie (or
the cookie format changes) could result in a lockout.

Thanks,

-- 
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/


[Catalyst] Session trouble

2007-07-13 Thread Bill Moseley
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