[Catalyst] Unnecessary session writes

Bill Moseley moseley at hank.org
Wed Dec 10 22:25:12 GMT 2008


When Catalyst::Session fetches an existing session it records its
"signature" which it then compare with the session data at the end
of the request to decide if the session should be written.

_load_session() does:

    $c->_session_data_sig( Object::Signature::signature($session_data) ) if $session_data;

And then _save_session does this:

        no warnings 'uninitialized';
        if ( Object::Signature::signature($session_data) ne
            $c->_session_data_sig )
        {
            $session_data->{__updated} = time();
            my $sid = $c->sessionid;
            $c->store_session_data( "session:$sid" => $session_data );
        }

Now, if you call $c->session and no session data is found (no session
id, or no session data in store), then a fresh session hash is created.


sub initialize_session_data {
    my $c = shift;

    my $now = time;

    return $c->_session(
        {
            __created => $now,
            __updated => $now,

            (
                $c->config->{session}{verify_address}
                ? ( __address => $c->request->address )
                : ()
            ),
        }
    );
}

So, if you look at the session every request, for example:

    # See if user has selected a language preference
    my $language = $c->session->{language} || 'en';

Then if a session doesn't exist it will generate a new session id and
store the empty session to the database (or whatever store you have).
A bot could have fun inserting rows into your database.


I'm using this instead:

sub initialize_session_data {
    my $c = shift;

    my $now = time;

    my $session_data = {
        __created => $now,
        __updated => $now,

        (
            $c->config->{session}{verify_address}
            ? ( __address => $c->request->address )
            : ()
        ),
    };

    # Only save this session if data is added by the application
    $c->_session_data_sig( Object::Signature::signature($session_data) );

    return $c->_session($session_data);
}

That won't help if you do this, of course:

    my $lang = $c->session->{user_prefs}{language} || 'en';



-- 
Bill Moseley
moseley at hank.org
Sent from my iMutt




More information about the Catalyst mailing list