Subject: | tmpdir (/tmp) isn't shared across a server cluster |
I've just tried out the CaptchasDotNet package on my website that's
hosted on www.easyspace.com. I used the unreleased version from
http://captchas.net/sample/perl/WebService/CaptchasDotNet.pm (referenced
from http://captchas.net/sample/perl/) rather than version 0.06, but the
fault is here too.
I've discovered that _init() uses File::Spec->tmpdir as the place to
create the CaptchasDotNet directory that is subsequently used as a
database of used "random" codes by the random() and
_verify_random_string() functions during the challenge and responses phases.
The problem is that tmpdir returns '/tmp' on my webserver, but the
hosting company runs a cluster and this filesystem isn't cross-mounted,
so if the browser gets directed to a different physical server between
the challenge and the response then "verify($random)" fails when it
shouldn't.
The fix is to ensure that the database (directory) is shared across all
servers in the cluster, so I've worked around it by doing this:
my @document_root = File::Spec->splitdir($document_root);
$#document_root--; # lose last directory (www)
$ENV{"TMPDIR"} = File::Spec->catdir(@document_root, 'tmp');
This works because my FTP login directory is the parent of "www" which
is the DOCUMENT_ROOT for the site.
Note that I have to do a bit of messing around because
$ENV{'DOCUMENT_ROOT'} doesn't point to the right place, so I have to
subtract PATH_INFO from PATH_TRANSLATED, which is what ends up in
$document_root in my script.
I think your best way around this is to have a new parameter to the
new() function which allows the user to specify the location of the
database directory.
Anyway, thanks for a very useful package. It worked perfectly when I
was testing it on my (non-clustered) PC!
Kevin