def self.multipart(request, boundary, content_length)
boundary = "--#{boundary}"
paramhsh = {}
buf = ""
input = request
input.binmode if defined? input.binmode
boundary_size = boundary.size + EOL.size
bufsize = 16384
content_length -= boundary_size
key_memo = []
status = input.read(boundary_size)
return {} if status == nil || status.empty?
raise ControllerExceptions::MultiPartParseError, "bad content body:\n'#{status}' should == '#{boundary + EOL}'" unless status == boundary + EOL
rx = /(?:#{EOL})?#{Regexp.quote(boundary)}(#{EOL}|--)/n
loop {
head = nil
body = ''
filename = content_type = name = nil
read_size = 0
until head && buf =~ rx
i = buf.index("\r\n\r\n")
if( i == nil && read_size == 0 && content_length == 0 )
content_length = -1
break
end
if !head && i
head = buf.slice!(0, i+2)
buf.slice!(0, 2)
filename = head[FILENAME_REGEX, 1]
content_type = head[CONTENT_TYPE_REGEX, 1]
name = head[NAME_REGEX, 1]
if filename && !filename.empty?
body = Tempfile.new(:Merb)
body.binmode if defined? body.binmode
end
next
end
if head && (boundary_size+4 < buf.size)
body << buf.slice!(0, buf.size - (boundary_size+4))
end
read_size = bufsize < content_length ? bufsize : content_length
if( read_size > 0 )
c = input.read(read_size)
raise ControllerExceptions::MultiPartParseError, "bad content body" if c.nil? || c.empty?
buf << c
content_length -= c.size
end
end
if i = buf.index(rx)
if (i > 2) && (j = buf.index(rx, i-2)) && (j < i)
i = j
end
body << buf.slice!(0, i)
buf.slice!(0, boundary_size+2)
content_length = -1 if $1 == "--"
end
if filename && !filename.empty?
body.rewind
data = {
:filename => File.basename(filename),
:content_type => content_type,
:tempfile => body,
:size => File.size(body.path)
}
else
data = body
end
unless key_memo.include?(name) && name !~ /\[\]/
paramhsh = normalize_params(paramhsh,name,data)
end
key_memo << name if filename && !filename.empty?
break if buf.empty? || content_length == -1
}
paramhsh
end