I wrote a nice description of this issue, but snippets ate it.
In short, this parses complicated form names into nice hashes, i.e. name[asd][asd] for multipart forms.
module Camping module Base def initialize(r, e, m) #:nodoc: e = H[e.to_hash] @status, @method, @env, @headers, @root = 200, m.downcase, e, {'Content-Type'=>'text/html'}, e.SCRIPT_NAME.sub(/\/$/,'') @k = C.kp(e.HTTP_COOKIE) qs = C.qs_parse(e.QUERY_STRING) @in = r todo = [] if %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)|n.match(e.CONTENT_TYPE) b = /(?:\r?\n|\A)#{Regexp::quote("--#$1")}(?:--)?\r$/ until @in.eof? fh=H[] for l in @in case l when Z: break when /^Content-Disposition: form-data;/ fh.u H[*$'.scan(/(?:\s(\w+)="([^"]+)")/).flatten] when /^Content-Type: (.+?)(\r$|\Z)/m puts "=> fh[type] = #$1" fh[:type] = $1 end end fn=fh[:name] o=if fh[:filename] o=fh[:tempfile]=Tempfile.new(:C) o.binmode else fh="" end while l=@in.read(16384) if l=~b o<<$`.chomp @in.seek(-$'.size,IO::SEEK_CUR) break end o<< l end if(fn) qs.merge!(C.qs_parse(fn + "=1")) parts = fn.split(/\[/) line = "" parts.each do |pp| pp = pp.gsub(/\]/,"") line += "['#{pp}']" end #p "line is:" #p line #p fh todo << ["qs#{line}", fh] #eval("qs#{line} = fh") #p qs end fh[:tempfile].rewind if fh.is_a?H end elsif @method == "post" qs.merge!(C.qs_parse(@in.read)) end #post process vars todo.each do |n| eval("#{n.first} = n.last") end #p "END QUERY" #p qs #exit @cookies, @input = @k.dup, qs.dup end end end // insert code here..