For Programmers: Free Programming Magazines  


Home > Archive > PERL CGI Beginners > January 2006 > CGI Upload Code









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author CGI Upload Code
David Gilden

2006-01-10, 3:56 am

Holiday Greetings,
I copied this from a CGI web site, and while it does work,
I was wondering what folks with more experience in PERL thought of=20
this code.
Thanks for any comments,
Dave Gilden


#!/usr/bin/perl -w

use CGI qw/:standard/;
use CGI;
use Fcntl qw( :DEFAULT :flock );
use CGI::Carp qw(fatalsToBrowser);
use strict;

# Upload Code
use constant UPLOAD_DIR =3D> "/home/sites/site01/web/private/mydata/";
use constant BUFFER_SIZE =3D> 16_384;
use constant MAX_FILE_SIZE =3D> 2 * 1_048_576; #Limit each upload to 2 M=
B
use constant MAX_DIR_SIZE =3D> 10 * 1_048_576; # Limit total uploads to 1=
0 MB
use constant MAX_OPEN_TRIES =3D> 100;

$CGI::DISABLE_UPLOADS =3D 0;
$CGI::POST_MAX =3D MAX_FILE_SIZE;

my $q =3D new CGI;
$q->cgi_error and error( $q, "Error transferring file: " . $q->cgi_error );

my $action =3D $q->param( "action" );
=20
if ($action =3D~ /Update/) {
print redirect("./import_clean_csv.php");
exit;
};
=20
if ($action =3D~ /Clean/) {
my @filesToRemove; =20
=20
chdir UPLOAD_DIR or die "Couldn't chdir to afm_data directory: $!";
=20
#my @filesToRemove =3D map {$_ =3D~ /^(\w[\w.-]*)/} <*>;
=20
opendir(DR,"./");
@filesToRemove =3D grep {$_ =3D~ /^(\w[\w.-]*)/} readdir DR;
closedir DR;


print $HTML_HEADER;
print '<div align=3D"center">';

foreach my $fr (@filesToRemove) {
=20
print "Deleted $fr<br>\n";
unlink($fr) or die "Couldn't Delete $fr $!";
}

print <<HTML_OUT;
<p class=3D"top-header">Your Done close this window!=20
<form><input type=3D"button" onclick=3D"self.close()" value=3D"Close Windo=
w"></form></p>
</div>
HTML_OUT
print end_html;
exit;
};


if ($action =3D~ /Upload/) {

my $file =3D $q->param( "file" ) || error( $q, "No file received." );

# my $filename =3D $q->param( "filename" ) || error( $q, "No filename ente=
red." );
my $fh =3D $q->upload( "file" );
my $buffer =3D "";

if ( dir_size( UPLOAD_DIR ) + $ENV{CONTENT_LENGTH} > MAX_DIR_SIZE ) {
error( $q, "Upload directory is full." );
}


# Open output file, making sure the name is unique
until ( sysopen OUTPUT, UPLOAD_DIR . "/$file", O_CREAT | O_RDWR | O=
_EXCL ) {
# $file =3D~ s/(\d*)(\.\w+)$/($1||0) + 1 . $2/e;
$1 >=3D MAX_OPEN_TRIES and error( $q, "Unable to save your file=
=2E" );
}
=20

# This is necessary for non-Unix systems; does nothing on Unix
#binmode $fh;
#binmode OUTPUT;

# Write contents to output file
while ( read( $fh, $buffer, BUFFER_SIZE ) ) {
print OUTPUT $buffer;
}

close OUTPUT;

------snip-------


Cool music.....From Guine=C3=A9 comes this CD of kora fusion, electronica =
=20
[ Audition Mp3s at the URL below ]
<http://www.coraconnection.com/pages...ds.html#sabolan>
usenet@DavidFilmer.com

2006-01-10, 3:56 am

David Gilden wrote:
> Holiday Greetings,


Merry Christmas.

> I copied this from a CGI web site, and while it does work,
> I was wondering what folks with more experience in PERL thought of
> this code.


A lot of it looks familiar. I wonder about some bits (none of my
suggested code has been tested)...

> #!/usr/bin/perl -w


better to 'use wanings' - lexical warnings better than global (-w)

>
> use CGI qw/:standard/;
> use CGI;


no need to use the CGI module twice.

> use Fcntl qw( :DEFAULT :flock );
> use CGI::Carp qw(fatalsToBrowser);
> use strict;


Good!

> # Upload Code
> use constant UPLOAD_DIR => "/home/sites/site01/web/private/mydata/";
> use constant BUFFER_SIZE => 16_384;
> use constant MAX_FILE_SIZE => 2 * 1_048_576; #Limit each upload to 2 MB
> use constant MAX_DIR_SIZE => 10 * 1_048_576; # Limit total uploads to 10 MB
> use constant MAX_OPEN_TRIES => 100;
>
> $CGI::DISABLE_UPLOADS = 0;
> $CGI::POST_MAX = MAX_FILE_SIZE;
>
> my $q = new CGI;
> $q->cgi_error and error( $q, "Error transferring file: " . $q->cgi_error );
>
> my $action = $q->param( "action" );
>
> if ($action =~ /Update/) {
> print redirect("./import_clean_csv.php");


That should be ./import_clean_csv.cgi, dontcha think ;)

HOWEVER, this is a redirect to a relative URL. That's NOT supported by
the CGI module. See
http://search.cpan.org/~lds/CGI.pm-...IRECTION_HEADER

> exit;


This is normally considered bad practice. Proper flow control should
happen within your "if" constructs. Most programmers would say that
"exit" should only be used to bail out of a program unexpectedely (with
an exit code).

> };
>
> if ($action =~ /Clean/) {
> my @filesToRemove;
>
> chdir UPLOAD_DIR or die "Couldn't chdir to afm_data directory: $!";
>
> #my @filesToRemove = map {$_ =~ /^(\w[\w.-]*)/} <*>;
>
> opendir(DR,"./");
> @filesToRemove = grep {$_ =~ /^(\w[\w.-]*)/} readdir DR;


I hope your program knows what it's doing... this looks like a
potential security risk...

> closedir DR;
>
> print $HTML_HEADER;


Where did that come from?

> print '<div align="center">';
>
> foreach my $fr (@filesToRemove) {
>
> print "Deleted $fr<br>\n";
> unlink($fr) or die "Couldn't Delete $fr $!";
> }


So if you can't delete a file, you first say it WAS deleted, and then
say it wasn't? Why not make it a bit more clear:
if (unlink $fr) {
print "Deleted $fr<br>\n";
}else{
die "Oh no - $!\n"
}

I don't like that <br> though. It goes against CSS best practices. The
paragraph should be in a (styled) <P> tagest. <br> shouldn't be used
for paragraphs in a CSS world.

> print <<HTML_OUT;


YUCK! Here docs make me sick to my stomach.

> <p class="top-header">Your Done close this window!
> <form><input type="button" onclick="self.close()" value="Close Window"></form></p>
> </div>
> HTML_OUT


Why are you mixing HTML and CGI.pm? Use CGI.pm to print this (and
avoid a here doc):

print
p({class => 'top-header'},
form(
input({type => 'button', onclick => 'self.close()', value
=> 'Close Window'}),
)
);

You never need to print raw HTML when using CGI.pm.

> print end_html;
> exit;


Same comment about exit

The upload stuff looks OK (and fairly familiar...)

Cheers!

--
http://DavidFilmer.com

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com