Link to home
Start Free TrialLog in
Avatar of datastarstar
datastarstar

asked on

Perl script won't run using mod_fcgid

On a new RHEL 7.5 server, I'm trying to get mod_fcgid to run on a simple perl script. I had previously been using mod_perl on an older server, with no issues.  I have confirmed that fcgi_module is installed and running. Server is Apache 2.4.6.

httpd.conf:
AddHandler fcgid-script .fcgi

hello.fcgi:
#!/usr/bin/perl
print "Content-Type: text/html\n\n";
print "hello world";

Error log:
[Fri Oct 12 17:33:50.655808 2018] [fcgid:warn] [pid 13551] (104)Connection reset by peer: [client xxx.xxx.xxx.xxx:xxxxxxx] mod_fcgid: error reading data from FastCGI server
[Fri Oct 12 17:33:50.655891 2018] [core:error] [pid 13551] [client xxx.xxx.xxx.xxx:xxxxxx] End of script output before headers: hello.fcgi
Avatar of David Favor
David Favor
Flag of United States of America image

Likely problem is mod_perl was configured to handle outputting headers. This is typical.

If you switch to any other mechanism, you must rewrite all your scripts to output correct headers... or somehow setup some common script to run first, which produces all headers.
Avatar of datastarstar
datastarstar

ASKER

Thanks, but it's the "somehow" that I need help with.  A "common" script sounds like a good approach, but how?
You'd write your common code in a PERL .pl or .pm file + ingest this file via require (.pl) or use $module (.pm) in each PERL script you use.

Or... use an off the shelf module like CGI (gold standard) which will likely suffice in most situations.

As for "how you do this", refer to the CGI module docs + either use this module as-is or extract ideas to create your own common class file.
I'm really looking for specific details vs a general answer. I now have the following. I don't get an error, but nothing prints to the browser.

CGI is too slow. My main application script is quite long, and must run hundreds of users concurrently.

#!/usr/bin/perl
use CGI::Fast;

while (my $q = CGI::Fast->new) {
print("Content-Type: text/plain\n\n");
foreach $var (sort(keys(%ENV))) {
$val = $ENV{$var};
$val =~ s|\n|\\n|g;
$val =~ s|"|\\"|g;
print "${var}=\"${val}\"\n";
}
}
This article is not from apache, but from the nginx server, which only runs stuff using fcgi. (if you want speed...)...
it realy doesn't matter as FCGI always is run as a free running process outside of the webserver.
(as opposed to mod_perl/mod_php which runs inside apache).

Here is the site: https://nginxlibrary.com/perl-fastcgi/

it downloads a wrapper perl script to handle all FGCI details...
wget http://nginxlibrary.com/downloads/perl-fcgi/fastcgi-wrapper -O /usr/bin/fastcgi-wrapper.pl
wget http://nginxlibrary.com/downloads/perl-fcgi/perl-fcgi -O /etc/init.d/perl-fcgi
chmod +x /usr/bin/fastcgi-wrapper.pl
chmod +x /etc/init.d/perl-fcgi
update-rc.d perl-fcgi defaults
insserv perl-fcgi

Open in new window


and then can user regular perl scripts like:
#!/usr/bin/perl

print "Content-type:text/html\n\n";
print <<EndOfHTML;
<html><head><title>Perl Environment Variables</title></head>
<body>
<h1>Perl Environment Variables</h1>
EndOfHTML

foreach $key (sort(keys %ENV)) {
  print "$key = $ENV{$key}<br>\n";
}

print "</body></html>";

Open in new window



This server process will listen to FCGI calls on 127.0.0.1:8999
Now you somehow have to send FCGI request to this socket....
(I am no apache user so....)
noci, this sounds really promising and if I can get it to work under Apache, it is exactly what I want. I tried to modify the instructions to run with Apache. The wrapper script is running (I can see it in top), but I don't think my "regular" perl scripts are running within the fcgi process. How can I verify this?

I am using a .pl or .cgi extension for my other script (the example envir script). It runs without error, but if I use .fcgi extension instead, it throws an error.
You can verify your scripts are running various ways.

1) Open a log file + write a message.

2) Use Sys::Syslog + write a message via rsyslogd to your normal system log file.

3) Insert a sleep(long time) into your perl script, then use ps to see if it's running.
To clarify, I can verify my script runs, but what I am asking is how to tell if it is running as a fgci script.
That would produce output in a browser...
24hour hindsight...,   the wrapper may need to be adjusted for apache, apache seems to start it's own wrappers.
Then there must also be a way to hand a socket to them. (and the wrapper must be able to pick it up).

The wrapper i posted is for nginx...,  Years ago i left apache because it was drowning out my system with too heavy processes.
If i had (ok RPi) 5 sessions it would crawl.. I then switched to lighttpd  which allowed around 20 sessions on the same hardware & scripting.
Later i moved to nginx   as there were more configuration descriptions available compared to lighttpd.

Nginx is more flexible in this.. It can have multiple fcgi backends f.e. one optimized for small requests, another for large requests...
And they can run on different systems, no need to on board of the webserver system.
imho nginx is more capable of running a website that apache is...   YMMV though.
In the end, I went back to using mod_perl -- was able to install this on RHEL 7 with some outside assistance. Thanks to all who contributed.
ASKER CERTIFIED SOLUTION
Avatar of datastarstar
datastarstar

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial