Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Perl v5 CGI error Use of uninitialized value $session_status

by RedJeep (Sexton)
on Oct 29, 2019 at 05:20 UTC ( #11108063=perlquestion: print w/replies, xml ) Need Help??

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

Hello friends. I am on Perl v5.24.3. Running on Windows IIS server. The web site uses Perl CGI. It is a new but simple web site and Perl CGI has worked well so far. During testing I found what appears to me to be an odd error. When a user logins the Perl web page works fine. Sometimes when a user is not logged and goes to the same page (or any other .pl page that requires login to be true, then an error is kicked off. The error is... Use of uninitialized value $session_status ... And I have no idea why I am getting this error when "I think" I am doing this correctly.

This error when run from command line..
Mon Oct 28 21:57:11 2019 template_requires_login_simple2.pl: Use of uninitialized value $session_status in string eq at C:\inetpub\wwwroot\template_requires_login_simple2.pl line 89.

This error from IIS header analysis..
HTTP2_SESSION_RECV_INVALID_HEADER
--> error = "Invalid character in header name."
--> header_name = "mon oct 28 23"<br> --> header_value = "06:35 2019 template_requires_login_simple2.pl: Use of uninitialized value $session_status in string eq at C:\\inetpub\\wwwroot\\template_requires_login_simple2.pl line 89."
I have reviewed the documentation and cannot determine why sometimes an error is produced when the user is not logged in and goes to a page that requires a login. I'd like a user to receive a nice message saying 'please login'. The error never occurs when the user is logged in.

I look forward to your insight.

Thank you,
---Robert

#!/usr/bin/perl ### Setup environment use CGI; use CGI::Carp qw(fatalsToBrowser); use CGI::Session; use CGI::Session qw/-ip-match/; use DBI; use strict; use warnings; $CGI::POST_MAX = 1024 * 1024 * 10; # max 10MB posts $CGI::DISABLE_UPLOADS = 1; # no uploads ######################################################### ### Setup variables my $title = "Template with Login"; my $error_message = ""; my $html = ""; ######################################################### ### Setup variables my $dbfile = "/inetpub/wwwroot/data/people1.db"; my $dsn = "dbi:SQLite:dbname=$dbfile"; my $user = ""; my $password = ""; my $dbh = DBI->connect($dsn, $user, $password, { PrintError => 0, RaiseError => 1, AutoCommit => 1, FetchHashKeyName => 'NAME_lc', }); ### Setup session data connection my $cgi = new CGI; my $session = CGI::Session->new("driver:sqlite", undef,{DataSource=>'/ +inetpub/wwwroot/data/session_management.db'}) or die (CGI::Session->errstr); my $cookie = $cgi->cookie(CGISESSID => $session->id ); print $cgi->header(-cookie=>$cookie); $session->flush(); ### Grab SID and determine session_status my $sid = $session->id(); my $session_status = "false"; $session_status = $session->param("user_logged_in"); ### Initialize my $x = init($session, $cgi); my $login_trials_count = $session->param("~login-trials"); sub init { my ($session, $cgi) = @_; if ( $session->param("~logged-in") ) { return 1; # Verify if user is not logged. } my $trials = $session->param("~login-trials") || 0; return $session->param("~login-trials", ++$trials); } ############################################### my $profile_lg_name = ""; my @fail_message = ""; ######################################################### ### Fetch info from session profile if ($session_status eq 'true') { $profile_lg_name = $session->param("profile_lg_name"); login_is_ok(); } else { push @fail_message, "Not logged in. Err 200"; login_is_not_ok(); } ######################################################### ### Print HTML document sub login_is_ok { ### The following sets up CGI. $CGI::POST_MAX = 1024 * 1024 * 10; # max 10MB posts $CGI::DISABLE_UPLOADS = 1; # no uploads my $q = CGI->new; my $entry_type = ''; $entry_type = $q->param('entry_type') || 0; $html = " <HEAD> <meta name=\"viewport\" content=\"width=device-width, initial-scal +e=1\"/> <link href=\"style2.css\" rel=\"stylesheet\" type=\"text/css\"> <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"favicon. +ico\" /> <meta http-equiv=\"refresh\" content=\"7200; URL=logout.pl\" /> <title>$title</title> </head> <h3>$title</h3> Welcome : $profile_lg_name <br> You are now logged in. </BODY> </HTML>"; print $html; $dbh->disconnect; exit(); } sub login_is_not_ok { ### Print HTML document $html = " <HTML> <HEAD> <TITLE>Template</TITLE> <meta http-equiv=\"refresh\" content=\"2\; URL=user_login.html\" /> </HEAD> <BODY> <P> Please log in. Redirecting to log in page. <p> </BODY> </HTML>"; print $html; }

Replies are listed 'Best First'.
Re: Perl v5 CGI error Use of uninitialized value $session_status
by haj (Priest) on Oct 29, 2019 at 07:28 UTC

    I didn't actually run the code, but a quick review shows some suspicious lines:

    ### Grab SID and determine session_status my $sid = $session->id(); my $session_status = "false"; $session_status = $session->param("user_logged_in");

    So, if the session does not contain a paraneter user_logged_in, you are overwriting the value "false" with undef.

    Maybe what you want is this:
    ### Grab SID and determine session_status my $sid = $session->id(); my $session_status = $session->param("user_logged_in") // "false";

    Later in the code (though not at line 89) you do the comparison which triggers the warning:

    if ($session_status eq 'true')

    Most probably that warning also causes the IIS to complain. IIS is expecting your response to start with a header, but gets a timestamp from the warning instead. The timestamp, starting with a [ character, is what you get from using CGI::Carp.

    That said, I guess you are aware that this program looks more like 20th-century legacy than current best practice for a web application. We love Perl just because it is so simple to whip something up which will run for decades without a change, but still... given that the internet is no longer the same friendly place which it was 20 years ago, a bit of general refurbishment wouln't hurt.

      Your fix... my $session_status = $session->param("user_logged_in") // "false"; Seems to be working. If the site proves even moderately successful then I will look at one of the Perl or Python web frameworks. I only have about 20 pages so didn't want to invest much extra effort.

      Thanks for your help!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11108063]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (4)
As of 2022-11-26 22:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?