Perl CGI to download a file via web browser

17,280

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.

Share:
17,280
Tanuj
Author by

Tanuj

Updated on June 18, 2022

Comments

  • Tanuj
    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
    Tanuj over 11 years
    its correct in the code , i believe while copy pasting code from my IDE to here i made it wrong ..
  • Tanuj
    Tanuj over 11 years
    Spent 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
    Dave Cross over 11 years
    Oh. I didn't know you could accept your own answer. That seems... broken.
  • Dave Cross
    Dave Cross over 11 years
    Now fix the bug that gives a cracker access to all the passwords on your server - mag-sol.com/articles/cgi2.html
  • CJ7
    CJ7 over 7 years
    @DaveCross Can you explain what that bug is because that link is now dead.
  • Dave Cross
    Dave Cross over 7 years
    Oops. 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.