Contact US

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Uploading Files

Using CGI.pm to upload files. by goBoating
Posted: 11 Jan 01

The following is a simple example of using the popular CGI.pm module written by Lincoln Stein to upload files.  This FAQ is not an exhaustive treatment of the topic.  Instead, it is a FAQ ;^).  Also, be aware that any time you let anyone put files on your machine you are taking a chance....Be paranoid.  For more information on CGI.pm, see it's documentation.  To find out how to do that, see the FAQ, "How can I use Perl's built-in help".

This is presented as two files.  It could as easily be one CGI file that does the entire trick.  It is presented as two files for clarity.  The first is a very simple HTML page with the necessary parts to allow the upload to run.  The second is a piece of CGI code which accepts the input from the HTML page and reads the file from the client.  Absolutely no attention has been paid to aesthetics.

****  HTML Page *****

<!-- change the next line to point at your cgi code. -->
<FORM METHOD="POST" ACTION="http://some.server.com/cgi-bin/upload.cgi"; ENCTYPE="multipart/form-data">
<P>Enter or Browse to the file you would like to upload.<BR>
<INPUT TYPE="submit" NAME="submit" VALUE="uploadMe"></FORM>

**** End HTML Page ****

Note that the <FORM.... ACTION=.....>, above, must be editted to point to
where you put the CGI code.  Note, also, in the first <INPUT ...> tag above the
NAME is 'FILEID'.  That will be important in the CGI code.  The CGI code below
would be written into a file named like the <FORM ....ACTION=....> and,
if you are on a UNIX box, set the execute bits to the web server daemon can run it.  
Also, if you are on a UNIX box, don't forget to convert dos2unix if you got this stuff via a PC.

**** Start CGI ****

use CGI;
$query = new CGI;
print $query->header;
print $query->start_html(-title=>"UPLOAD PLEASE");

# retrieve the upload file name.  Note that it is retrieved with
# the same name here ('FILEID') that it has in the HTML.
unless ($fileID = $query->param('FILEID'))
    { &showError('No file name specified.'); }

# Check to make sure the uploaded file is safe to keep
# by checking its type.  
# First retrieve the file type .
# If it is not 'text/html' or 'text/plain', stop and complain.
# You can modify the regex to allow the types you would
# like to accept.  If you don't know how, see the FAQ on
# pattern matching.  
# I recommend against excluding types.  Instead, you should
# explicitly define the types you want to accept.

$type = $query->uploadInfo($fileID)->{'Content-Type'};
unless ($type =~ /text\/[html|plain]/i)
    &showError("Dangerous file type of $type.<BR>UPLOAD ABORTED.");

# If we are still running (did not bail on the file type and fileID exists),
# then,

@pathName = split(/\\/,$fileID);
# Read file from remote machine and write locally.
# You must change the following line to point to a
# dir on your machine that is writable by the web server daemon
$newFile ='/path/to/put/the/new/file/';
# add the upload filename to the new path
$newFile .= pop(@pathName);

# open a handle to the new file you will write
open(OPF,">$newFile") || &showError("Failed to open OPF, $!");

# while you read from the remote machine,
# write to the output file.
print "<P><CENTER>Uploading <BR>$fileID <BR>to<BR>$newFile<BR></CENTER></P>\n";
while ($bytesread=read($fileID,$buffer,1024))
    print OPF "$buffer";
    # The 1024 buffer size is nearly arbitrary.
    # Watch to make sure the file is not to large.
    # Someone could fill your file system if this is
    # not watched.  The 27000 byte limit is also arbitrary.
    # You need to set it to an appropriate number for
    # your situation.
    # The $bytesread value comes into the while loop
    # in 1024 $buffer chunks, so add up the chunks as they come.
    $sum_bytes += $bytesread;
    if ($sum_bytes > 27000)
        close OPF;
        unlink $newFile;
        &showError("File is to large.");
close OPF;
print $query->end_html;
sub showError
# a generic complaint generator
my @error = @_;
print "<CENTER><font color=\"\#ff4500\">ERROR - @error</font><BR>\n";
print "Please use the BACK button to return to the previous page<BR>\n";
print "and correct the error.<BR></CENTER>\n";
print $query->end_html;

**** End CGI Code ****

'hope this is useful.

Back to Perl FAQ Index
Back to Perl Forum

My Archive

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close