# serve an image file
#
# The file is read as chunks to avoid consuming memory
use strict;
use warnings;
foreach (qw(PATH ENV BASH_ENV CDPATH IFS TERM)) { $ENV{$_}='' } # secure ENV
use CGI qw(:standard);
use Fcntl;
# this is specific, provide your own code to set the path
# Oh, and make sure your path is clean!!
my $path = 'path_to_some_image_file.gif';
# read the file as 2048 byte chunks to avoid
# sucking all into memory at once
my $buffer;
my $buffer_size = 2048;
die unless -e $path;
$path =~ m/\.(gif|jpg|png)$/ or die;
# here's the code in question
print header(-type => "image/$1", -expires => "now");
binmode STDOUT;
sysopen(my $fh, $path, O_RDONLY) or die "Failed to open $path: $!";
while (sysread($fh, $buffer, $buffer_size)) {
print $buffer;
}
exit;
Securing those environment variables is not needed, since you don't spawn any kids.
You're using the wrong MIME type for "JPEG" images. It's should be image/jpeg.
die is not very appropriate for CGI scripts.
exit is not needed.
sysread is probably more appropriate, but I find $/ = \2048 and $/ = \$buffer_size neat:
local $/ = \2048; open(my $fh, '<', $path) or die "Failed to open $path: $!"; binmode($fh); binmode(STDOUT); print while <$fh>;
perlmonks.org content © perlmonks.org and ikegami, ruzam
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03