# File lib/cgi_multipart_eof_fix.rb, line 16
16: def read_multipart(boundary, content_length)
17: params = Hash.new([])
18: boundary = "--" + boundary
19: quoted_boundary = Regexp.quote(boundary, "n")
20: buf = ""
21: bufsize = 10 * 1024
22: boundary_end=""
23:
24: # start multipart/form-data
25: stdinput.binmode if defined? stdinput.binmode
26: boundary_size = boundary.size + EOL.size
27: content_length -= boundary_size
28: status = stdinput.read(boundary_size)
29: if nil == status
30: raise EOFError, "no content body"
31: elsif boundary + EOL != status
32: raise EOFError, "bad content body #{status.inspect} expected, got #{(boundary + EOL).inspect}"
33: end
34:
35: loop do
36: head = nil
37: if 10240 < content_length
38: require "tempfile"
39: body = Tempfile.new("CGI")
40: else
41: begin
42: require "stringio"
43: body = StringIO.new
44: rescue LoadError
45: require "tempfile"
46: body = Tempfile.new("CGI")
47: end
48: end
49: body.binmode if defined? body.binmode
50:
51: until head and /#{quoted_boundary}(?:#{EOL}|--)/.match(buf)
52:
53: if (not head) and /#{EOL}#{EOL}/.match(buf)
54: buf = buf.sub(/\A((?:.|\n)*?#{EOL})#{EOL}/) do
55: head = $1.dup
56: ""
57: end
58: next
59: end
60:
61: if head and ( (EOL + boundary + EOL).size < buf.size )
62: body.print buf[0 ... (buf.size - (EOL + boundary + EOL).size)]
63: buf[0 ... (buf.size - (EOL + boundary + EOL).size)] = ""
64: end
65:
66: c = if bufsize < content_length
67: stdinput.read(bufsize)
68: else
69: stdinput.read(content_length)
70: end
71: if c.nil? || c.empty?
72: raise EOFError, "bad content body"
73: end
74: buf.concat(c)
75: content_length -= c.size
76: end
77:
78: buf = buf.sub(/\A((?:.|\n)*?)(?:[\r\n]{1,2})?#{quoted_boundary}([\r\n]{1,2}|--)/) do
79: body.print $1
80: if "--" == $2
81: content_length = 1
82: end
83: boundary_end = $2.dup
84: ""
85: end
86:
87: body.rewind
88:
89: /Content-Disposition:.* filename="?([^\";]*)"?/i.match(head)
90: filename = ($1 or "")
91: if /Mac/i.match(env_table['HTTP_USER_AGENT']) and
92: /Mozilla/i.match(env_table['HTTP_USER_AGENT']) and
93: (not /MSIE/i.match(env_table['HTTP_USER_AGENT']))
94: filename = CGI::unescape(filename)
95: end
96:
97: /Content-Type: (.*)/i.match(head)
98: content_type = ($1 or "")
99:
100: (class << body; self; end).class_eval do
101: alias local_path path
102: define_method(:original_filename) {filename.dup.taint}
103: define_method(:content_type) {content_type.dup.taint}
104: end
105:
106: /Content-Disposition:.* name="?([^\";]*)"?/i.match(head)
107: name = $1.dup
108:
109: if params.has_key?(name)
110: params[name].push(body)
111: else
112: params[name] = [body]
113: end
114: break if buf.size == 0
115: break if content_length === 1
116: end
117: raise EOFError, "bad boundary end of body part" unless boundary_end=~/--/
118:
119: params
120: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.