CGI Upload Problems

H

Hal Vaughan

I've written Perl scripts to upload files before, but I'm having a lot of
problems getting it to work in this case. I have a form with nothing
outstanding about it and I'm simply trying to use the CGI::param(filename)
to get the handle so I can read from it and write it to a file on my web
server.

I've snipped the other parts, since the form and Perl code would be long.
Here's the basic form:

<form method="post" action="/perl/upload.pl" name="DataUpload">
UploadData: <input name="uploaddata" type="file">
<input name="UploadData" value="Submit" align="left" type="submit">
</form>

And here's what I have in my upload.pl script:
(again, the relevant parts, only)

use CGI;
$fname = CGI::param("file");
$fdata = CGI::param("data");
# $uhandle = CGI::param("uploaddata");
$uhandle = CGI::upload("uploaddata");
$tfile = "/var/www/data/temp.upload";
open OUT, ">$tfile";
binmode OUT;
$fdata = <$uhandle> or cgilog("DEBUG Upload Error: $!");
print OUT $fdata;
close OUT;

At this point I'm only testing this with a text file that is less than 50
bytes long, so I'm not worried about reading in too much data at once.
Once I've got it working, I'll replace that with a loop to read from the
file handle with a specified buffer length and write to the output.

cgilog() is my own logging routine that just dumps the log statements to a
log file. In this case, I keep getting either "No such file or directory"
as the error or no error reported at all. I also have uncommented the
commented out line and used that to replace the line above it. It makes no
difference.

My guess is this is something extremely simple and obvious that I expect to
be doing that I'm not because I've gone over this many times and spent
hours on Google to try to find what I'm doing wrong, but I can't find a
thing.

This is for a system running Apache (1.3) on Linux.

Thanks for any help.

Hal
 
H

Hal Vaughan

Forgot to include with this that it is on a secure server, using an HTTPS
page instead of HTTP. I don't know if that makes a difference.
 
P

Paul Lalli

Hal said:
I've written Perl scripts to upload files before, but I'm having a lot of
problems getting it to work in this case. I have a form with nothing
outstanding about it and I'm simply trying to use the CGI::param(filename)
to get the handle so I can read from it and write it to a file on my web
server.

I've snipped the other parts, since the form and Perl code would be long.
Here's the basic form:

<form method="post" action="/perl/upload.pl" name="DataUpload">

You forgot the critical component:
enctype="multipart/form-data"

That attribute *must* be in your form tag for any file upload fields to
work.

(This, of course, has nothing to do with Perl, and everything to do
with CGI)

Paul Lalli
 
H

Hal Vaughan

Paul said:
You forgot the critical component:
enctype="multipart/form-data"

That attribute *must* be in your form tag for any file upload fields to
work.

(This, of course, has nothing to do with Perl, and everything to do
with CGI)

Paul Lalli

Ouch.

I knew it had to be something so obvious that I expected it and kept missing
it when I checked it over (and a symbol recognition learning disability
doesn't help!).

I added this and now it works on my test server on my LAN, but does not work
on the web server I rent space on. Other upload tests work on that server,
but not this one.

Thanks and I'll post when I find out why it's working on my LAN and not on
the Internet server.

Hal
 
H

Hal Vaughan

This just does not make sense, but it fixes it. Any insight would be
appreciated.

I had a sample working that I had cut and pasted from a web page. I changed
the example script enough so it was working with the form I was already
using. I got it working without much trouble. Then I started copying over
lines from the non-working script to the example script. It worked fine.
Then I reversed the process, and it never would work.

I finally noticed the only difference was that the non-working script had 2
things the other didn't: "use strict;" and variable declarations with two
"our (...);" statements. It turns out if I declare $uhandle with all the
other variables, it does not work. The full script is rather short, so I
was declaring any variables that were used in the main script as "our" and
variables in routines as "my". (This isn't my normal way, but, again, this
script is short).

If $uhandle is declared as "our", it won't upload the file. If I declare it
with "my" it'll work. I've never seen a problem like this. Could it
somehow be interfering with the namespace in CGI or something else? I can
make this work now by just declaring it with "my", but does anyone know why
that makes a difference?

This is on Perl 5.6.0. The local server is 5.8.?, which would explain why
it worked on the local server and not the Internet one.

Hal
 
X

xhoster

Hal Vaughan said:
I've snipped the other parts, since the form and Perl code would be long.
Here's the basic form:

<form method="post" action="/perl/upload.pl" name="DataUpload">
UploadData: <input name="uploaddata" type="file">
<input name="UploadData" value="Submit" align="left" type="submit">
</form>

And here's what I have in my upload.pl script:
(again, the relevant parts, only)

use CGI;

No use strict?
$fname = CGI::param("file");
$fdata = CGI::param("data");

What is the point of these two lines?
# $uhandle = CGI::param("uploaddata");
$uhandle = CGI::upload("uploaddata");
$tfile = "/var/www/data/temp.upload";
open OUT, ">$tfile";

Always check the success of open.
binmode OUT;
$fdata = <$uhandle> or cgilog("DEBUG Upload Error: $!");

It is not an error for a file-handle read to return a false value.
print OUT $fdata;
close OUT;

Usually check the success of close.

At this point I'm only testing this with a text file that is less than 50
bytes long, so I'm not worried about reading in too much data at once.
Once I've got it working, I'll replace that with a loop to read from the
file handle with a specified buffer length and write to the output.

CGI.pm already did this for you once (and your web server may have already
done it a second time.) You might want to look into simply copying the
temporary file that already exists.
cgilog() is my own logging routine that just dumps the log statements to
a log file. In this case, I keep getting either "No such file or
directory"

Since reading an false value from a file-handle is not an error, the value
of $! after doing that is not meaningful. It is just left over from
whatever was in $! from some unknown point in the past.

Xho
 
J

J. Gleixner

Hal said:
This just does not make sense, but it fixes it. Any insight would be
appreciated. [...]
If $uhandle is declared as "our", it won't upload the file. If I declare it
with "my" it'll work. I've never seen a problem like this. Could it
somehow be interfering with the namespace in CGI or something else? I can
make this work now by just declaring it with "my", but does anyone know why
that makes a difference?

This is on Perl 5.6.0. The local server is 5.8.?, which would explain why
it worked on the local server and not the Internet one.

The answer, or at least a good clue, should be found in your Web
server's error log. Hint: perldoc -f our
 
G

Gunnar Hjalmarsson

Paul said:
You forgot the critical component:
enctype="multipart/form-data"

That attribute *must* be in your form tag for any file upload fields to
work.

(This, of course, has nothing to do with Perl, and everything to do
with CGI)

True. Nevertheless, by using the Perl module CGI::UploadEasy you get
help to identify that rather common mistake.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top