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

Help me please.....

I have a kind of predicament! I created a site that is using Apache::Session::MySQL, it works very well. Then I created another, that works too. So I now created a third, that uses the very same scripts, and it worked too, but now it does not work.

Here is what it is doing....
It is creating the _session_id;
It is also creating the cookie and passing it to the browser;
The browser then passes it back and forth to the site no matter what page you visit, I verified that it is not merely creating a different session for every page. it is remembering the session "id" from page to page. However, it will not store any data into it;
When I "login" on the other sites, it keeps me logged in until I click logout, then it deletes the cookie and the session. On this site, when I login and change pages, it says I'm NOT logged in! so I go login, and it says I was successfully logged in, and it does get my real name out of the 'registered_users' MySQL database, as well as the last time I logged in. It displays those for me.
So I know it works, because when I have it log me in, when it shows it is successful, it is first checking the $sess_ref->attr("login") to make sure it is set to 1, if it is, then it knows I was successfully logged in. But if it is not then it says something went wrong, but I never get that message, it always says I was successfully logged in.

So why does it "lose" the information when I leave the page, using the same session_id? The Cookie stays in tact.
Oh yeah, I also have the site check to see if the user does not have cookies turned on, if not then the site adds &sess_id=$sess_id to every link, after the ?pg=page_name. So I forced my browser to reject the cookie, and started a brand new session, which was then added to every link at the end of the link, and every form as a hidden field.
So I did make sure it was in everything I went to, and when I logged in, it again said successful, but when I changed pages, with the same sess_id added to the link, it again, said I was not logged in, so I know that the sessions are somehow not working(holding session variables).

I deleted the sessions table and recreated it, but it's not working. I'm sooooo lost. I learned these things(Apache::Session) from the book, "Perl and MySQL for the Web" by Paul DuBois. I cannot find any help with the Apache::Session module, the docs don't have any kind of trouble shooting, and no site or list to get help. Can someone, PLEASE help me, or point me in the right direction?

I would really appreciate the help.
Thank you, very much for any help you can be!

Richard.
  • Comment on Please help me... Apache::Session::MySQL

Replies are listed 'Best First'.
Re: Please help me... Apache::Session::MySQL
by FamousLongAgo (Friar) on Dec 28, 2002 at 07:21 UTC
    With web applications especially, it's very hard to diagnose a problem without seeing the code. You're maintaining a lot of state through a combination of client cookie, database table, and script logic, and on top of that, the setup makes it hard to debug. The problem could be anywhere.

    Reading about it in prose makes it even harder - remember that the code may not be doing what you think it's doing! Putting up the Perl helps us get to the meat of the problem - just don't neglect the READMORE tag.

    Good luck!
Re: Please help me... Apache::Session::MySQL
by iguanodon (Priest) on Dec 28, 2002 at 15:53 UTC
    I agree with FamousLongAgo, this is a complicated setup and there's not enough information here to debug it. Show us the code...

    Some general comments on Apache::Session:

    • I cannot find any help with the Apache::Session module, the docs don't have any kind of trouble shooting, and no site or list to get help.
      The author supports that module on the apache-modperl mailing list.
    • Make sure you are updating something in the top level of the session hash, so Apache::Session will know that it has changed. The docs suggest putting a time stamp in the top level.
    • If you're using undef %session, try changing it to untie %session and vice versa. I don't know why this sometimes helps, but I've found that changing from one to the other can fix problems with session data not saving. The Apache::Session docs say you should undef or untie your session hash as soon as you are done with it. I'd appreciate any comments on why undef or untie might behave differently.
    • Try wrapping your undef %session or untie %session and your database disconnect in an END{} block to make sure it happens in all cases. Your script may be exiting without executing that code because of an error or a forgotten exit() somewhere else.
    • Speaking of errors, you are running with strict and warnings turned on, right? Check the server error log and correct any errors from your script. I've found that error messages that seem totally unrelated to session handling can interfere with the saving of session data (usually by causing a premature exit, see above).
      thank you both, very much!

      I will join the mailing list, and post the problem there too. I think I did narrow it down...

      I used Shell to run the site, and I get these errors:

      [Sat Dec 28 10:02:21 2002] index.cgi: (in cleanup) Can't call method "release_all_locks" on an undefined value at /usr/lib/perl5/site_perl/5.6.1/Apache/Session.pm line 599 during global destruction.

      and

      index.cgi: (in cleanup) Can't call method "update" on an undefined value at /usr/lib/perl5/site_perl/5.6.1/Apache/Session.pm line 508 during global destruction.

      The code in my index.cgi file is pretty simple:

      #!/usr/bin/perl -w use CGI::Carp qw(fatalsToBrowser); use CGI qw(:standard :cgi-lib escapeHTML); use Mail::Sendmail; #@ USE_STATEMENTS use Digest::MD5; use Crypt::CBC; use Crypt::Blowfish; use LWP::UserAgent; push(@inc, "/home/mydom/my_mods"); use FRHWebDB::Session; # This contains the MySQL connections #@ USE_STATEMENTS ReadParse(\%in); use vars qw($cookie $sess_id $sess_ref $page $logged_in %in);# These a +re global $sess_id = cookie ("session_id"); if ($sess_id eq "" && $in{sess_id} ne "") { $sess_id = $in{sess_id};#if no cookies then it's in the url } $sess_ref = FRHWebDB::Session->open_with_expiration(undef, $sess_id) i +f defined ($sess_id);#Open with Expriration require "/home/mydom/site/data.conf";#This contains header # information and other stuff, like menu and things like # that if ($in{pg} eq "quit" && defined($sess_ref)) { if ($sess_ref->attr ("remember_me") == 1) { $sess_ref->attr ("loggedin", 0); $message = qq~You have been Logged Out$nname_ws!<br><br>~;#$nn +ame_ws is their nickname with a # space in front of it, if no nick na +me then it's blank # (Out!) } else { Delete_Session_Forever($sess_ref); } } if (!defined ($sess_ref))# no session yet, so create one. { defined ($sess_ref = FRHWebDB::Session->open (undef, undef)) or error ("Could not create new session: $FRHWebDB::Session::e +rrstr"); $cookie = cookie (-name => "session_id", -value => $sess_ref->session_id(), -path => url (-absolute => 1), -expires => "+1y" );#Create the cookie to put on user pc at top_header() } get_cookie_values($sess_ref) if defined ($sess_id);#Ok, get # session values from the $sess_ref [apache::session]. get_company_values() if !defined($sess_id);#No session so # just define the company variables($co_name and such) require "/home/mydom/site/config.data";#Ok this one has all # the javascripts, css and lots of configuration variables, # and such. Plus a browser check. #Set expiration of session if none exists. $sess_ref->expires ($sess_ref->now() + (60*60*24*365)) if !defined ($s +ess_ref->expires()); $Page_Dir = "/home/mydom/site/pages";#directory where all # the pages in .conf files are stored. $pg = $in{pg}; $test_cookie2 = cookie ("session_id"); if (!defined ($test_cookie2)) {#users pc has cookies # Turned off, so add the session to every link and form # using the variables I've defined here. $nocookies = 1; $inc_sess_id = "&sess_id=" . $sess_ref->session_id(); $hidden_inc_sess_id = hidden(-name=>"sess_id", -value=>$sess_r +ef->session_id()); } else {#Ok, they do have cookies turned on! $nocookies = 0; $inc_sess_id = ""; $hidden_inc_sess_id = ""; } if (!$pg || !-e "$Page_Dir/$pg.conf") {#No page so load home require "$Page_Dir/home.conf"; $page .= $page_content; } elsif(-e "$Page_Dir/$pg.conf") {#Ok there is a page so # load it instead of home require "$Page_Dir/$pg.conf"; $page .= $page_content; } top_header("$title","","");#ok, now this is in # data.conf, it is the header and it uses CGI.pm's header() # start_html() etc. #ok, now below closes the table and creates the right menu # if any. right_menu() is defined in config.data $page .= qq~ &lt;/div /> &lt;/font /> &lt;/p />\n&lt;/td />~ . right_menu("in_table_cell","125",$overrideit) + . end_page_footer(); print $page; exit; # Exit system.
      That is that. You can see the output at http://www.firstratehosting.com/t/index.cgi I'm not near finished with it,
      I'm trying to get the sessions to work, then I'm going to add an affiliate program to it,
      then finish the site.

      It still does not work though...

      If you need to also see the Session.pm code let me know, I'll post that too.

      Thank you ever so kindly.
      Richard

      edited: Sat Dec 28 17:57:25 2002 by jeffa - broke out the Mop of Formatting +42 on this one

        Hmmm... this is even more complicated than I thought. Your session handling is wrapped in another module. What is FRHWebDB::Session? Is that your module or someone else's?

        The first thing I would recommend is adding a time stamp to the session every time the script is invoked.

        Also, I don't see how your session is being untied. Maybe this is buried in FRHWebDB::Session but I suspect it's being left to happen when the Apache::Session object is cleaned up automatically at the end of the script. This may work most of the time but as the Apache::Session docs say, you should explicitly call undef or untie from your script.

        I use an END block in my "index" script to handle this:

        END { $session->{'timestamp'} = localtime(); undef $session; $dbh->disconnect; }