marcparillo
asked on
Download multiple files with Perl
Im in a bind with downloading files. I want the website visitor to click a series of boxes depending on what files they want to download and send the request to a Perl script to initiate the download. I have a perl script that will download one file -- it works. Is there a way to download an entire folder containing several files? I've also tried using Archive::Zip to place all the requested files into one zip file to download, but that may be an unnecessary step. Another problem with Archive::Zip: the files, once downloaded, reveal the folder structure of my server -- probably not a good idea.
Can anyone suggest a secure and reliable module, if one exists, that will initiate the download of several requested files at the same time?
Thanks.
Can anyone suggest a secure and reliable module, if one exists, that will initiate the download of several requested files at the same time?
Thanks.
Will Archive::Zip still reveal the directory structure if you chdir() into the appropriate directory before calling addFile for the file?
ASKER
mjcoyne -- your suggestion worked. Hadn't thought of chdir() into the appropriate directory.
Is it possible to chdir() a couple of different places in the same script?
The files to download are in separate folders. Is it possible to chdir() around the server and collect files to download?
When I try this -- I get an Internal Server Error.
(I suppose I could also move all the folders I want into the same folder before building the zip file and then download the files, but it would be nice to move around the server)
#head on over to FOLDER1 add a bunch of files stored in an array
chdir ('/var/www/vhosts/mydomain .com/httpd ocs/FOLDER 1/');
foreach $i (@file){
$zip->addFile("$i");
}
#now go to a different directory and add one more file from FOLDER2
chdir ('/var/ww/vhosts/mydomain. com/httpdo cs/FOLDER2 /');
$zip->addFile("$anotherfil e.txt");
die 'Cannot create $zip_file_name: $!\n' if $zip->writeToFileNamed("$z ip_file_na me") != AZ_OK;
Is it possible to chdir() a couple of different places in the same script?
The files to download are in separate folders. Is it possible to chdir() around the server and collect files to download?
When I try this -- I get an Internal Server Error.
(I suppose I could also move all the folders I want into the same folder before building the zip file and then download the files, but it would be nice to move around the server)
#head on over to FOLDER1 add a bunch of files stored in an array
chdir ('/var/www/vhosts/mydomain
foreach $i (@file){
$zip->addFile("$i");
}
#now go to a different directory and add one more file from FOLDER2
chdir ('/var/ww/vhosts/mydomain.
$zip->addFile("$anotherfil
die 'Cannot create $zip_file_name: $!\n' if $zip->writeToFileNamed("$z
you can change directory as many times as you need in the script.
Sounds like you have a solution here.
Sounds like you have a solution here.
ASKER
Here's the script that works -- with only chdir one time -- in case anyone's interested:
#!/usr/bin/perl
use CGI;
use Archive::Zip qw( :ERROR_CODES :CONSTANTS ) || die "Can't find Module";
my $zip = Archive::Zip->new();
my $q = new CGI;
my $i;
#read in variables, including an array of files
my @file = $q->param('file');
my $file2 = $q->param('file2');
my $zip_file_name="MyFiles.zi p";
#chdir into appropriate directory
chdir ('/var/www/vhosts/mydomain .com/httpd ocs/FOLDER 1/');
foreach $i (@file){
$zip->addFile("$i");
}
#add a different file from a different folder
$zip->addFile("FOLDER2/$sc ript.txt") ;
die 'Cannot create $zip_file_name: $!\n' if $zip->writeToFileNamed("$z ip_file_na me") != AZ_OK;
#start downloading
$path = '/var/www/vhosts/mydomain. com/httpdo cs/FOLDER1 /';
$filepath = "$path$zip_file_name";
my $size= -s $filepath;
my $buff;
print "Content-type: application/forced-downloa d\r\n";
print "Content-Length: $size\r\n";
print "Content-disposition: attachment;filename=$zip_f ile_name\r \n\r\n";
open(FILE, "<$filepath") || die;
binmode FILE;
binmode STDOUT;
while (read FILE, $buff, 1024) {
print $buff;
}
close(FILE);
#!/usr/bin/perl
use CGI;
use Archive::Zip qw( :ERROR_CODES :CONSTANTS ) || die "Can't find Module";
my $zip = Archive::Zip->new();
my $q = new CGI;
my $i;
#read in variables, including an array of files
my @file = $q->param('file');
my $file2 = $q->param('file2');
my $zip_file_name="MyFiles.zi
#chdir into appropriate directory
chdir ('/var/www/vhosts/mydomain
foreach $i (@file){
$zip->addFile("$i");
}
#add a different file from a different folder
$zip->addFile("FOLDER2/$sc
die 'Cannot create $zip_file_name: $!\n' if $zip->writeToFileNamed("$z
#start downloading
$path = '/var/www/vhosts/mydomain.
$filepath = "$path$zip_file_name";
my $size= -s $filepath;
my $buff;
print "Content-type: application/forced-downloa
print "Content-Length: $size\r\n";
print "Content-disposition: attachment;filename=$zip_f
open(FILE, "<$filepath") || die;
binmode FILE;
binmode STDOUT;
while (read FILE, $buff, 1024) {
print $buff;
}
close(FILE);
ASKER
jhurst -- do you know why I would get an Internal Server Error when I try to chdir a couple of times in the same script?
no, it makes no sense that you get that internal server error.
I wonder if you are trying to change to some directory that is not permitted though.
I suspect that you may be running on a Microsoft server and "enough said" if that is the case.
I wonder if you are trying to change to some directory that is not permitted though.
I suspect that you may be running on a Microsoft server and "enough said" if that is the case.
ASKER
I get a Premature End of Script Headers when I try to
chdir('/path/to/one/folder /');
and then
chdir('/path/to/a/differen t/folder/' );
chdir('/path/to/one/folder
and then
chdir('/path/to/a/differen
ASKER
It's a unix server -- I'll check the permissions again -- but I'm in the httpdocs directory so all should be okay.
is it apache ?
If so this is VERY strange. I would just expect that an attept to change to a directory that is not permitted would just fail in perl. The one thing that I do see that is different in what you do and when I do when I user chdir, is that I do not have the trailing /. This does not mean that you are wrong, or even that I am right, it is just something that I note is different.
If so this is VERY strange. I would just expect that an attept to change to a directory that is not permitted would just fail in perl. The one thing that I do see that is different in what you do and when I do when I user chdir, is that I do not have the trailing /. This does not mean that you are wrong, or even that I am right, it is just something that I note is different.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
kblack05.
perldoc CGI::Carp
perldoc CGI::Carp
Thanks Tintin, I am aware, however this method will also redirect console and syslog errors and give a logged record.
Regards
Regards
ASKER
Thanks everyone.
I can now chdir freely and I learned a few things about error tracing.
I'll split up the points.
I can now chdir freely and I learned a few things about error tracing.
I'll split up the points.
Sadly the answer is sort of NO.
The hrml protocol returns a response. Not the "a" response.
There are kluges, such as mime, etc but realistically your zip approach is the best choice since none of the kludges is reliable and cross platform