Why does my Perl CGI program fail with "Software error: ..."? - perl

When I try to run my Perl CGI program, the returned web page tells me:
Software error: For help, please send mail to the webmaster (root#localhost), giving this error message and the time and date of the error.
Here is my code in one of the file:
#!/usr/bin/perl
use lib "/home/ecoopr/ecoopr.com/CPAN";
use CGI;
use CGI::FormBuilder;
use CGI::Session;
use CGI::Carp (fatalsToBrowser);
use CGI::Session;
use HTML::Template;
use MIME::Base64 ();
use strict;
require "./db_lib.pl";
require "./config.pl";
my $query = CGI->new;
my $url = $query->url();
my $hostname = $query->url(-base => 1);
my $login_url = $hostname . '/login.pl';
my $redir_url = $login_url . '?d=' . $url;
my $domain_name = get_domain_name();
my $helpful_msg = $query->param('m');
my $new_trusted_user_fname = $query->param('u');
my $action = $query->param('a');
$new_trusted_user_fname = MIME::Base64::decode($new_trusted_user_fname);
####### Colin: Added July 12, 2009 #######
my $view = $query->param('view');
my $offset = $query->param('offset');
####### Colin: Added July , 2009 #######
#print $session->header;
#print $new_trusted_user;
my $helpful_msg_txt = qq[];
my $helpful_msg_div = qq[];
if ($helpful_msg)

The "please send mail to the webmaster" message you see is a generic message that the web server gives you when anything goes wrong and nothing handles it. It's not at all interesting in terms of solving the actual problem. Check the error log to find possible relevant error output from your program.
And, go through my How do I troubleshoot my Perl CGI script? advice on finding the problem.
My guess is that you have a syntax error with that dangling if(). What you have posted isn't a valid Perl program.
Good luck,

is that something related to suexec module
Improper configuration of suExec can cause permission errors
The suEXEC feature provides Apache users the ability to run CGI and SSI programs under user IDs different from the user ID of the calling web server. Normally, when a CGI or SSI program executes, it runs as the same user who is running the web server.
apache recommends that you not consider using suEXEC.
http://httpd.apache.org/docs/2.2/suexec.html

From the StackOverflow page: How to trap program crashes with HTTP error code 500
I see that your include: use CGI::Carp (fatalsToBrowser);
... stifles the HTTP 500 error. Simply removing this will allow the programs to crash "properly".

Related

can't locate object method "see" via package "Net::IMAP::Simple"

I am trying to fetch unread emails from server and mark them as seen (read) after fetching. I'm using perl script and the package Net::IMAP::Simple. I'm writing this script for the office work.
Below is some code :
use strict;
use warnings;
use Net::IMAP::Simple;
use Email::Simple;
use HTTP::Date;
#some code....
# Create the object
my $server = Net::IMAP::Simple->new($imap_server) or die "Can't connect to server: $imap_server ";
# Log on
my $login = $server->login($imap_user,$imap_passwd) or die "Login failed (bad username or password)";
#some code.....
# set the message as seen
$server->see($i);
# i also used $server->add_flags($i,'\Seen'); but it throws same error.
The Irony is, this code works fine on my Gmail account , which i use for testing. but when i test it in office it throws error ;
can't locate object method "see" via package "Net::IMAP::Simple"
I don't know what's the issue here.
The methods see and unsee were added in Net::IMAP::Simple version 1.1899_05.
> 1.1899_05: Tue Jun 16 06:42:16 EDT 2009
> - I started working on ticket 45953,
> - created sub_flags() and add_flags()
> - taught delete() to use add_flags() -- adds \Deleted
> - providing see() and unsee() for ticket 45953
> - I started building tests for the flag manipulation stuff and
> put reselect stuff ... noticed a possible bug in
> Net::IMAP::Server
You likely have an older version on your production system. Update it, and include a minimum version in your Makefile.PL or cpanfile or whatever you use to track dependencies.

Why might Perl allow for http websites using TOR but not https?

I am having difficulty using perl to visit a website via TOR if it is an https site but not if it is an http site.
#!/usr/bin/perl
use strict;
use WWW::Mechanize;
use LWP::Protocol::socks;
use LWP::Protocol::https;
use utf8;
my $mech = WWW::Mechanize->new(timeout => 60*5);
$mech->proxy(['http', 'https'], 'socks://localhost:9150');
$mech->get("https://www.google.com");
I am receiving the error message: Error GETing https://www.google.com: Status read failed: Bad file descriptor at line 10," where line i10 is the last line of the program.
In the TOR browser, I can successfully view: "https://www.google.com" with a port of 9150.
I am using ActivePerl 5.16.2; Vadalia 0.2.21 and Tor 0.2.3.25.
I have a Windows machine and my primary internet browser is Mozilla.
I have tried installing packages with the commands:
cpan LWP::UserAgent
ppm install LWP::Protocol::https
cpan LWP::Protocol::https
ppm install LWP::Protocol::socks
cpan LWP::Protocol::socks
ppm install Mozilla::CA
ppm install IO::Socket::SSL
ppm install Crypt::SSLeay
cpan Crypt::SSLeay
Thank you for any help! Please let me know whether there is any further information that I can provide.
Time ago, i'd found the way to go throught https sites with Tor using WWW::Curl::Easy to fetch those kind of sites, because using LWP i found the same problems.
After that i save all html in files and parsing them using WWW::Mechanzie or HTML::TreeBuilder.
If you want more interactivity with site like post forms , etc. This solutions may be more tedious because you'll need to interact with curl.
package Curl;
use warnings;
use WWW::Curl::Easy;
use WWW::UserAgent::Random;
my $curl = WWW::Curl::Easy->new;
my $useragent = rand_ua("browsers");
my $host = 'localhost';
my $port = '9070';
my $timeout = '20';
my $connectTimeOut= '20';
&init;
sub get
{
my $url = shift;
$curl->setopt(CURLOPT_URL, $url);
my $response_body;
$curl->setopt(CURLOPT_WRITEDATA,\$response_body);
my $retcode = $curl->perform;
if ($retcode == 0) {
print("Transfer went ok Http::Code = ".$curl->strerror($retcode)."\n");
my $response_code = $curl->getinfo(CURLINFO_HTTP_CODE);
# judge result and next action based on $response_code
return \$response_body;
} else {
# Error code, type of error, error message
print("An error happened: $retcode ".$curl->strerror($retcode)." ".$curl->errbuf."\n");
return 0;
}
}
sub init
{
#setejem el proxy
$curl->setopt(CURLOPT_PROXY,"$host:".$port);
$curl->setopt(CURLOPT_PROXYTYPE,CURLPROXY_SOCKS4);
#posem les altres dades
$curl->setopt(CURLOPT_USERAGENT, $useragent);
$curl->setopt(CURLOPT_CONNECTTIMEOUT, $connectTimeOut);
$curl->setopt(CURLOPT_TIMEOUT, $timeout);
$curl->setopt(CURLOPT_SSL_VERIFYPEER,0);
$curl->setopt(CURLOPT_HEADER,0);
}
Hope this will help you!
Maybe the proxy that you are using is already an HTTPS proxy (ie. CONNECT proxy). In that case this should work (untested):
#!/usr/bin/perl
use strict;
use WWW::Mechanize;
use LWP::Protocol::socks;
use LWP::Protocol::https;
use utf8;
my $mech = WWW::Mechanize->new(timeout => 60*5);
$mech->proxy(['http'], 'socks://localhost:9150');
$mech->proxy(['https'], 'https://localhost:9150'); ### <-- make https go over https-connect proxy
$mech->get("https://www.google.com");
I cannot find the origin but I fought with that a long time ago. Basically the problem I had was with the imlpementation that LWP::UserAgent used for the https requests.
Possibly this question can help you: How do I force LWP to use Crypt::SSLeay for HTTPS requests?

Open2 Api failure while installing Mead software

I am running into some issues trying to install a software called MEAD . I would appreciate if someone could have alook .
I get the following error while installing
/mead/bin # ./mead.pl GA3
Using system rc-file: /home/karosh/mead/bin/../.meadrc
Warning: Can't find user rc-file
Cluster: /home/karosh/mead/bin/../data/GA3/GA3.cluster
open2: exec of /home/karosh/mead/bin/driver.pl failed at ./mead.pl line 230
THe mead software is not written by me so I have not changed any of the perl scrips . I line 230 in the driver.pl file is
sub run_mead {
my %options = #_;
my $reader = FileHandle->new();
my $writer = FileHandle->new();
unless ( open2($reader, $writer, "$FindBin::Bin/driver.pl") ) {
die "Unable to run MEAD.\n";
}
...
...
}
Does this error mean that open2 was not found . The mead folks have put the following line in the file:
use strict;
use File::Spec;
use FileHandle;
use IPC::Open2;
Or does it mean that i need to install the rpm that contains the API . I see that this API is a part of the core perl bundle http://perldoc.perl.org/IPC/Open2.html. So why was it not installed ? Do i need to install perl again .
Someone has earlier faced this problem - http://www.summarization.com/~radev/mead/email/0160.html but the solution is not working for me . I find no Perl files with the incorrect perl directives . The mead team has been dissolved and there is no one to ask questions but I need to use this software.
I think if some one can explain me the meaning of the error than I can do deeper. Anyone?
It probably means that .../driver.pl doesn't have execute permission. Change the file permissions or call it like
open2($reader, $writer, "perl $FindBin::Bin/driver.pl")
open2($reader, $writer, "$^X $FindBin::Bin/driver.pl")

How to access a simple SOAP Service in Perl

I am currently dabbling around with perl and SOAP, using SOAP::Lite.
I have a simple SOAP server that appears to run fine:
#!perl -w
use SOAP::Transport::HTTP;
use Demo;
# don't want to die on 'Broken pipe' or Ctrl-C
$SIG{PIPE} = $SIG{INT} = 'IGNORE';
my $daemon = SOAP::Transport::HTTP::Daemon
-> new (LocalPort => 801)
-> dispatch_to('/home/soaplite/modules')
;
print "Contact to SOAP server at ", $daemon->url, "\n";
$daemon->handle;
It includes a small class called Demo, which simply retrieves the systems total memory:
Demo.py
#!/usr/bin/perl
use Sys::MemInfo qw(totalmem freemem totalswap);
print "total memory: ".(&totalmem / 1024)."\n";
I have an example of a SOAP client below written in PERL, although I am unsure how to communicate with the server (since the tutorial I am following here goes of on a tangent e.g. retrieve the result of the Demo.py class from the client:
#!perl -w
use SOAP::Lite;
# Frontier http://www.userland.com/
$s = SOAP::Lite
-> uri('/examples')
-> on_action(sub { sprintf '"%s"', shift })
-> proxy('http://superhonker.userland.com/')
;
print $s->getStateName(SOAP::Data->name(statenum => 25))->result;
Any help would be greatly appreciated :)
For the server script, the dispatch_to method takes the path to the package to load, and the name of the package itself. If you pass a third parameter, it will limit the names of the methods made visible by the server. (e.g. 2 methods named memory and time, passing Demo::time as the 3rd param will make memory invisible to the client service.)
File server.pl
my $daemon = SOAP::Transport::HTTP::Daemon
-> new (LocalPort => 801)
-> dispatch_to('/home/soaplite/modules', 'Demo')
;
Your Demo package should be a package with methods that return the values. I couldn't get Sys::MemInfo compiled on my system, so I just used localtime instead. I'm not sure why you named your package Demo.py, but Perl packages must have the extension pm, otherwise they won't be properly loaded.
File Demo.pm
#!/usr/bin/perl
package Demo;
#use Sys::MemInfo qw(totalmem freemem totalswap);
sub memory {
#print "total memory: ".(&totalmem / 1024)."\n";
return "Can't load Sys::MemInfo, sorry";
}
sub time {
my $time = localtime;
return $time;
}
1;
For the client code, there's 2 important pieces that must be properly specified to work, the proxy and the uri. The proxy is the url path to the soap web service. Since you are running the server script as a daemon process, your path is just the web site's url. My computer doesn't have a url, so I used http://localhost:801/. The 801 is the port you specified above. If you were running as a cgi script inside of a different web server (such as Apache), then you would need to specify the cgi script to call (e.g. http://localhost/cgi-bin/server.pl, changing the package in server.pl to SOAP::Transport::HTTP::CGI.
uri is probably the most confusing, but it's the namespace of the xml files returned by the web service. Turn on +trace => 'debug' to see the xml file returned by the web service. The uri should just be the name of the server. Even if you switch ports or to a cgi dispatch method, this uri stays the same.
File test.pl
#!perl -w
use SOAP::Lite +trace => 'debug';
# Frontier http://www.userland.com/
$s = SOAP::Lite->new(proxy => 'http://superhonker.userland.com:801/',
uri => 'http://superhonker.userland.com/');
#might be http://www.userland.com/
#but I could not test sub-domains
print $s->time()->result;
I'll recycle these two answers for tips:
Client of web service in Perl
Remote function call using SOAP::Lite

Why can't I connect to my CAS server with Perl's AuthCAS?

I'm attempting to use an existing CAS server to authenticate login for a Perl CGI web script and am using the AuthCAS Perl module (v 1.3.1). I can connect to the CAS server to get the service ticket but when I try to connect to validate the ticket my script returns with the following error from the IO::Socket::SSL module:
500 Can't connect to [CAS Server]:443 (Bad hostname '[CAS Server]')
([CAS Server] substituted for real server name)
Symptoms/Tests:
If I type the generated URL for the authentication into the web browser's location bar it returns just fine with the expected XML snippet. So it is not a bad host name.
If I generate a script without using the AuthCAS module but using the IO::Socket::SSL module directly to query the CAS server for validation on the generated service ticket the Perl script will run fine from the command line but not in the browser.
If I add the AuthCAS module into the script in item 2, the script no longer works on the command line and still doesn't work in the browser.
Here is the bare-bones script that produces the error:
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
use AuthCAS;
use CGI::Carp qw( fatalsToBrowser );
my $id = $ENV{QUERY_STRING};
my $q = new CGI;
my $target = "http://localhost/cgi-bin/testCAS.cgi";
my $cas = new AuthCAS(casUrl => 'https://cas_server/cas');
if ($id eq ""){
my $login_url = $cas->getServerLoginURL($target);
printf "Location: $login_url\n\n";
exit 0;
} else {
print $q->header();
print "CAS TEST<br>\n";
## When coming back from the CAS server a ticket is provided in the QUERY_STRING
print "QUERY_STRING = " . $id . "</br>\n";
## $ST should contain the received Service Ticket
my $ST = $q->param('ticket');
my $user = $cas->validateST($target, $ST); #### This is what fails
printf "Error: %s\n", &AuthCAS::get_errors() unless (defined $user);
}
Any ideas on where the conflict might be?
The error is coming from the line directly above the snippet Cebjyre quoted namely
$ssl_socket = new IO::Socket::SSL(%ssl_options);
namely the socket creation. All of the input parameters are correct. I had edited the module to put in debug statements and print out all the parameters just before that call and they are all fine. Looks like I'm going to have to dive deeper into the IO::Socket::SSL module.
As usually happens when I post questions like this, I found the problem. It turns out the Crypt::SSLeay module was not installed or at least not up to date. Of course the error messages didn't give me any clues. Updating it and all the problems go away and things are working fine now.
Well, from the module source it looks like that IO::Socket error is coming from get_https2
[...]
unless ($ssl_socket) {
$errors = sprintf "error %s unable to connect https://%s:%s/\n",&IO::Socket::SSL::errstr,$host,$port;
return undef;
}
[...]
which is called by callCAS, which is called by validateST.
One option is to temporarily edit the module file to put some debug statements in if you can, but if I had to guess, I'd say the casUrl you are supplying isn't matching up to the _parse_url regex properly - maybe you have three slashes after the https?