Hello monks!
I had to add a filter to an old program that uses WWW::Salesforce::Simple and was packaged in an EXE (for Windows) using pp, but after the change in a up-to-date Activeperl distribution, I got:
500 Can't connect to www.salesforce.com:443 at WWW/Salesforce.pm line 497.As the perl script runs OK when invoqued from the command line, but fails in the EXE, I tried to find the problem tracing the files manually (with a text editor).
I've spend many days tracking this issue reading docs, RT bug reports, and posts in many forums, but always far away the real root of the problem.
I started by searching which script in perl library generates that error message. As I found some, I tried to discard the ones that were not packaged in the EXE by looking the dependencies. First, I tried some tracing tools like Devel::Trace, but it doesn't work in EXE as I couldn't figure out how to pass -d:Trace argument to it (I even tried placing it in the first line of my script). Then I found that @INC has the info I wanted. Later, I learned that renaming the EXE file as ZIP, I could browse it contents.
I did a directory compare from the extracted files from the old and new EXE, and identified which modules have changed lately, specially those that are dependencies of WWW::Salesforce module. The most relevant ones where related to HTTPS and SSL.
I found a hint somewhere in this site about including the following in my script to enable a trace in that module:
use IO::Socket::SSL qw(debug99);Gotcha! It is not being able to load the SSL CA certificates, which is mandatory (and the default) to verify host names for HTTPS connections from some time ago. A quick review to the contents of the ZIP archive (renamed EXE file), I could confirm that cacert.pem file was not included with the Mozilla::CA module. The workaround was to compile with the following option in pp:
-a "C:\Perl\lib\Mozilla\CA\cacert.pem;lib/Mozilla/CA/cacert.pem"Actually, I tried many forms of that argument until it was stored in the proper directory inside the package (EXE file). But it didn't work!!! The file remained unable to be loaded by Net::SSLeay module.
Some debug instructions introduced in IO::Socket::SSL pointed to LWP::Protocol::https, which in turn pointed again to Mozilla::CA.
Debugging CA.pm file from Mozilla::CA, I found the following line:
my $file = File::Spec->catfile(dirname(__FILE__), "CA", "cacert.pe +m");
The problem was the __FILE__ token, which returns an absolute path when running perl in command line, but a relative path if run when packed with PAR::Packer into the EXE file. There is a RT report about this in another context, where a workaround was done.
CA.pm tried to transform a relative path into an absolute one unsuccessfully using Cwd, which appended the location of the EXE file to the path instead the real cache area location that PAR uses in runtime.
My workaround for this case required to find how to get the current temp dir for the cache, and I found it inside @INC, so I changed the previous line into this one:
my $file = File::Spec->catfile(dirname($INC{'Mozilla/CA.pm'}), "CA +", "cacert.pem");
This way, the Mozilla::CA module works fine both in command line and inside an EXE file.
Happy end? No... I need some help in the following:
Thanks in advance!
In reply to __FILE__, pp (PAR::Packer) and extra files by vitoco
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |