Skip to page content or Skip to Accesskey List.

Work

Main Page Content

Quick And Dirty File Upload How To

Rated 4.08 (Ratings: 1)

Want more?

  • More articles in Code
 
Picture of AnthonyB

Anthony Baratta

Member info

User since: 10 Jul 1999

Articles written: 12

Uploading files is a semi-complex process involving the right incantations on both the client forms and the server - but it can be tamed. Here's a quick over view of what you need to have to accept file uploads.

Example "simple" upload form...

<form name="UploadForm" method="post" action="./file.cgi"

enctype="multipart/form-data" >

<INPUT TYPE=FILE NAME="FileName1" VALUE="">

<INPUT TYPE=SUBMIT NAME="Upload" VALUE="Upload File">

</form>

REQ 1

You must be using a browser and server that supports HTTP 1.1 (Apache 1.3.x

and IIS 4.0. 3.x Netscape and above and 3.02? IE and above). Note that the

upload form needs a enctype. For file uploads you need

multipart/form-data.

REQ 2

It's best that you use a CGI library like cgi-lib.pl or CGI.pm to assist you in

uploading files. These libraries can help you limit the file sizes and upload

locations as well as other niceties that will make the process

easier.

CGI-LIB

http://cgi-lib.stanford.edu/cgi-lib/

CGI.PM

http://stein.cshl.org/software/WWW/CGI/

I'm partial to cgi-lib because its a smaller library and I only currently use the

upload and form parsing functions. But both libraries are very good.

REQ 3

An understanding that you are allowing anonymous (unless the upload area

is password protected) people to upload files to your server. Make sure you

write code that chmod's the files to 666 or some other type of readable but

not executable form. Check for .cgi , .pl for extensions and strip them off.

Look for shebangs in the first line of all files - remove them or quarantine

them. Also, people have the potential to upload malicious HTML pages and

other 'tainted' stuff.

REQ 4

Be paranoid. God is always building a better idiot.

After constructing the proper form, everything else is set within the CGI program. With cgi-lib.pl you have the following variables that can be set to control the upload process: (There are more than these variables that can be set - read the library's documentation to ferret out all the other options.)

# Spool the files to the ______ directory

# (directory needs to be 777)

$cgi_lib::writefiles = "/full/path/to/upload/dir";

# Limit upload size

$cgi_lib::maxdata = 50000000;

# set to 50 megs;

The Upload directory is a "temp" location and the files are given unique names by the web server 23455.1 for file number one and 23455.2 for file number two (if you are doing multi-uploads). You are then responsible for getting the temp files renamed and put in their proper locations.

By parsing the form you can glean all the info you need to rename the files back to their original names. Cgi-Lib.pl uses the following parse function:

# Reading and pare the data. Save the return value to $ret

# Pass references to retrieve the data, the filenames,

# and the content-type

$ret = &ReadParse(\%cgi_data,\%cgi_cfn,\%cgi_ct,\%cgi_sfn);

Where:

  • %cgi_data - is the form data sent (for files is the full temp path and name on server)

  • %cgi_cfn - is the common (original) file name (full path, may need to be truncated)
  • %cgi_ct - is the content-type of the file (not always accurate)
  • %cgi_sfn - is the just temp name of the file (no path) as given by the server

For example:

<FORM NAME=UPLOADFORM ENCTYPE="multipart/form-data"

ACTION="/cgi-bin/upload.cgi" METHOD="POST>

<INPUT TYPE="file" NAME="File1"> # User puts in: c:\autoexec.bat

<INPUT TYPE="file" NAME="File2"> # User puts in: c:\config.sys

<INPUT TYPE="file" NAME="File3"> # User puts in: c:\bootlog.txt

<INPUT TYPE="text" NAME="UserName"> # User puts in: Howdy Doody

<INPUT TYPE="SUBMIT" NAME="SUBMIT">

</FORM>

** upload.cgi **

#!/usr/bin/perl

require 5.001;

require "cgi-lib.pl";

# Spool the files to the ______ directory

# (directory needs to be 777)

$cgi_lib::writefiles = "/tmp/uploads";

# Limit upload size

$cgi_lib::maxdata = 50;

# set to 50k ;

$ret = &ReadParse(\%cgi_data,\%cgi_cfn,\%cgi_ct,\%cgi_sfn);

** You would now have the following info...

$cgi_data{'UserName'} = "Howdy Doody"

$cgi_data{'File1'} = "/tmp/uploads/2343235.1"

$cgi_cfn{'File1'} = "c:\autoexec.bat"

$cgi_ct{'File1'} = "text/plain"

$cgi_sfn{'File1'} = "2343235.1"

$cgi_data{'File2'} = "/tmp/uploads/2343235.2"

$cgi_cfn{'File2'} = "c:\config.sys"

$cgi_ct{'File2'} = "text/plain"

$cgi_sfn{'File2'} = "2343235.2"

$cgi_data{'File3'} = "/tmp/uploads/2343235.3"

$cgi_cfn{'File3'} = "c:\bootlog.txt"

$cgi_ct{'File3'} = "text/plain"

$cgi_sfn{'File3'} = "2343235.3"

Hope this helps. Good Luck.

Mutated into a life-size Dilbert doll, Anthony spends the days wedged into his replica of Cardinal Fang's Comfy Chair coding solutions to the most thorny of internet software problems.

The access keys for this page are: ALT (Control on a Mac) plus:

evolt.org Evolt.org is an all-volunteer resource for web developers made up of a discussion list, a browser archive, and member-submitted articles. This article is the property of its author, please do not redistribute or use elsewhere without checking with the author.