From: ara.t.howard@... Date: 2006-02-10T13:57:21+09:00 Subject: Re: can't get multipart_form from cgi.rb to work 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) # download <<-html #{ CGI::escapeHTML f } #{ CGI::escapeHTML stat.mtime.to_s } #{ CGI::escapeHTML stat.size.to_s } #{ uri } html end table = <<-html #{ table_rows }
file modification time size download
html content = <<-html #{ user }::files

#{ user }::files

to download - right click -> save as



#{ table }

upload files

html when /upload/ buttons = [] 8.times do buttons << <<-html
html end content = <<-html #{ user }::upload

#{ user }::upload



#{ buttons }


index

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 #{ CGI::escapeHTML f.inspect } #{ s } html end table = <<-html #{ table_rows }
file status
html content = <<-html #{ user }::uploaded

#{ user }::uploaded


#{ table }

index

html else content = "#{ cgi.inspect }" content << '
' content << cgi.params.inspect content << '
' content << cgi.params.map{|key,value| [key.inspect, value.map{|v| [v.inspect, v.class]}.inspect]}.inspect end rescue Exception => e content = "#{ e.message } - (#{ e.class })
#{ e.backtrace.join '
' }" ensure cgi.out{ content.to_s } end