Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re: Cgi pm and photo uploads

by sulfericacid (Deacon)
on Oct 04, 2003 at 19:58 UTC ( #296571=note: print w/replies, xml ) Need Help??


in reply to Cgi pm and photo uploads

Here are a few tips before I get started.. First of all, please keep your questions short (sometimes itís difficult enough trying to find out what youíre trying to do, lengthy paragraphs just add more confusion). Also, please use <code></code> tags around all codes (whether they be HTML, CSS, Perl/CGI). Putting them in code tags makes it more legible for those who are trying to help you.

It looks like you're on the right track. You have the HTML section of your form complete and it'll ask you to search a file on your hard drive. If you want the form to upload to your server, you have to tell it to do so (otherwise the file will just disappear after your script is done running). Below is a script I wrote a few months ago which asks the user for an image then it uploads it to a folder on your server.

I don't like playing with separate HTML files, especially forms, so the script below makes the form for us (which you can remove that section and go with what you already have). The key part to pay attention to is:

# open a new file and transfer bit by bit from what's in the buffe +r open( SAVED, ">>$localfile" ); # || die $!; while ( $bytesread = read( $remotefile, $buffer, 1024 ) ) { print SAVED $buffer; } close SAVED;
This is where the dirty stuff happens! This is opening a file and transfering your uploaded image bit by bit until the end of file, then it saves this copy on your server. This might be a little confusing but this is straight from the docs from search.cpan.org on CGI.

Below is a complete script which asks for user input, uploads an image and stores some of that information to a database. You probably aren't looking for all of this but hopefully this gives you an idea on how to upload and transfer files from a form to your server.

Hope this helps.

#!/usr/bin/perl -w # # IMAGES FOLDER MUST BE CHMOD TO 777 otherwise script fails # use warnings; use CGI qw/:standard/; use POSIX; use DB_File; my %upload; my $upload = "imagegallery.db"; tie %upload, "DB_File", "$upload", O_CREAT|O_RDWR, 0644, $DB_BTREE or die "Cannot open file 'upload': $!\n"; my $mode = 0755; print header, start_html('Upload Form!'); print "Upload formats allowed: jpg, gif, bmp.<br>"; print start_form( -method => 'post', -enctype => 'multipart/form-data' ), table( Tr( td(""), td("Please keep filenames, descriptions and titles short to + preserve a more uniformed appearance (under 20 chars)"), ), Tr( td("Image Title: "), td( textfield( -name => 'title', -size => 50, -maxlength => 80 ), ), ), Tr( td("Short Description: "), td( textfield( -name => 'desc', -size => 50, -maxlength => 80 ), ), ), Tr( td("File: "), td( filefield( -name => 'upload', -size => 50, -maxlength => 80 ), ), ), Tr( td(), td( submit( 'button', 'submit' ), ) ) ), end_form(), hr; if ( param() ) { # take form data my $remotefile = param('upload'); my $desc = param('desc'); $desc =~ s/::/\&\#58\;\&\#58\;/g; # remove semicolons my $title = param('title'); $title =~ s/::/\&\#58\;\&\#58\;/g; # remove semicolons # make new variable to prevent overwriting of form data my $filename = $remotefile; # remove all directories in the file name path $filename =~ s/^.*[\\\/]//; $filename =~ s/::/\&\#58\;\&\#58\;/g; # remove semicolons foreach (keys %upload) { my ( $filename1, $title, $desc, $width, $height ) = split ( /::/, $upl +oad{$_} ); if ($filename1 eq $filename) { print qq(<font color="red">A file with that name already exists. Uplo +ad aborted.</font>); exit; } } # full file path to upload directory (must include filename) my $localfile = "/home/sulfericacid/public_html/gallery/images/$fi +lename"; # full url to upload directory (cannot include filename or an end +slash /) my $url = "http://sulfericacid.perlmonk.org/gallery/images"; my $type = uploadInfo($remotefile)->{'Content-Type'}; unless ( $type eq 'image/pjpeg' || $type eq 'image/gif' || $type e +q 'image/bmp') { print "Wrong! This is not a supported file type."; exit; } # open a new file and transfer bit by bit from what's in the buffe +r open( SAVED, ">>$localfile" ); # || die $!; while ( $bytesread = read( $remotefile, $buffer, 1024 ) ) { print SAVED $buffer; } close SAVED; chmod $mode, "$localfile"; # or die "can't chmod: $!"; print "-----------------------------<br>"; print qq(File was uploaded to <a href="$url\/$filename">$url\/$filename</a>) +; # required since module was not preinstalled on server use lib "/home/sulfericacid/public_html/lib/"; use Image::Info qw(image_info dim); # assigning info to a filename (better be an image) my $info =image_info("$localfile"); # if for any reason we can't open the file, this error trap should +pick it up if ( my $error = $info->{error} ) { #die "Can't parse image info: $error\n"; } # declaring the width and heighth of your image my ( $w, $h ) = dim($info); my $combo = join("::", $filename, $title, $desc, $w, $h); $upload{localtime()} = "$combo"; }


"Age is nothing more than an inaccurate number bestowed upon us at birth as just another means for others to judge and classify us"

sulfericacid

Replies are listed 'Best First'.
Re: Re: Cgi pm and photo uploads
by mandog (Curate) on Oct 04, 2003 at 23:29 UTC
    Hello sulfericacid

    Your script is pretty easy to follow. It does the job. However, there are a few things that could be tweaked

    You might put my $localfile at the top of the script. It will be easier to find there when you move the script to another host. Generally it is best to put constants like this at the top of the script.

    You might run in taint mode (put -T on the shbang line)

    You allow some nasty chars in the user supplied filename. Evil can be done to you with more than semicolons. Better to use the regex's in perldoc perlsec to ban everything except what you explicitly allow.

    Having your images directory world writable, is a bit risky. For one thing other users on your server will be able to clobber things.

    If it is not set globally, you might also look at $CGI::POST_MAX

    Hope this is helpful

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://296571]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (8)
As of 2021-02-25 08:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?