Martin Hart wrote:
>Hi all,
>
>I have a single HTML form which contains simple text controls as well as file
>upload controls. I had assumed that the CGI library would return me items of
>type String for the text boxes and items of type Tempfile for the file upload
>boxes....
>
>However, it appears (after searching the archives) that StringIO is used
>instead of Tempfile on ruby 1.8 (in some cases and not others?), and that as
>soon as you specify an enctype of multipart you never? receive Strings but
>always receive either Tempfile or StringIO.
>
>This is what i really want from the CGI library:
>* CGI returns *everything* as a string except for file uploads - which are
>returned as Tempfiles
>
>Assuming that I cannot have that
can somebody in the know please tell me
>(or point me to some documentation)...
>
>1. how can I tell whether or not the supplied parameter was a file upload or
>simple text that has been passed to me as a Tempfile/StringIO? At the moment
>I don't know whether to copy the file or not - because I don't know if it is
>a valid file or just another parameter.
>
>2. do hidden controls work with multi-part forms? there is some discussion of
>them not working on the mailing list dating back to last November but I don't
>know if that has been fixed or not. My limited testing here indicates that
>hidden parameters are ignored on multipart forms?
>
>3. why are all values expressed as Tempfile/StringIO when using a multipart
>form? Why not just have the file uploads as tempfiles?
>
>4. how does the CGI library determine whether or not to switch between
>Tempfile/StringIO
>
>5. do I have to specifically close the IO object (assuming that one is
>returned?) - or perhaps I do not have to close the StringIO but I do have to
>close the Tempfile?
>
>6. are all of the form parameters in different tempfiles or are they all in
>one? Say i close the file after reading 1 argument ... does this mean that I
>cannot read any more?
>
>Thanks for any help you can give me - I am pretty stuck on this. If I get
>code working with StringIO objects it seems to break when I submit large
>files, and if I get code working with Tempfile it seems to break when I
>submit small files 
>
>Cheers,
>Martin
>
>
>
>
Here is the code that i use. Prob not the best but has worked for me so far.
class Upload
#{{{ -----------------------Uploads file to server from html
form--------------------------
#max size of file in bytes
MAX_SIZE = 100000
#where the file goes / MUST HAVE WRITE PRIVS HERE
PATH = "/home/paul/web/"
#how many file inputs - you can upload multiple files at once
FILE_COUNT = 3
#what file types do we allow?
CONTENT_TYPES= ['image/jpg','image/jpeg','image/gif','image/png']
def initialize
#how are things going?
@status = []
if $form.isPost
post
print @status.join('<br/>')
form
else
form
end
end
def form
#{{{
puts '<form method="post" enctype="multipart/form-data">'
FILE_COUNT.times do
puts '<p/><input type="file" name="myfile">'
end
puts '<p/><input type=hidden name=upl value="upload">'
puts '<br/><input type=checkbox name="overwrite"/>Overwrite?'
puts '<br/><input type="submit">'
puts '</form>'
end#}}}
def post
#{{{
oOverwrite = $cgi['overwrite'][0]
bOverwrite = false
overwrite = ''
if oOverwrite
overwrite = oOverwrite.read.chomp
if overwrite == 'on' then bOverwrite = true end
end
$cgi['myfile'].each do |incoming|
if incoming.size == 0
@status<< "Ignoring empty field"
next
end
if incoming.size > MAX_SIZE
@status<< "Data too large for
#{incoming.original_filename}(#{incoming.size} > #{MAX_SIZE})"
next
end
#need to strip

...trailing space...ouch
if not CONTENT_TYPES.include? incoming.content_type.strip
@status<< "Type not allowed(type =
#{incoming.content_type}) allowed content = #{CONTENT_TYPES.join(' | ')}"
next
end
#puts incoming.filename
# all should be ok to upload
sfilename = incoming.original_filename.untaint
#see if name has whacks...ie?
rdash = sfilename.rindex('\\')
if rdash
sfilename = sfilename[rdash+1,sfilename.length]
end
#physical path
path = PATH + $Domain + '/img/' + sfilename
if File.exist? path
if bOverwrite
File.delete path
else
@status<< "File already exists
(#{incoming.original_filename})"
next
end
end
#write to file
file = File.new(path.untaint,'w')
file << incoming.read
file.close
#path to link from web
httpPath = "http://#{$Domain}/img/#{sfilename}"
@status<< "Completed upload of <a target=_blank
href='#{httpPath}'>#{httpPath}</a>"
end
end#}}}
end#}}}
Upload.new