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

Would someone please some up theiebeasts! This is my current issue, I'm using HTML::Mason and Apache::Session and what I'm doing is using my session.id as a cookie value. In the autohandler of /auth_required/, I check the value of the cookie, and save an instance of Apache::Session::Pg to that ID. (This ignores some of the given authentication steps.) Then I have $S set as a MasonGlobal and I read from a few tables in Pg into that variable, and display the information elsewhere on the site. For some reason however, the information in $S can get mixed up. I assumed *maybe wrongly* that no other thread or process could set $S, so the information stays in it until needed. In trial production environment I found that other processes when they viewed the index.html would have the sql values they requested loaded into the same global $S overwriting what else was there.

So the first question would be, are Mason globals specific to thread/process, and how can this happen? Crappy arrow diagram displays contents of thought.

$S Global is set in httpd.conf

User makes request->Autohandler reads cookie's value->Creates a tied Apache::Session::Pg hash as %S->$S Contains a reference to %S->Hash is derefrenced and read and written to in subcomps, which transparently changes Pg's session table in a frozen column a_session.

Yet for some reason when two people are in the system the fields in the templates can be populated with someone elses $S. The first monk to identify problem gets a cookie, the first one to suggest a solution gets a jar.

Update
Perrin: Right on!.. Though your 15min too late. I always get back with the solutions on my SoPW post, so I would like to point to the problem this time: The line that currently reads $S = \%APACHE_SESSION; read my $S = \%APACHE_SESSION; -- stupid mistake for someone like myself to make. The last incarnation of this I passed $S via arguements, but it got VERY messy, so i tried something else. I'm going open my session method for peer review, and so we stop getting stop questions on sessions and cookies.

As follows my mason autohandler:
<%init> ## Verfiy we have a cookie with a _session_id my $j = Apache2::Cookie::Jar->new($r); my $c = $j->cookies('**COOKIE_NAME**'); unless ( defined $c ) { module::Error::nice_error($m, 'E201'); } ## Verify we have session that matches cookies ID my %APACHE_SESSION; eval { tie %APACHE_SESSION, 'Apache::Session::Postgres', $c->value, { Handle => $dbh, Commit => 1, }; }; if ( $@ ) { ## No tuple with matching ID (form cookie), bogus data. $dbh->rollback; module::Error::nice_error($m, 'E301'); } $S = \%APACHE_SESSION; ## Verify that the sessioned user still has an entry in the users +table ## Save user information into $U by ref $U = $dbh->selectrow_hashref( q{ SELECT * FROM users WHERE pkid = ? }, {}, $APACHE_SESSION{' +pkid'} ); if ( defined $U ) { delete $U->{'password'}; } else { $dbh->rollback; module::Error::nice_error($m, 'E501'); } </%init>


Evan Carroll
www.EvanCarroll.com

Replies are listed 'Best First'.
Re: A review/question on Mason::Globals
by perrin (Chancellor) on Dec 14, 2005 at 01:34 UTC
    It is not possible for two processes to be changing the same $S at the same time. It is a separate variable in every process. If you don't do anything to clear the value out though, it will persist, and the next user to hit that same process will see the $S from the last request. Try logging $$ (the current process ID) along with the relevant values from $S to help you debug it. It can also be useful to run in single process mode, which is done with the -X switch to httpd if you are using apache 1.x.