Perl cgi compilation error in autovivication.pm - apache

I'm using a perl cgi script that uses our own libraries, which use the "no autovivification" pragma. E.g.
/usr/lib/company/mysim.cgi:
#!/usr/bin/perl -w
use strict;
# ... other use
use Company::Module1;
/usr/lib/perl5/Company/Module1.pm
package Company::Module1;
no autovivification;
use strict;
use warnings;
Approximately 50% of the time, when accessing the URL to reach the cgi script the compilation fails with...
[Fri Dec 04 15:40:10.744901 2015] [:error] [pid 30455:tid 2961136448] Bareword "A_HINT_STRICT" not allowed while "strict subs" in use at /usr/lib/i386-linux-gnu/perl5/5.20/autovivification.pm line 144.\nBareword "A_HINT_WARN" not allowed while "strict subs" in use at /usr/lib/i386-linux-gnu/perl5/5.20/autovivification.pm line 144.\nBareword "A_HINT_FETCH" not allowed while "strict subs" in use at /usr/lib/i386-linux-gnu/perl5/5.20/autovivification.pm line 144.\nBareword "A_HINT_STORE" not allowed while "strict subs" in use at /usr/lib/i386-linux-gnu/perl5/5.20/autovivification.pm line 144.\nBareword "A_HINT_EXISTS" not allowed while "strict subs" in use at /usr/lib/i386-linux-gnu/perl5/5.20/autovivification.pm line 144.\nBareword "A_HINT_DELETE" not allowed while "strict subs" in use at /usr/lib/i386-linux-gnu/perl5/5.20/autovivification.pm line 144.\nCompilation failed in require at /usr/lib/company/mysim.cgi line 14.\nBEGIN failed--compilation aborted at /usr/lib/company/mysim.cgi line 14.\n
(taken from /var/log/apache2/ssl/error.log as this script sits on the https port).
My environment is:
- debian jessie (8.2)
- tomcat7
- apache2 (2.4)
- perl 5.20.2
- libautovivification-perl 0.12-1+b1
My questions are:
Has anyone seen this before? It seems odd that the autovivification module fails to compile due to a "use strict" pragma.
Can anyone explain the intermittent nature of the compilation error? Even more odd, the cgi fails to compile ~half the time, and works fine (i.e. runs and returns expected results) the other ~half.
Thanks for your time.
09/12/2015: Some additional information...
Thanks all for the feedback.
There's no explicit creation of threads, though this is in the context of apache so there's presumably threading of requests.
The root cause does seem to be a failure in the XSLoader. At least this minimal working example...
package autovivification;
use 5.008_003;
use strict;
use warnings;
our $VERSION;
BEGIN {
$VERSION = '0.12';
}
BEGIN {
require XSLoader;
XSLoader::load(__PACKAGE__, $VERSION);
}
my %bits = (
strict => A_HINT_STRICT,
warn => A_HINT_WARN,
fetch => A_HINT_FETCH,
store => A_HINT_STORE,
exists => A_HINT_EXISTS,
delete => A_HINT_DELETE,
);
compiles, whereas this
package autovivification;
use 5.008_003;
use strict;
use warnings;
our $VERSION;
BEGIN {
$VERSION = '0.12';
}
#BEGIN {
# require XSLoader;
# XSLoader::load(__PACKAGE__, $VERSION);
#}
my %bits = (
strict => A_HINT_STRICT,
warn => A_HINT_WARN,
fetch => A_HINT_FETCH,
store => A_HINT_STORE,
exists => A_HINT_EXISTS,
delete => A_HINT_DELETE,
);
fails with the same error.
So, I'll go a-poking around for a load error in the apache logs.... somewhere.
Thanks again for your time.
16/12/2015: Update - Fixed
The root cause was mod_perl, combined with a (possible) change between apache 2.2 and 2.4. The apache configuration for the script, which gives it a ScriptAlias URI of /cgi-bin/script, occurs before setting up the URI /cgi-bin to be handled by mod_perl. In apache 2.2, this ordering seems to be important and the script was not handled by mod_perl. However, in apache 2.4 the ordering does not seem to be important and the script is now handled by mod_perl.
The error arose because this script was not (and never meant to be) handled by mod_perl. The fix was to change the URI for the script to /somethingelse/script.
Thanks to everyone for the comments.

The root cause was mod_perl, combined with a (possible) change between apache 2.2 and 2.4. The apache configuration for the script, which gives it a ScriptAlias URI of /cgi-bin/script, occurs before setting up the URI /cgi-bin to be handled by mod_perl. In apache 2.2, this ordering seems to be important and the script was not handled by mod_perl. However, in apache 2.4 the ordering does not seem to be important and the script is now handled by mod_perl.
The error arose because this script was not (and never meant to be) handled by mod_perl. The fix was to change the URI for the script to /somethingelse/script.
– HalfOpenedEye

Related

My Perl warnings are FATAL and I don't know why

I have two servers with the same configurations: httpd + mod_perl (I thought the settings were 100% the same), but in one server I got some perl warnings, while in the other server the same warnings get me FATAL errors. Look:
Server A log:
Use of uninitialized value in numeric eq (==) at
Server B log:
[Wed Jun 08 14:32:47 2016] [error] Use of uninitialized value in string eq at
In server A the request flow goes on and the user gets the desired result, but in server B the user gets a 500 error.
I am using
use strict;
use warnings;
in the file on both servers.
Any thoughts ?
Example of the code causing this warning/FATAL:
$allowed_sellers = any { $_ == $user->{user_id} } (111,123,222,345);
UPDATE:
I found this code in a module that I am using (Moo):
package Moo::_strictures;
use strict;
use warnings;
sub import {
if ($ENV{MOO_FATAL_WARNINGS}) {
require strictures;
strictures->VERSION(2);
#_ = ('strictures');
goto &strictures::import;
}
else {
strict->import;
warnings->import;
}
}
1;
But the env variable MOO_FATAL_WARNINGS seems to not be defined. Any thougts ?
SOLVED:
Guys, thanks a lot! We have finally discovered the problem: In server A the version of module Moo was 1.003 while server B was using a newer version 2.000001
Before version 2, calling use Moo; enabled strictures, which makes all warnings fatal except for a few categories. This caused a lot of problems*, so warnings are no longer fatal in version 2 and up.
To fix, upgrade Moo to the latest version. While you're at it, you should really fix the cause of the warnings, too.
* See the following discussions:
Default fatalization of warnings needs mst's clarification before new major strictures
fatal warnings are a ticking time bomb
Moo 2 and strictures 2

Composer needs a proxy to install laravel apparently, where do I get that? can I set it up myself using apache?

I was trying to get started with Laravel just last night, so I tried to install it with composer but it wouldn't go through and kept sayin The "https://packagist.org/packages.json" file could not be downloaded: SSL operation failed with code 1. , so I looked around and found out that you need to tell composer to use a proxy.(q1 q2 q3).
Well now this might sound silly but honestly I had no idea what a proxy was until last night, so I went and studied it a bit and I got this far:
"Proxy means to act on behalf of another. In the context of a Web server, this means
one server fetching content from another server, then returning it to the client"
and apparently there's 2 kinds of proxy: forward proxy and reverse proxy.
In those 3 pages that I just showed, they were saying before runing php bin\composer global require "laravel/installer=~1.1" you have to set an env var like this: set http_proxy=username:password#proxy_server:port
So now my question is: I still don't know where can I get a proxy like that, should I set it up myself with apache? is that gonna even work? what do I do?
Your thoughts would be appreciated, thank you.
Edit: Environment info:
I'm on windows 7
installed xampp-win32-5.6.14-0-VC11-installer
all of those 5 important extensions are all enabled in phpinfo()
the path= C:\Users\UserName\AppData\Roaming\Composer\vendor\bin is set in environment variables
here's a picture of the whole error
here's the result of php -m i.stack.imgur.com/wz030.png
Some stuff that I tried:
I went into these sites: proxy4free.com us-proxy.org proxylist.hidemyass.com ultraproxies.com,
I tried this: set https_proxy=https://xteamweb.com:xteam#75.55.165.86:8088 and this one: set http_proxy=http://1proxy.space and many others from those sites: i.stack.imgur.com/6YWyp.png
but no matter what, this is the result of all of them: i.stack.imgur.com/mqOrP.png
Still nothing...
Ok here's the solution, if you're having the same problem:
1:
Make sure these are all uncommented in php.ini:
extension=php_openssl.dll
extension=php_curl.dll
extension=php_sockets.dll
extension_dir="E:\xampp\php\ext"
browscap="E:\xampp\php\extras\browscap.ini"
Add these 2 lines at the end of php.ini
curl.cainfo=c:\openssl-1.0.2d-win32\ssl\cert.pem
openssl.cafile=c:\openssl-1.0.2d-win32\ssl\cert.pem
2:
Run this: php -r "print_r(openssl_get_cert_locations());"
and you'll get:
Array
(
[default_cert_file] => c:/openssl-1.0.2d-win32/ssl/cert.pem
[default_cert_file_env] => SSL_CERT_FILE
[default_cert_dir] => c:/openssl-1.0.2d-win32/ssl/certs
[default_cert_dir_env] => SSL_CERT_DIR
[default_private_dir] => c:/openssl-1.0.2d-win32/ssl/private
[default_default_cert_area] => c:/openssl-1.0.2d-win32/ssl
[ini_cafile] => c:\openssl-1.0.2d-win32\ssl\cert.pem
[ini_capath] =>
)
3:
Make these folders:
c:\openssl-1.0.2d-win32
c:\openssl-1.0.2d-win32\ssl
c:\openssl-1.0.2d-win32\ssl\certs
c:\openssl-1.0.2d-win32\ssl\private
Download this: http://curl.haxx.se/ca/cacert.pem.
Rename it to cert.pem and put it in c:\openssl-1.0.2d-win32\ssl\.
Rename it to cert.crt and put it in c:\openssl-1.0.2d-win32\ssl\certs\.
So:
c:\openssl-1.0.2d-win32\ssl\cert.pem
c:\openssl-1.0.2d-win32\ssl\certs\cert.crt
4:
Download https://getcomposer.org/Composer-Setup.exe and install it, It will no longer gives u the ERR_CONNECTION error.
Go to c:\users\YOURUSERNAME.
composer.bat should be there, if not create it yourself.
Add c:\users\YOURUSERNAME to your path.
Edit composer.bat and delete what's in it and put this in #php "%~dp0composer.phar" %*.
Download https://getcomposer.org/composer.phar.
Place composer.phar in c:\users\YOURUSERNAME.
5:
Done.
Composer will now install laravel using: composer global require "laravel/installer=~1.1" with no problem.
(Plus: now composer command is available globally instead of using it like: php composer.phar or php bin\composer).

open_basedir restriction when parsing LESS files

I got a warning when parsing my "Twitter BootStrap" files and saving them on disk in my less-cache folder.
Warning: is_file(): open_basedir restriction in effect. File(/../../lib/bootstrap/less/reset.less.less) is not within the allowed path(s): (/var/www/vhosts/example.com/:/tmp/) in /var/www/vhosts/example.com/httpdocs/wp-content/modules/wp-less/lessc/lessc.inc.php on line 80
I'm using (for example) #import "../../lib/bootstrap/less/reset.less"; in the main file that I'm parsing.
The funky thing is, that the first stylesheet gets the extension two times: reset.less.less - the other ones not. Another thing that keeps me wondering, is why the heck there's a leading / in front of the files.
Some data about the environment and server:
PHP 5.3.3
Wordpress 3.4.2
The WP-LESS Plugin (yes, I commit to this repo), which uses the LESSc library - which throws the error from here.
php.ini
include_path = ".:..:"
upload_temp_dir _no value/not set_
open_basedir = "/var/www/vhosts/example.com/:/tmp/"
Thanks for any help in advance!

How do I include a file in Apache config without generating an error when it doesn't exist?

This is for a shared config file that should include another file if it exists, but still work otherwise. If I do
Include foo.conf
and foo.conf doesn't exist, apache will complain:
could not open document config file /etc/httpd/conf/foo.conf
I came up with a clever solution, though there may be a better way. Put one of the characters in brackets so Apache will treat it as a glob pattern, which is allowed to match zero files without causing an error. E.g.:
Include foo.con[f]
According to http://httpd.apache.org/docs/2.4/mod/core.html#include you could use "IncludeOptional":
Alternatively, the following command will just be ignored in case of missing files or directories:
IncludeOptional conf/vhosts/*/*.conf
IncludeOptional foo.conf
Apache httpd version 2.3.6 and later
https://httpd.apache.org/docs/2.4/mod/core.html#includeoptional
I tried the same as Wouter Van Vliet, but I still got errors. Then I found this link. I added this snippet to my /etc/apache2/apache2.conf and it works like a charm!
Note: You need mod_perl for it!
Here is the code:
<perl>
use File::stat;
foreach $file (glob '/srv/www/vhosts/*/conf/vhost.conf') {
my $stat = stat($file);
if ($stat->uid != 0 || $stat->gid != 0) {
warn "$file is not owned by root:root, skipping!\n";
next;
}
if ($stat->mode & 0002) {
warn "$file is world-writable, skipping!\n";
next;
}
push #Include, $file;
}
</perl>

Apache mod_perl2 migration problem

I have an apache2 config file under /etc/init.d/apache2/conf.d/ which uses Perl Sections.
I am just trying to test if a module is loaded and configure apache as appropriate.
if( Apache->module( "mod_ssl.c" ) )
{
...
} else { ... }
This is the error I see though when restarting. I've also tried Apache2->method but get same error.
# /etc/init.d/apache2 restart
Restarting web server: apache2Building Appliance configuration for Debian 5.0.7
Syntax error on line 73 of /etc/apache2/conf.d/foobar.conf:
\t(in cleanup) Can't locate object method "module" via package "Apache" (perhaps you forgot to load "Apache"?) at /etc/apache2/conf.d/foobar.conf line 357.\n
failed!
I don't think it is an #INC problem... And apache and libapache2-mod-perl2 packages are both installed. In fact if I comment that line out the rest of the perl actually runs fine.
perl -e 'print join "\n",#INC'
/etc/perl
/usr/local/lib/perl/5.10.0
/usr/local/share/perl/5.10.0
/usr/lib/perl5
/usr/share/perl5
/usr/lib/perl/5.10
/usr/share/perl/5.10
/usr/local/lib/site_perl
I've also tried using the Apache::compat and "Apache2->module".
I suspect the problem is something is missing in startup.pl - but I've been googling and reading the mod perl docs and going round in circles. Any suggestions stackoverflow???
BTW- my startup.pl:
#!/usr/bin/perl -w
use strict;
use lib qw( /usr/lib/perl5/ /usr/lib/perl5/Bundle /usr/lib/perl5/Apache2 ) ;
BEGIN
{
use Apache2 ();
my $hostname = `hostname`;
}
use Apache;
use Apache::DBI ();
use Apache2::Const ();
use Apache2::Log ();
use Apache2::URI ();
use Apache2::compat;
use LWP::UserAgent ();
use DBI() ;
1;
The documentation on porting from 1.0 to 2.0 suggests Apache2::Module::loaded()