Perl CGI to download a file via web browser
Solution 1
Rearranging the HTML headers worked. here is the working script. one can use this as it is
use CGI;
my $html= new CGI;
#get the file name from URL ex. http://<server_IP>/cgi-bin/download.cgi?a=testing.txt
my $file= $html->param('a');
# $file is nothing but testing.txt
my $filepath= "/var/www/upload/$file";
print ("Content-Type:application/x-download\n");
print "Content-Disposition: attachment; filename=$file\n\n";
open FILE, "< $filepath" or die "can't open : $!";
binmode FILE;
local $/ = \10240;
while (<FILE>){
print $_;
}
close FILE;
# use Unlink if u want to delete the files after download.
#unlink ($filepath);
Solution 2
I think you've just spelled your content-disposition header wrong. It should be "attachment", not "attachement".
Update (following comment below):
Ok, so looking further I see that you're printing a CGI header (Content-Type: text/html) followed by two newlines and then, later, printing more CGI headers and expecting the browser to notice them. The first blank line in your response will tell the browser that the headers are finished. So your second batch of headers will just be seen as content.
I also see that you are printing the contents of the file before your second set of headers. Which would make them footers rather than headers :-)
You need to re-order your code so that you only return one set of headers. And then you return the data.
Tanuj
Updated on June 18, 2022Comments
-
Tanuj about 2 years
Need some cgi-perl script which can download a file from a server machine. EX: click on a download link and it will open a "save as" window and will allow me to save the file on my local machine.
I have created a web page using CGI, using this I will upload a file to server and will run a perl script to convert it to some other format (till here I am done). Now I need get this file back (download back) to the system.
#!/usr/bin/perl #print "Content-type: text/html\n\n"; my $filepath='/upload/testing.pm'; print "Content-Type: text/html\n\n"; open("DOWNLOADFILE", "<".$filePath); while($fileContents = <DOWNLOADFILE>) { print $fileContents; } print "Content-Type: text\n"; print "Content-Disposition: attachment; filename='testing.pm'\n"; print "Content-Description: File to download\n\n"; close DOWNLOADFILE;
Upload a file from my machine (client) to server machine, where I have a perl script which will convert the file to another format and will save the newly converted file to a dir ex: /upload-> till here I am done with scripting.
Now I need to download this file back to client machine using browser. In this case I was trying to download testing.pm file back to client machine.
-
Tanuj over 11 yearsits correct in the code , i believe while copy pasting code from my IDE to here i made it wrong ..
-
Tanuj over 11 yearsSpent some time in understanding HTML headers for downloading a file.. Thanks Dave for suggesting the solution .. i have updated the working script down...
-
Dave Cross over 11 yearsOh. I didn't know you could accept your own answer. That seems... broken.
-
Dave Cross over 11 yearsNow fix the bug that gives a cracker access to all the passwords on your server - mag-sol.com/articles/cgi2.html
-
CJ7 over 7 years@DaveCross Can you explain what that bug is because that link is now dead.
-
Dave Cross over 7 yearsOops. I moved the articles around a bit. The link is not dead; it tells you where to go - perlhacks.com/articles/cgi-programming/cgi-programming-part-2. But to summarise, if I send you a file parameter of "../../../etc/passwd", you send me the file that contains all of your passwords for me to crack at my leisure.