Apache-PAR
view release on metacpan or search on metacpan
next;
}
my $unpackdir = $class->unpack_par($file, $tempdir);
unless(defined($unpackdir)) {
print STDERR "Unable to unpack $file. Skipping.\n";
next;
}
$conf =~ s/##UNPACKDIR##/$unpackdir/g;
$UNPACK_LIST{$file} = $unpackdir;
# TODO: Use UNPACK_LIST in handler, etc to reload changed content.
}
unless ($mod_perl::VERSION < 1.99) {
$err = Apache->server->add_config([split /\n/, $conf]);
} else
{
Apache->httpd_conf($conf);
}
die $err if $err;
}
map {$PARFILE_LIST{$_} = 1;} @pars;
}
sub unpack_par {
my $class = shift;
my($par, $tmpdir) = @_;
require File::Spec;
require File::Path;
require Digest::MD5;
warn "[PAR] unpacking '$par'\n" if DEBUG;
my $zip = Archive::Zip->new;
my $rv = $zip->read($par);
unless($rv == AZ_OK) {
print STDERR "Unable to read ZIP file '$par': error code $rv";
return undef;
}
$tmpdir ||= File::Spec->tmpdir;
unless($tmpdir) {
print STDERR "no temp directory specified";
return undef;
}
unless(-d $tmpdir) {
print STDERR "temp dir '$tmpdir' does not exist or is not a directory";
return undef;
}
my $tmppar = File::Spec->catdir($tmpdir, 'par', (File::Spec->splitpath($par))[1,2]);
# Instead of using full path, this will append MD5
# my $fh;
# unless(open $fh, '<', $par) {
# print STDERR "unable to read '$par': $!";
# return undef;
# }
# binmode($fh);
# my $md5 = Digest::MD5->new->addfile($fh)->hexdigest;
# my $tmppar = File::Spec->catdir($tmpdir, 'par', $md5);
# close($fh);
warn "[PAR] unpack dir is '$tmppar'\n" if DEBUG;
# mtime check for if MD5 approach isn't used
if (-d $tmppar) {
if (DEBUG) {
warn "[PAR] archive has been unpacked previously\n";
warn "[PAR] directory age: ", -M $tmppar, "\n";
warn "[PAR] archive age: ", -M $par, "\n";
}
return $tmppar if (stat($tmppar))[9] > (stat($par))[9];
warn "[PAR] removing old unpack dir '$tmppar'" if DEBUG;
File::Path::rmtree $tmppar;
}
# XXX Add signature check here
# unpack the files
foreach my $member ($zip->members) {
# $member->fileName is always in Unix format
# See also Archive::Zip::_asLocalName()
my $file = File::Spec->catfile($tmppar, split('/', $member->fileName));
warn "[PAR] extracting '$file'\n" if DEBUG;
my $rv = $member->extractToFileNamed($file);
unless($rv == AZ_OK) {
print STDERR "Error extracting '$file' from '$par': error code: $rv";
return undef;
}
if ($member->fileAttributeFormat == 3) { # unix permissions
my $perms = $member->unixFileAttributes & 0xFFF;
unless(chmod $perms, $file) {
print STDERR "chmod $perms, $file failed: $!";
return undef;
}
}
}
return $tmppar;
}
import(__PACKAGE__,@pardir,@parfiles,@parloc);
1;
__END__
=head1 NAME
Apache::PAR - Perl extension for including Perl ARchive files in a mod_perl (1.x or 2.x)
environment.
=head1 SYNOPSIS
Inside Apache configuration:
PerlSetVar PARInclude /path/to/par/archive/directory
...
PerlAddVar PARInclude /path/to/a/par/file.par
...
( run in 1.215 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )