Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

File Upload - What Next?

by Thathom (Acolyte)
on Jul 06, 2001 at 00:19 UTC ( [id://94254]=perlquestion: print w/replies, xml ) Need Help??

Thathom has asked for the wisdom of the Perl Monks concerning the following question:

Ok, heres the script I have so far. It uses CGI.pm and passes through a text variable and tells me the file name thats going to be uploaded. It works great. (so far). How do I upload the file to the UPLOAD_DIR?

Genius wanted.....:)


Form: AS a form should be, using...
input type=file name=file input type=text name=var1
Script:
#!/usr/bin/perl use CGI; use constant BUFFER_SIZE => 16_384; use constant MAX_FILE_SIZE => 48_576; use constant UPLOAD_DIR => "/absolute/path/to/"; $CGI::DISABLE_UPLOADS = 0; $CGI::POST_MAX = MAX_FILE_SIZE; my $req = CGI->new;<br> my $var1 = $req->param('var1'); my $file = $req->param("file"); if ($file) { my $buffer; my $file_handle = $req->upload( $file ); my $format = $req->uploadInfo($file)->{'Content-Type'}; } print "Content-type: text/html\n\n"; print "Passed Variable = $var1<p>"; print "File name = $file<p>\n"; exit;
Sooo close!!!.......

Replies are listed 'Best First'.
Re: File Upload - What Next?
by tachyon (Chancellor) on Jul 06, 2001 at 00:55 UTC

    Here is a complete example from the O'Reilly book "CGI Programming" aka The Rat Book. I recommend this book to you. This script is public domain and freely available so I'm sure this does not breach copyright.

    HTML <form action="upload.cgi" method="POST" enctype="multipart/form-data"> <p>Please choose a file to upload: <input type="file" name="file"> <p>Please enter a name for this file: <input type="text" name="filename"> </form> use strict; use CGI; use Fcntl qw( :DEFAULT :flock ); use constant UPLOAD_DIR => "/usr/local/apache/data/uploads"; use constant BUFFER_SIZE => 16_384; use constant MAX_FILE_SIZE => 1_048_576; # Limit each upload to + 1 MB use constant MAX_DIR_SIZE => 100 * 1_048_576; # Limit total uploads +to 100 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_err +or ); my $file = $q->param( "file" ) || error( $q, "No file receive +d." ); my $filename = $q->param( "filename" ) || error( $q, "No filename ent +ered." ); my $fh = $q->upload( "file" ); my $buffer = ""; if ( dir_size( UPLOAD_DIR ) + $ENV{CONTENT_LENGTH} > MAX_DIR_SIZE ) { error( $q, "Upload directory is full." ); } # Allow letters, digits, periods, underscores, dashes # Convert anything else to an underscore $filename =~ s/[^\w.-]/_/g; if ( $filename =~ /^(\w[\w.-]*)/ ) { $filename = $1; } else { error( $q, "Invalid file name; files must start with a letter or n +umber." ); } # Open output file, making sure the name is unique until ( sysopen OUTPUT, UPLOAD_DIR . "/$filename", O_CREAT | O_RDWR | +O_EXCL ) { $filename =~ s/(\d*)(\.\w+)$/($1||0) + 1 . $2/e; $1 >= MAX_OPEN_TRIES and error( $q, "Unable to save your file." ); } # 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; print $q->header( "text/plain" ), "File received."; sub dir_size { my $dir = shift; my $dir_size = 0; # Loop through files and sum the sizes; doesn't descend down subdi +rs opendir DIR, $dir or die "Unable to open $dir: $!"; while ( readdir DIR ) { $dir_size += -s "$dir/$_"; } return $dir_size; } sub error { my( $q, $reason ) = @_; print $q->header( "text/html" ), $q->start_html( "Error" ), $q->h1( "Error" ), $q->p( "Your upload was not procesed because the following e +rror ", "occured: " ), $q->p( $q->i( $reason ) ), $q->end_html; exit; }

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

      Thanks my friend!!
        Ok, there WAS a problem with this script, but thanks to various people (you know who you are) it now works. Im sure there are scurity issues and all that but it works:) The only one problem i still have is that i get an internal server error when the file size is too big. Must I do some code checking the MAX FILE size or is that what the $CGI: : POST_MAX line is suppose to do for me? Heres the form......
        <FORM ENCTYPE="multipart/form-data" ACTION="the.cgi" METHOD=POST> Var1 : <input type=text name=var1><br> File : <INPUT NAME="file" TYPE="file"><p> <INPUT TYPE="submit" VALUE="Send File"> </FORM>
        and heres the script.........
        #!/usr/bin/perl use CGI; #SET SOME DEFAULT STUFF ################################################### use constant BUFFER_SIZE => 16_384; use constant MAX_FILE_SIZE => 48_576; $CGI::DISABLE_UPLOADS = 0; $CGI::POST_MAX = MAX_FILE_SIZE; #GET THE VARIABLE AND FILE INFORMATION ################################################### my $query = new CGI; my $filehandle = $query->upload('file'); my $filename = $query->param('file'); my $var1 = $query->param('var1'); #GET FILE NAME BY REMOVING FULL DIRECTORY INFO #eg C:\windows\blah\file.txt ############################################## @pathz = (split(/\\/,$filename)); $fileb = $pathz[$#pathz]; @pathza = (split('/',$fileb)); $filename = $pathza[$#pathza]; #UPLOAD THE FILE TO SELECTED DESTINATION ############################################## open OUTPUT, ">/absolute/path/to/$filename" or die "Can't open: $!"; while (<$filehandle>) { print OUTPUT; } close OUTPUT or die "Can't close: $!"; #DONE ############################################## print "Content-type: text/html\n\n"; print "Sorted!<p>\n"; print "Passed Variable = $var1<p>"; print "File name uploaded was <i>$filename</i><p>\n"; exit;
        Thankyou everyone!, I hope that helps alot of other people too!
Re: File Upload - What Next?
by PrakashK (Pilgrim) on Jul 06, 2001 at 00:40 UTC
    You already have the filehandle. Just read from the filehandle and write to a file in your UPLOAD_DIR.
    # after getting $file_handle my $file = "some_name"; # pick a name open F, ">" . UPLOAD_DIR . "$file" or die "$!"; while (<$file_handle>) { print F; } close F; close $file_handle;
    /prakash
      Thankyou, thats helped alot

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://94254]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (5)
As of 2024-03-29 09:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found