Problems mixing regular form fields with file uploads

I’m trying to build a form that includes both regular form fields, such
as text inputs and checkboxes, along with file uploading. It seems,
though, that all the fields are treated like a File when a file input
is used. I’ve tried to narrow it down with this script:

require 'CGI’
cgi = CGI.new

if cgi.params.length == 0
print ""
print ""
print ""
else
$stderr << cgi.params[‘title’].first
$stderr << cgi.params[‘logo’].first.original_filename
end

Entering “A picture” in the title input and choosing a file called
"123.jpg" would add the following to the log: “A picture123.jpg”.
Instead I get “#<File:0x40b7e8>123.jpg”.

Entering “A picture” in the title input and not choosing a file
produces:
#StringIO:0x209a52c#StringIO:0x20b3f04

I’m baffled. Why is the title input treated first as a file and since
as a StringIO? I reckon it has something to do with the enctype, but I
can’t seem to come up with a solution.

How would one go about extracting regular form data alongside file
handling?

Note, I’m using mod_ruby 1.1.1, Apache 1.3.x, and Ruby 1.8.0 on OS X
10.3.

// David

I’ve narrowed the problem down even further. It appears to be a problem
with the total length of the request. If I upload a 10K file and a
“hehe” in the text, both are presented as StringIO objects that can be
read.

If I upload a 15K file and a “hehe” the file is presented as a
StringIO, but the “hehe” as a File object.

If I upload a 20K file and a “hehe” both are presented as File objects.

Additionally, as soon as either of the fields switch to the file object
representation they’re representing empty files. So doing a .size
returns 0, whereas the correct size is returned on the StringIO
objects.

I’ve tried this on two different setups now. Ruby 1.8.0/mod_ruby
1.0.7/OS X 10.3 and on a Ruby 1.8.0/mod_ruby 1.1.1/FreeBSD 4.8. Both
exhibit the exact same symptoms.

So even though I’m somewhat wiser of the problem cause, I’m even more
baffled about what to do.

Unlike PHP, it doesn’t seem like mod_ruby exposes any
upload_max_filesize or post_max_size variables. And in any case, why
would they be set so low (around 16K) on default? And what’s the point
in switching from a StringIO to a File object representation?

So many questions… (hopefully at least some answers, this time ;))

I’m trying to build a form that includes both regular form fields,
such as text inputs and checkboxes, along with file uploading. It
seems, though, that all the fields are treated like a File when a file
input is used. I’ve tried to narrow it down with this script:

require ‘CGI’
cgi = CGI.new

if cgi.params.length == 0
print “”
print “”
print “”
else
$stderr << cgi.params[‘title’].first
$stderr << cgi.params[‘logo’].first.original_filename
end

Entering “A picture” in the title input and choosing a file called
“123.jpg” would add the following to the log: “A picture123.jpg”.
Instead I get “#<File:0x40b7e8>123.jpg”.

Entering “A picture” in the title input and not choosing a file
produces:
#StringIO:0x209a52c#StringIO:0x20b3f04

I’m baffled. Why is the title input treated first as a file and since
as a StringIO? I reckon it has something to do with the enctype, but I
can’t seem to come up with a solution.

How would one go about extracting regular form data alongside file
handling?

Note, I’m using mod_ruby 1.1.1, Apache 1.3.x, and Ruby 1.8.0 on OS X
10.3.

// David


David Heinemeier Hansson.
http://www.loudthinking.com/ – Broadcasting Brain