On Fri, 10 Feb 2006, Michael Schilling wrote: > Hello again, > > as I couldn't reproduce the described multipart_form error (see > description below) directly on the command-line I looked into the cgi.rb > source and found the chunk of code that raises the exception: the problem is in your source i'm afraid. you can call CGI.new more than once in a script : each call attempts to parse ENV and STDIN according to the cgi spec. check out the docs for details. the other issue is that if, and only if, you create a form using multipar the cgi params are either StringIO or Tempfile objects. this is a good thing. consider a 10GB file upload. you need a way to determine this. following is one way: harp:~> cat a.rb #! /usr/local/bin/ruby require "cgi" class Upload attr_accessor 'cgi' def initialize self.cgi = CGI::new 'html4' file = get 'file' file ? answer : make_form end def make_form cgi.out { cgi.html { cgi.body { "\n" + cgi.multipart_form{ "\n" + cgi.file_field("file",40,500000) + "\n" + cgi.br + cgi.submit("test it") + "\n" } } } } end def answer cgi.out { cgi.html { cgi.body{ "\n" + cgi.p{ "This should be the filename : " + param('file').original_filename + "\n" } + cgi.br } } } end def get key value = param key value = value.read.strip if value.respond_to?('read') value end def param key cgi.params[key].first end end Upload::new if $0 == __FILE__ this should run with ruby 1.8 up. inlined below is a totally simple upload script i sometimes use for personal stuff. it allows upload/download and some other stuff. regards. -a -- happiness is not something ready-made. it comes from your own actions. - h.h. the 14th dali lama #! /usr/local/bin/ruby require 'cgi' require 'tempfile' require 'ftools' require 'uri' cgi = CGI::new user = ENV['REMOTE_USER'] || 'anonymous' headers = {} content = '' begin mode = cgi.params['m'].first || 'index' mode = mode.read.strip if mode.respond_to? 'read' case mode when /index|^$/ files = Dir['**/*'].select{|f| f !~ %r/html|cgi/} dirname = File::dirname cgi.script_name files.sort!{|a,b| File::stat(b).mtime <=> File::stat(a).mtime} table_rows = files.collect do |f| stat = File::stat f uri = 'http://' << cgi.host << File::join(dirname, f) # <a href=#{ URI::escape f } title="right click -> save as">download</a> <<-html <tr valign=top aligh=left> <td> #{ CGI::escapeHTML f } </td> <td> #{ CGI::escapeHTML stat.mtime.to_s } </td> <td> #{ CGI::escapeHTML stat.size.to_s } </td> <td> <a href=#{ uri } title="right click -> save (page) as">#{ uri }</a> </td> </tr> html end table = <<-html <table width=100%> <tr valign=top aligh=left> <td> <b><u> file </b></u> </td> <td> <b><u> modification time </b></u> </td> <td> <b><u> size </b></u> </td> <td> <b><u> download </b></u> </td> </tr> #{ table_rows } </table> html content = <<-html <html> <head> <title>#{ user }::files</title> </head> <body> <h3>#{ user }::files</h3> <table cellpadding=1 align=right width=100%> <tr align=right> <td> <i>to download - right click -> save as</i> </td> </tr> </table> <hr> <hr> </table> <hr> #{ table } <hr> <h3><a href=#{ cgi.script_name }?m=upload>upload files</a></h3> </body> </html> html when /upload/ buttons = [] 8.times do buttons << <<-html <input size=100 name=file type=file> <hr width=30% align=left> html end content = <<-html <html> <head> <title>#{ user }::upload</title> </head> <body> <h3>#{ user }::upload</h3> <hr> <form action=#{ cgi.script_name } method=POST enctype=multipart/form-data> <input size=100 name=file type=file> <hr width=30% align=left> #{ buttons } <input type=submit value=upload> <hr width=30% align=left> <input type=reset value=clear> <hr width=30% align=left> <input type=hidden name=m value=put> <form> <hr> <h3><a href=#{ cgi.script_name }?m=index>index</a></h3> </body> </html> html when /put/ uploaded = [] tempfiles = cgi.params['file'] tempfiles.each do |tempfile| org_path = tempfile.original_filename local = "#{ org_path }" local.gsub! %r|[/\\]|,'/' local.gsub! %r|\s+|,'_' local.downcase! next if local =~ /^\s*$/ begin File::mkpath(File::dirname(local)) rescue nil if tempfile.path File::copy tempfile.path, local else open(local,'w'){|f| f.write tempfile.read} end File::chmod 0777, local uploaded << [org_path, true] rescue raise raise tempfile.methods.inspect uploaded << [org_path, false] end end table_rows = uploaded.collect do |u| f, status = u s = (status ? 'success' : 'failed') <<-html <tr valign=top aligh=left> <td> #{ CGI::escapeHTML f.inspect } </td> <td> #{ s } </td> </tr> html end table = <<-html <table width=100%> <tr valign=top aligh=left> <td> <b><u> file </b></u> </td> <td> <b><u> status </b></u> </td> </tr> #{ table_rows } </table> html content = <<-html <html> <head> <title>#{ user }::uploaded</title> </head> <body> <h3>#{ user }::uploaded</h3> </table> <hr> #{ table } <hr> <h3><a href=#{ cgi.script_name }?m=index>index</a></h3> </body> </html> html else content = "#{ cgi.inspect }" content << '<hr>' content << cgi.params.inspect content << '<hr>' content << cgi.params.map{|key,value| [key.inspect, value.map{|v| [v.inspect, v.class]}.inspect]}.inspect end rescue Exception => e content = "<b>#{ e.message } - (#{ e.class })</b><hr>#{ e.backtrace.join '<br>' }" ensure cgi.out{ content.to_s } end