def read_multipart(boundary, content_length,request)
content_length = content_length.to_i
params = Hash.new([])
boundary = "--" + boundary
buf = ""
bufsize = 10 * 1024
$stdin.binmode if defined? $stdin.binmode
boundary_size = boundary.size + EOL.size
content_length -= boundary_size
status = $stdin.read(boundary_size)
loop do
head = nil
body = ''
until head and /#{boundary}(?:#{EOL}|--)/n.match(buf)
if (not head) and /#{EOL}#{EOL}/n.match(buf)
buf = buf.sub(/\A((?:.|\n)*?#{EOL})#{EOL}/n) do
head = $1.dup
""
end
next
end
if head and ( (EOL + boundary + EOL).size < buf.size )
body << buf[0 ... (buf.size - (EOL + boundary + EOL).size)]
buf[0 ... (buf.size - (EOL + boundary + EOL).size)] = ""
end
c = if bufsize < content_length
$stdin.read(bufsize) or ''
else
$stdin.read(content_length) or ''
end
buf.concat(c)
content_length -= c.size
end
buf = buf.sub(/\A((?:.|\n)*?)(?:#{EOL})?#{boundary}(#{EOL}|--)/n) do
body << $1
if "--" == $2
content_length = -1
end
""
end
/Content-Disposition:.* filename="?([^\";]*)"?/ni.match(head)
filename = ($1 or "")
if /Mac/ni.match(request.headers_in['HTTP_USER_AGENT']) and
/Mozilla/ni.match(request.headers_in['HTTP_USER_AGENT']) and
(not /MSIE/ni.match(request.headers_in['HTTP_USER_AGENT']))
filename = CGI::unescape(filename)
end
/Content-Type: (.*)/ni.match(head)
content_type = ($1 or "")
/Content-Disposition:.* name="?([^\";]*)"?/ni.match(head)
name = $1.dup
data = nil
if content_type.to_s != ''
data = Iowa::FileData.new(filename,content_type,body)
else
data = body
end
if params.has_key?(name)
if params[name].respond_to?(:push)
params[name].push data
else
params[name] = [params[name]] << data
end
else
params[name] = data
end
break if buf.size == 0
break if content_length === -1
end
params
end