How do you use the Apache "ScriptInterpreterSource Registry-Strict" directive? - perl

i run Apache web server on windows in order to work on some Perl CGI scripts. in production these scripts run on a linux box, and in the source code repository they all have shebangs like: #!/usr/bin/perl, but on my windows machine the shebangs would be #!c:\perl\bin\perl.exe, so i have a conflict with the source code base.
enter the Apache ScriptInterpreterSource directive.
i've been trying to make it work, based on what i can google. but so far no luck. i have:
added these things to the appropriate directive
AllowOverride None
Options Indexes FollowSymLinks ExecCGI
Order allow,deny
Allow from all
ScriptInterpreterSource Registry-Strict
added:
AddHandler cgi-script .cgi
edited my registry and added a new String to
HKEY_CLASSES_ROOT\.cgi\Shell\ExecCGI\Command=C:\Perl\bin\perl.exe
now, i know that CGIs work on this server as long as they have the right shebang.
but when i try to access a CGI without a shebang the apache log spits out:
No Exec CGI Verb found for files of
type '.cgi'
any thoughts, insights, or even wild-ass guesses would be appreciated.
thanks.

It sounds like the ScriptInterpreterSource line is being ignored. If it's set to Registry or Registry-Strict, it should ignore the shebang lines and use the registry only.
Also, the Apache 2.2 docs have a slightly different location for the registry key:
HKEY_CLASSES_ROOT\.cgi\Shell\ExecCGI\Command\(Default) => C:\Perl\bin\perl.exe -wT

This works for Python scripts as well. I did the following to fix my Apache install to ignore the shebang requirement in my scripts. Without this the shebang is required in the current version of Apache 2.4 - or at least it was in mine.
# tell apache to use registry - this requried a registry hack
# to the following:
# [HKEY_CLASSES_ROOT\.py\Shell\ExecCGI\Command] = "c:\\python\\python.exe"
ScriptInterpreterSource Registry-Strict

Instead of running your perl code in separate CGI processes, consider using mod_perl (See http://perl.apache.org).
Mod_perl is a lot more efficient, as the Perl code is loaded and parsed only once and then runs directly within the Apache processes with no need to start or communicate with other processes.

Related

Nginx FastCGI Perl configuration

I am trying to get FastCGI to work with Perl CGI in FastCGI mode. By that I mean that I can run Perl CGI scripts on Nginix without any issues but it does not appear (based on performance measurements) that my scripts are running in FastCGI mode. I've seen mentions about spawn-fcgi but nothing recent or details on how to implement with current versions of Nginx and Ubuntu.
I am relatively new to Linux.
Environment info:
Ubuntu 22.04 hosted in the "cloud"
nginx version: nginx/1.18.0 (Ubuntu)
Tutorial I followed: https://techexpert.tips/nginx/perl-cgi-nginx/
I have installed fcgiwrap.
CGI works, HTTPS works.
I am enclosing the bulk of my Perl CGI script within
use CGI::Fast;
while(my $q = new CGI::Fast)
{
# all my code
}
My script is doing a simple write and query from a very small SQLite3 database (4 columns, 500 rows, 290k db size).
I am testing across the Internet.
Script execution performance is about half of a second (.42 seconds per page) or 345ms. That is about the same as IIS Windows CGI.
I also saw that requesting a simple HTML file only has marginally better performance.
I understand that there is a lot more to performance testing than the preceding. The point is that I think there is something missing with my FastCGI configuration. I imagine it has something to do with me needing to launch the Perl FastCGI script somehow and then somehow connect that to Nginx. If anyone can point me in the right direction or provide example config files, that would be great. Thanks all!

Configure Apache2 to allow clients to run Perl Scripts in cgi-bin

I have two perl scripts; one acts like the client (and queries); the other acts like the server and returns information. On an Apache server (not my own) they work perfectly.
However, on my ubuntu/Linux_box with Apache2 (that I set up) they do not; I get a 404 not found error. The cgi-bin directory is located at usr/lib/cgi-bin. What specific files/settings etc have to be changed/altered/etc. And, what specific changes/alterations/etc. need to be made?
Edit:
I changed the httpd.conf and tried both of the following (but neither worked):
ScriptAlias /diag/ /usr/lib/cgi-bin
ScriptAlias /diag/ /usr/lib/cgi-bin/
I am using a perl script as the client, and it did not work. For illustration purposes I attempted to locate the file with the browser shown in the 2nd pic.
If they are receiving 404, it means that the file does not even exist in the correct location. In the httpd.conf look for the "ScriptAlias" directive that has an entry for cgi-bin, should be something like
ScriptAlias /cgi-bin/ /some_folder/cgi-bin
Once you know the correct folder, the 404 error should go away.
Two other points -
1. For cgi files, ensure that the execute bit is set.
2. Verify that the location of perl matches the one in the perl script.

How do you deploy a PSGI script in Apache without restarting?

I want to deploy a PSGI scripts that runs in Apache2 with Plack. Apache is configured with:
<Location "/mypath">
SetHandler perl-script
PerlResponseHandler Plack::Handler::Apache2
PerlSetVar psgi_app /path/to/my/script.psgi
</Location>
When I test the script with plackup, the --reload parameter watches updates on the .psgi file. In the production environment it is fine that Apache and Plack do not check and restart on each change for performance reasons, but how can I tell them explicitly to restart Plack::Handler::Apache2 and/or the PSGI script to deploy a new version?
It looks like Plack regularly checks for some changes but I have no clue when. Moreover it seems to create multiple instances, so I sometimes get different versions of script.psgi when at /mypath. It would be helpful to manually flush perl response handler without having to restart Apache or to wait for an unknown amount of time.
The short answer is you can't. That's why we recommend you to use plackup (with -r) for quick development and use Apache only for deployment (production use).
The other option is have a development apache process, and set MaxRequestsPerChild to a really small value, so that you will get a fresh child spawned in a very short period of time. I haven't tested this, and doing so will definitely impact the performance of your entire httpd, if you run the non-development application running on the same process (which is a bad idea in the first place anyway).
Apache2::Reload (untested)
You can move your application out of the appache process,
e.g.
FastCgiExternalServer /virtual/filename/fcgi -socket /path/to/my/socket
an run your programm with
plackup -s FCGI --listen /path/to/my/socket --nproc 10 /path/to/my/script.psgi
This way you can restart your application without restarting apache.
if you save the pid of the main fcgi process (--pid $pid_file)
you can easyly restart an load your new code.
There is also a module avail to manage (start,stop, restart) all your fcgi pools:
https://metacpan.org/pod/FCGI::Engine::Manager::Server::Plackup (not tested)

Perl CGI or CGI::Fast under Apache 2.2 on Debian Lenny

I have 2 different web servers on a Debian Lenny machine. One is running FastCGI (TRAC) and the other web server is running PHP and some CGI scripts. So I have currently the 2 Apache2 modules enabled (cgi and fcgi) and the 2 vhosts setup accordingly. I have no other particular interest for these both modules running at the same time.
So I want to keep ONLY Apache fastcgi module running as it looks to be the more efficient one.
Could you pls confirm the following assessments to be right or correct ?
1- I will have nothing to do/change for the TRAC site (already running fcgi)
2- I will have to tune the other web server vhost to be set with an handler to fastcgi scripts
3- I will have to change only the perl modules from "use CGI" to "use CGI::Fast"
4- I will be able to keep the rest of the perl existing CGI scripts w/o other changes
5- I do not need to use CGI::Apache but CGI::FastCGI (i/o the current CGI module) in the web server scripts
I hope my point is clear as it's all a bit foreign to me ...
Thx
EDIT:
thx for the hints to Naveed and J-16,
Here is what I did to get it working if it can help others :
hum, installed CGI::Fast with CPAN, then it works better..
On Debian with libperl already installed
perl -MCPAN -e shell
cpan> install CGI::Fast
changed filename from *.cgi to *.fcgi,
included the fastcgi while loop as adviced below by Naveed,
setup the apache concerned vhost with the right handler for fastcgi (See fastcgi doc)
enabled the Apache fastcgi module (a2enmod fastcgi) and disabled the cgi module,
checked the fastcgi.conf file in the Apache settings,
restarted Apache,
checked the fastcgi running as an Apache sub process (ps -afx),
fixed some script issues, already in.. but newly appearing when running fastcgi, as adviced (errors detected by checking the Apache logs),
EDIT: adapted the file upload code as the initial script did not work anymore (still don't understand why), so I had to replace the while loop by a such one:
open(FILE,">$upload_dir/$file_name")
while ($bytes_count = read($file_query,$buffer,2096)) {
$size += $bytes_count;
print FILE $buffer;
}
close(FILE);
done.
World is not yet perfect but it finally works.
You will have to do a little more than just change use CGI to use CGI::Fast. Make sure you wrap you CGI scripts with a while loop, as the documentation states http://p3rl.org/CGI::Fast
use CGI::Fast;
while (CGI::Fast->new()) {
# The original CGI code goes in here
}

mod_perl 2 variable and process corruption

We've just ported a fairly large codebase from an ancient Perl 5.005.03 CGI environment to mod_perl 2, and now that it's undergoing a public beta there are a few, possibly related, issues we're encountering from time to time. These build up until we have to restart the server.
All of our code compiles under use strict, but has been previously called as a compiled, run and discarded CGI script. Problems we've encountered so far: setting $| or calling STDOUT->autoflush(1); using old-style global filehandles (open(ERRORFILE, $errorfile) rather than open(my $fh_error, $errorfile)). Also calling system() - shortly after we started the public beta, we spotted e.g. /bin/tail or /usr/sbin/sendmail listening on ports 80 and 443, which stopped the server from being restarted. I've since rewritten that code to use pure-Perl methods, and we no longer have that problem.
Two issues remain. The first one is that the logs are full of mod_perl complaining about constants having been redefined, e.g.
Constant subroutine ModPerl::ROOT::ModPerl::PerlRun::usr_local_..._cgi_forgotpassword::O_CREAT redefined at /usr/lib/perl5/ModPerl/Util.pm line 69.
Also, occasionally seemingly core variables will get trashed. One of our core in-house modules logs information about the PID and name of the script, and produced information like this:
20090202-233948-32154:Started script /usr/local/.../cgi/account/renewalcalendar
20090202-233948-32154:Ended script /usr/sbin/apache2
At other times the process ID will end up as undef. This is rare and intermittent.
Secondly, and also intermittently, we will occasionally see garbage collection not kick in. (Perhaps an issue of weak references? But nearly all of the time everything works fine.) The most immediate symptom of this is database handles opened that are never closed, but when I delve deeper into the issue, it becomes apparent that there's a DBI object stored in a standard Perl hash object, and that object's DESTROY method is (rarely and intermittently) not called.
We're running Debian 5.0 (Lenny), Perl 5.10.0, Apache 2.29, mod_perl 2.0.4, openSSL 0.9.8g. I can provide more information if necessary, but I think that's the basics.
The salient parts of the apache config, being /etc/apache2/sites-enabled/*sitename*, are (some bits redacted for confidentiality reasons):
<VirtualHost ...:443>
<Directory />
Options SymLinksIfOwnerMatch
AllowOverride None
</Directory>
<Directory /usr/local/.../cgi>
SetHandler perl-script
PerlResponseHandler ModPerl::PerlRun
PerlOptions +ParseHeaders
Options +ExecCGI
</Directory>
</VirtualHost>
There's some SSL, rewrites and redirection stuff going on there, but that's the important stuff.
Does this sound familiar to anyone? Alternatively, can anyone recommend any way of debugging the problem further?
For your memory problem: you need to call weaken (from standard module Scalar::Util)