Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Using CGI.pm to upload files.

Uploading Files

Using CGI.pm to upload files.

by  goBoating  Posted    (Edited  )
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 *****

<HTML>
<HEAD>
<TITLE>UPLOAD THIS</TITLE>
</HEAD>
<BODY>
<!-- 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="file" NAME="FILEID" VALUE="" SIZE=50 MAXLENGTH=80><BR>
<INPUT TYPE="submit" NAME="submit" VALUE="uploadMe"></FORM>
</BODY>
</HTML>

**** 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 ****

#!/usr/local/bin/perl
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;
exit;
}

**** End CGI Code ****

'hope this is useful.
Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top