Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

File Upload

by rsiedl (Friar)
on Jul 13, 2004 at 19:34 UTC ( [id://374115]=perlquestion: print w/replies, xml ) Need Help??

rsiedl has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I'm having some trouble uploading a file from a web page form.
The form submits and creates the file, but the file is 0 bytes.
I'm using Perl 5.8.4, CGI and Apache2 on FC1. The same script was working with Perl 5.6, CGI and Apache1 on RH7.2...
Here's my code:
my $error = undef; my $directory = "./tmp/"; my $filename = $q->param("filename"); my $origfile = $filename; $filename =~ s/^.*[\\\/:]//; if ( open(OUTFILE,'>'.$directory.$filename) ) { binmode OUTFILE; my $bytesread; my $buffer; while ( !$error && ( $bytesread = read ($origfile,$buffer,4096) ) ) +{ if ( !(print OUTFILE $buffer) ) { $error = 'Could not save uploaded file'; } } close OUTFILE; } else { # error <- file creation error $error = 'Could not create file'; } close($filename);
Anyone have any ideas?

Cheers,
Reagen

Note I have replaced the instance of attachfile with filename

Update I have just found I am getting "read() on unopened filehandle at line..." (the line where it reads) in the apache log.

Solution I found the solution. I had my upload script in a sub and this is how i was calling it:
my $filename = $q->param("filename"); &uploadFile("$filename");
When i removed the "s from the sub line
&uploadFile($filename);
it worked. dont know why.

Replies are listed 'Best First'.
Re: File Upload
by Ovid (Cardinal) on Jul 13, 2004 at 19:53 UTC

    You have a possible security hole here.

    my $filename = " ../../asdf"; $filename =~ s/^.*[\\\/:]//; print $filename;

    In other words, someone can submit a form with the filename containing a newline and possibly have some fun. I've not played around with tha too much, but it's worth considering. Instead, try a variant of:

    my $_filename = $p->param('filename') || ''; my ($filename) = $_filename =~ /(\w+)$/; # only use word characters fr +om the end

    Also, have you double-checked that the form in question used multipart-formdata encoding (or however you spell it)?

    Cheers,
    Ovid

    New address of my CGI Course.

      thanks for the pointer on the security.

      Yep, using enctype="multipart/form-data".
Re: File Upload
by delirium (Chaplain) on Jul 13, 2004 at 19:43 UTC
    Is that the entire script? I see you close $attachfile and read from it, but where is it opened at?

    Also, (and I know you said the file got created, so this may be a moot question) does "./tmp/" exist and is it writable by your webserver's UID?

      Oops, forgot to change the attachfile to filename.

      yep. ./tmp exists and is writable. i have also tried it as world writable (777).
Re: File Upload
by iburrell (Chaplain) on Jul 13, 2004 at 20:18 UTC
    Do you get an error message? I don't see the error being reported anywhere. I suggest putting $! in the error strings so you can see the reason for a failure. You don't really need to check the return value of the print. Writing to a local file will rarely fail; the common problem of disk full will be reported if you check the return of the close.

    Also, check $q->cgi_error() at the top. If CGI.pm can't parse the POST, then it will show up there. And check that $filename is not undef, which happens with the missing form param.

    Another thing to try is instrument the read loop. Print out the bytesread. This will give a good indication of what is being read.

Re: File Upload
by davidj (Priest) on Jul 13, 2004 at 19:43 UTC
    I do not see in your code where you are opening the file referenced by $attachfile. Could that be the problem?

    davidj
      I'd run this with strict and check the permissions on Apache.
      ah sorry. I modified the code to make it simpler for my posting and missed that reference.
      $code =~ s/attachfile/filename/g
Re: File Upload
by knoebi (Friar) on Jul 14, 2004 at 08:24 UTC
    this is a very commen problem and so there are many solutions for this problem at cpan. CGI::Upload would be one of them...
Re: File Upload
by bradcathey (Prior) on Aug 29, 2004 at 14:40 UTC

    Strange solution, I have been unsuccessful (file name is created, but 0 bytes) trying to pass the image file name as a scalar into an upload subroutine, as in your example

    my $filename = $q->param('filename'); &uploadFile($filename); sub uploadFile { my $file = shift; ...

    and found success only in grabbing it within the subroutine itself.

    sub uploadFile { my $file = $q->param('filename'); ...

    And I'm not really sure why. But I'd thought I'd add this to the discussion in hopes to better understand the process.


    —Brad
    "Don't ever take a fence down until you know the reason it was put up." G. K. Chesterton

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://374115]
Approved by kvale
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (5)
As of 2024-04-25 08:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found