Jabda
Jabda

Reputation: 1792

PERL CGI multiple content types. How To Download File AND view contents.

A page that prints out a file (on the server) contents and provides a direct download link.

Download File HERE

Start contents of file:
line 1
line 2
line 3
...

I am not sure of the best way and the right header that will allow a download link and HTML text. This prints out blank

            print $mycgi->header(
                   -cookie => $mycookie, 
                    -Type => "application/x-download"
                    -'Content-Disposition'=>'attachment; filename="FileName"'
              );

Upvotes: 1

Views: 1893

Answers (1)

ThisSuitIsBlackNot
ThisSuitIsBlackNot

Reputation: 24073

You can include a link to a script and pass the filename as a parameter. The link might look something like this:

http://url/to/script?action=download&file=foo

Below that, simply print the contents of the file:

#!/usr/bin/perl -T

use strict;
use warnings;

use CGI qw/escapeHTML/;

my $q = CGI->new;

print $q->header,
      $q->start_html('foo'),
      $q->a({ -href => 'http://url/to/script?action=download&file=foo' }, 'Click to download'),
      "<pre>";

open my $fh, "<", "/path/to/file" or die $!;

print escapeHTML($_) while <$fh>;

close $fh;

print "</pre>", $q->end_html;

Note that you should use escapeHTML() to prevent the browser from rendering anything in the file as HTML (which the <pre> tag alone does not take care of).

When the script is called with the action parameter set to download, use the application/x-download content type as you did above:

my $q = CGI->new;

# Untaint parameters
my ($action) = ($q->param('action') =~ /^(\w+)$/g);
my ($file)   = ($q->param('file') =~ /^([-.\w]+)$/g);

# Map file parameter to the actual file name on your filesystem.
# The user should never know the actual file name. There are many
# ways you could implement this.
???

if ($action eq "download") {
    print $q->header(
        -type => "application/x-download",
        -'Content-Disposition' => 'attachment; filename="FileName"'
    );

    open my $fh, "<", $file or die "Failed to open `$file' for reading: $!";

    print while <$fh>;

    close $fh;
}

Note that you also need to print the contents of the file in the body of the response.

Upvotes: 1

Related Questions