Handling file uploading from www forms with CGI.pm
Introduction
Netscape Navigator 2.0 introduced a new facility for forms, the file upload element. This element allows the user
to select a local file to be submitted with the form to the server that handles the form. File uploading is
a frequently needed facility in many occasions, but the technique involved in handling forms that upload
files is rarely discussed in CGI programming texts, and online tutorials/references on this topic are few.
The technique is very simple as we shall see.
The form
First of all we'll need to prepare the HTML form that will contain the file upload element:
|
|
<FORM ENCTYPE="multipart/form-data" ACTION="/cgi-bin/upload.pl" METHOD="POST">
Please choose directory to upload to:<br>
<SELECT NAME="dir">
<OPTION VALUE="images">images</OPTION>
<OPTION VALUE="sounds">sounds</OPTION>
</SELECT>
<p>
Please select a file to upload: <BR>
<INPUT TYPE="FILE" NAME="file">
<p>
<INPUT TYPE="submit">
</FORM>
Which will look on the browser like that:
Notice the form parameter ENCTYPE="multipart/form-data" which determines the encoding that
will be used to submit it.
The CGI script
On the server side, we'll have the CGI program (upload.pl) that will handle the upload.
We will use CGI.pm that does all the dirty job for us. CGI.pm processes the submission of the form
for us and provides us with a simple method of retrieving each individual part of the submission.
In our case we only have one element, called file:
1 #!/usr/bin/perl
2 use CGI;
3 my $cgi = new CGI;
4 my $dir = $cgi->param('dir');
5 my $file = $cgi->param('file');
Now it is quite obvious what the value of $dir will be. But what will the value of $file
be assigned to? ACtually $file now is two things:
- In a scalar context it is the filename on the client computer, as it appears in the file selection box.
- When used in a filhandle context, it behaves as a read-mode filhandle from which the uploaded file can be
read just like any normal file opened locally. (actually what happens here is that CGI.pm keeps the upload in
a temporary file and provides us with an open handle to it so we can read through it)
And that's all there is to it. Now all we got to do is read in the file and store it somewhere or do whatever else
we might want to do with it.
6 $file=~m/^.*(\\|\/)(.*)/; # strip the remote path and keep the filename
7 my $name = $2;
8 open(LOCAL, ">$dir/$name") or die $!;
9 while(<$file>) {
10 print LOCAL $_;
11 }
12 print $cgi->header();
13 print "$file has been successfully uploaded... thank you.\n";
First of all, because the filename that we get from the form includes the full path of the file on the remote machine
we need to strip that part. Lines 6-7 do just that. Next we open a local file and we just iterate through the upload
input and dump its contents to it. Finally we print out a message back to the browser to confirm that the upload
has been successful.
Online Documentation/Tutorials
- The POD documentation for CGI.pm has a section explaining all you need to know about file uploading.
Comments
|
perlfect | Posted at 7:51pm on Friday, June 8th, 2007 | 6 $file=~m/^.*(\|/)(.*)/; # strip the remote path and keep the filename
7 my $name = $2;
8 open(LOCAL, ">$dir/$name") or die $!;
9 while() {
10 print LOCAL $_;
11 }
12 print $cgi->header();
13 print "$file has been successfully uploaded... thank you.n"; |
June 8th, 2007 | Posted at 7:54pm on Friday, June 8th, 2007 | perl with explanations and tips easy to understand even for beginners, but also frequently useful even to more experienced programmers. The code is clear and straightforward and the topics covered as well-thought and correspond to real world examples, so frequently you can literally copy code snippets from the book and fit them in your program |
error 500 | Posted at 6:54am on Thursday, June 14th, 2007 | HI
I am getting this error in the browser what might be the problem "HTTP Error 500 - Server Error" Please help to find the error .Regards Shashi |
security check | Posted at 3:59pm on Monday, June 18th, 2007 | I see this is meant to be simple example, but many people will just copy and paste this dangerous snippet into their CGI script. If you don't want to be pwned, you must overcome laziness and:
1. strip any dangerous characters from directory parameter, or check directory name against predefined list on server.
2. ensure uploaded files can't be executed.
Afterabove is done, running with perl -T is encouraged. |
Jeff | Posted at 3:15am on Thursday, July 26th, 2007 | Please stop posting terrible perl scripts that will cause those who use them security problems. Please! |
Taureth | Posted at 8:48pm on Tuesday, August 28th, 2007 | The VERY simple example is appreciated... I needed info on file upload, not a course in security issues, so it was perfect for me... those who are too lazy or stupid to include security coding probably deserve to get what they asked for... |
Cherry | Posted at 11:24pm on Wednesday, August 29th, 2007 | When executed..
# perl upload.pl
# err msg :Is a directory at upload.pl line 8.
Consequently 500 Internal Serv Err !!
Wat Could Be Done?? |
DT | Posted at 5:37pm on Sunday, November 18th, 2007 | RE:Cherry
You need to:
a) create the directory
b) allow write access to the directory(DO NOT ALLOW 777!) |
samirzedan | Posted at 8:24am on Friday, January 11th, 2008 | On the excellent site and wish to participate in it |
Gregory Swofford | Posted at 3:35am on Monday, January 14th, 2008 | Here's a snippet I include anytime I use CGI.pm. You can trap all your errors to debug a script. If the file 'error.log' doesn't exist, the server will create it as 'user nobody'.
# FOR DEBUGGING:
#use strict;
use CGI qw(:standard);
use CGI::Carp qw(fatalsToBrowser);
BEGIN {
open (STDERR, '>>error.log');
}
# END FOR DEBUGGING |
Neil Fraser | Posted at 12:57pm on Monday, March 3rd, 2008 | Don't forget to CLOSE the file while you are done. Your operating system has a limited number of file handles.
close(LOCAL); |
axe | Posted at 3:56pm on Thursday, March 27th, 2008 | my file uploads but it does not have any data. Any suggetion ? |
Tim | Posted at 4:06pm on Monday, May 26th, 2008 | an empty file sometimes means the form HTML didn't include ENCTYPE="multipart/form-data" I have been stung with this a few times and it drove me crazy until I figured it out :) Also a note for beginners, $dir needs to be something otherwise it may try and put your file in the wong place, ie:
my $dir="pics"; # and make sure the directory pics is in the same directory as the script is being run from. |
Comments to date: 13.
|
Suggested Reading
The Official CGI.pm Programming Guide is the definitive manual and guidebook for writing CGI programs
with perl and the CGI library. While the manual distributed with the library as part of perl's documentation is well
written and covers almost anything you'd need to know about using CGI.pm, this book is a useful companion for anyone
making CGI scripts with perl.
CGI Programming is an introductry book for CGI programming, perhaps not the best book I've read.
It covers most topics about the CGI protocol and how to write server side programs to work with it.
Nevertheless, most if not all of the information in this book (as with most books that discuss CGI programming)
can be found in tutorials and references on the web, but if you feel like buying a book anyway, you may want to
consider this one.
Webmaster in a nutshell is a catch-all reference book for webmaster and programmers. It does
not have anuything that you can't find online, but if you're liek me you might want to have all the
stuff you refer to frequently nicely laid out in a well-organized book lying on your desk. If you're looking
for something like that then you'll be happy with this book.
The Perl Cookbook is full of quick solutions to everyday programming problems in perl with explanations
and tips easy to understand even for beginners, but also frequently useful even to more experienced programmers.
The code is clear and straightforward and the topics covered as well-thought and correspond to real world examples,
so frequently you can literally copy code snippets from the book and fit them in your program. It is a nice complement
for the Camel Book on your bookshelf.
|