neilwatson has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to understand and use someone else's code. Consider this snippet:
sub load_session { my $self = shift; my $sid = shift; return undef unless $sid; ########## # # Grab a valid matching session, assuming it hasn't expired yet. # my $dbh = $self->_db_handle(); my $sth = $dbh->prepare("SELECT * FROM mapps_sessions WHERE sid=? +AND expires > NOW()"); unless ($sth->execute($sid) && $sth->rows()) { return undef; } my $row = $sth->fetchrow_hashref; return undef unless $row; # thaw the data and make it accessable. $self->{data} = thaw($row->{data}); $self->{uid} = $row->{uid}; ########## # # Update it to be sure it doesn't expire. # FIXME: should this be done in the script # or in another handler? # my $s = $self->update_session($sid); unless ($s) { return undef; } return $self->{data}->{uid}; return undef; }

And now consider my code:

use strict; use warnings; use lib "/usr/local/apache/virtual/itiv/modules"; use Mapps::Session; use Mapps::Auth; #################### # Get current session # and check for expiry my $sid; # get session id from cookie my $cookies = Apache::Cookie->fetch(); if ($cookies->{license_session}) { $sid = $cookies->{license_session}->value(); # load session from db my $s = Mapps::Session->new(); $s->load_session($sid); # session is good continue if (defined $s){ $m->call_next; } # Else session is undefined # or cookie does not exist. # Delete cookie and # redirect to login. }else{ # set cookie Apache::Cookie->new( $r, name => 'license_session', value => '', path => '/', )->bake; my $url = $m->comp('/login.html', msg=>"Invalid session or cookie" +); print "$url\n\n"; }

Currently the table mapps_session is empty. Shouldn't $s->Mapps::Session($sid) return undef? If so, should my code not redirect me to /login.html? The does not perform as I would expect. It acts as if the session is good and returns the html page I asked for.

Can someone offer me some enlightenmnet?

Neil Watson
watson-wilson.ca

Replies are listed 'Best First'.
Re: Checking for "return undef"
by Ovid (Cardinal) on Apr 21, 2004 at 16:31 UTC

    You don't appear to be checking your return values:

    # load session from db my $s = Mapps::Session->new(); $s->load_session($sid); # session is good continue if (defined $s){ $m->call_next; }

    I see nothing in load_session() which would undefine $s. Try this:

    # load session from db my $s = Mapps::Session->new(); if (defined $s->load_session($sid)) { $m->call_next; }

    Cheers,
    Ovid

    New address of my CGI Course.

Re: Checking for "return undef"
by shemp (Deacon) on Apr 21, 2004 at 16:03 UTC
    You need to look at your cascade of if-else's:
    if ( $cookies->{license_session} ) { ... if ( defined $s ) { ... } } else { # set cookie ... }
    when running through this code, when checking $cookies->{license_session}
    if true, you drop into the code block for that if, otherwise you do the cooresponding else.

    So lets say you get into the if, and the $s is not defined. There is no cooresponding else with the if that checks if $s is defined.
    The else that causes the redirect is matched with the outer if.
      I see your point. I fixed the if structures, but the problem persists:
      use strict; use warnings; use lib "/usr/local/apache/virtual/itiv/modules"; use Mapps::Session; use Mapps::Auth; #################### # Get current session # and check for expiry my $sid; # get session id from cookie my $cookies = Apache::Cookie->fetch(); if ($cookies->{license_session}) { $sid = $cookies->{license_session}->value(); # load session from db my $s = Mapps::Session->new(); $s->load_session($sid); # session is good continue if (defined $s){ $m->call_next; # Else session is undefined }else{ denied(); } # Else cookie does not exist. }else{ denied(); } # Delete cookie and # redirect to login. sub denied { # set cookie Apache::Cookie->new( $r, name => 'license_session', value => '', path => '/', )->bake; my $url = $m->comp('/login.html', msg=>"Invalid session or cookie" +); print "$url\n\n"; }

      Neil Watson
      watson-wilson.ca

Re: Checking for "return undef"
by ysth (Canon) on Apr 21, 2004 at 16:30 UTC
    sub load_session { ... return undef; ... } And now consider my code: ... $sid = $cookies->{license_session}->value(); # load session from db my $s = Mapps::Session->new(); $s->load_session($sid); # session is good continue if (defined $s){ $m->call_next; }
    return controls what the sub returns, but you aren't using a return value. load_session isn't ever going to change $s. Try:
    if (defined $s->load_session($sid)) { $m->call_next; }
    (Actually, a method can change the object it is called on, by assigning to $_[0]. This came as a surprise to me.)

      Actually, a method can change the object it is called on, by assigning to $_[0]. This came as a surprise to me.

      That's because @_ contains aliases to the passed arguments. It can be useful, but it's dangerous :)

      Cheers,
      Ovid

      New address of my CGI Course.

        I know about the aliasing; I just assumed that the object passed was a shallow copy rather than the real McCoy.