提交 b4330932 编写于 作者: J Jeremy Kemper

Ruby 1.9 compat: ensure binary encoding for post body parsing

上级 b5c8433a
......@@ -16,6 +16,7 @@ def self.included(base)
def initialize_with_stdinput(type = nil, stdinput = $stdin)
@stdinput = stdinput
@stdinput.set_encoding(Encoding::BINARY) if @stdinput.respond_to?(:set_encoding)
initialize_without_stdinput(type || 'query')
end
end
......
......@@ -65,6 +65,7 @@ def query_string
# variable is already set, wrap it in a StringIO.
def body
if raw_post = env['RAW_POST_DATA']
raw_post.force_encoding(Encoding::BINARY) if raw_post.respond_to?(:force_encoding)
StringIO.new(raw_post)
else
@cgi.stdinput
......
......@@ -228,6 +228,8 @@ def initialize(env, stdinput = nil)
super
stdinput.set_encoding(Encoding::BINARY) if stdinput.respond_to?(:set_encoding)
stdinput.force_encoding(Encoding::BINARY) if stdinput.respond_to?(:force_encoding)
@stdinput = stdinput.is_a?(IO) ? stdinput : StringIO.new(stdinput || '')
end
end
......@@ -382,6 +384,8 @@ def multipart_body(params, boundary)
multipart_requestify(params).map do |key, value|
if value.respond_to?(:original_filename)
File.open(value.path) do |f|
f.set_encoding(Encoding::BINARY) if f.respond_to?(:set_encoding)
<<-EOF
--#{boundary}\r
Content-Disposition: form-data; name="#{key}"; filename="#{CGI.escape(value.original_filename)}"\r
......
......@@ -466,8 +466,8 @@ def parse_request_parameters(params)
parser.result
end
def parse_multipart_form_parameters(body, boundary, content_length, env)
parse_request_parameters(read_multipart(body, boundary, content_length, env))
def parse_multipart_form_parameters(body, boundary, body_size, env)
parse_request_parameters(read_multipart(body, boundary, body_size, env))
end
def extract_multipart_boundary(content_type_with_parameters)
......@@ -519,7 +519,7 @@ def get_typed_value(value)
EOL = "\015\012"
def read_multipart(body, boundary, content_length, env)
def read_multipart(body, boundary, body_size, env)
params = Hash.new([])
boundary = "--" + boundary
quoted_boundary = Regexp.quote(boundary)
......@@ -529,8 +529,14 @@ def read_multipart(body, boundary, content_length, env)
# start multipart/form-data
body.binmode if defined? body.binmode
case body
when File
body.set_encoding(Encoding::BINARY) if body.respond_to?(:set_encoding)
when StringIO
body.string.force_encoding(Encoding::BINARY) if body.string.respond_to?(:force_encoding)
end
boundary_size = boundary.size + EOL.size
content_length -= boundary_size
body_size -= boundary_size
status = body.read(boundary_size)
if nil == status
raise EOFError, "no content body"
......@@ -541,7 +547,7 @@ def read_multipart(body, boundary, content_length, env)
loop do
head = nil
content =
if 10240 < content_length
if 10240 < body_size
UploadedTempfile.new("CGI")
else
UploadedStringIO.new
......@@ -563,24 +569,24 @@ def read_multipart(body, boundary, content_length, env)
buf[0 ... (buf.size - (EOL + boundary + EOL).size)] = ""
end
c = if bufsize < content_length
c = if bufsize < body_size
body.read(bufsize)
else
body.read(content_length)
body.read(body_size)
end
if c.nil? || c.empty?
raise EOFError, "bad content body"
end
buf.concat(c)
content_length -= c.size
body_size -= c.size
end
buf = buf.sub(/\A((?:.|\n)*?)(?:[\r\n]{1,2})?#{quoted_boundary}([\r\n]{1,2}|--)/n) do
content.print $1
if "--" == $2
content_length = -1
body_size = -1
end
boundary_end = $2.dup
boundary_end = $2.dup
""
end
......@@ -607,7 +613,7 @@ def read_multipart(body, boundary, content_length, env)
else
params[name] = [content]
end
break if content_length == -1
break if body_size == -1
end
raise EOFError, "bad boundary end of body part" unless boundary_end=~/--/
......
......@@ -49,7 +49,7 @@ def body
# Either the RAW_POST_DATA environment variable or the URL-encoded request
# parameters.
def raw_post
env['RAW_POST_DATA'] ||= url_encoded_request_parameters
env['RAW_POST_DATA'] ||= returning(url_encoded_request_parameters) { |b| b.force_encoding(Encoding::BINARY) if b.respond_to?(:force_encoding) }
end
def port=(number)
......@@ -340,6 +340,7 @@ def initialize(path, content_type = Mime::TEXT, binary = false)
@content_type = content_type
@original_filename = path.sub(/^.*#{File::SEPARATOR}([^#{File::SEPARATOR}]+)$/) { $1 }
@tempfile = Tempfile.new(@original_filename)
@tempfile.set_encoding(Encoding::BINARY) if @tempfile.respond_to?(:set_encoding)
@tempfile.binmode if binary
FileUtils.copy_file(path, @tempfile.path)
end
......
......@@ -511,16 +511,26 @@ def test_header_properly_reset_after_get_request
FILES_DIR = File.dirname(__FILE__) + '/../fixtures/multipart'
if RUBY_VERSION < '1.9'
READ_BINARY = 'rb'
READ_PLAIN = 'r'
else
READ_BINARY = 'rb:binary'
READ_PLAIN = 'r:binary'
end
def test_test_uploaded_file
filename = 'mona_lisa.jpg'
path = "#{FILES_DIR}/#{filename}"
content_type = 'image/png'
expected = File.read(path)
expected.force_encoding(Encoding::BINARY) if expected.respond_to?(:force_encoding)
file = ActionController::TestUploadedFile.new(path, content_type)
assert_equal filename, file.original_filename
assert_equal content_type, file.content_type
assert_equal file.path, file.local_path
assert_equal File.read(path), file.read
assert_equal expected, file.read
end
def test_test_uploaded_file_with_binary
......@@ -529,10 +539,10 @@ def test_test_uploaded_file_with_binary
content_type = 'image/png'
binary_uploaded_file = ActionController::TestUploadedFile.new(path, content_type, :binary)
assert_equal File.open(path, 'rb').read, binary_uploaded_file.read
assert_equal File.open(path, READ_BINARY).read, binary_uploaded_file.read
plain_uploaded_file = ActionController::TestUploadedFile.new(path, content_type)
assert_equal File.open(path, 'r').read, plain_uploaded_file.read
assert_equal File.open(path, READ_PLAIN).read, plain_uploaded_file.read
end
def test_fixture_file_upload_with_binary
......@@ -541,10 +551,10 @@ def test_fixture_file_upload_with_binary
content_type = 'image/jpg'
binary_file_upload = fixture_file_upload(path, content_type, :binary)
assert_equal File.open(path, 'rb').read, binary_file_upload.read
assert_equal File.open(path, READ_BINARY).read, binary_file_upload.read
plain_file_upload = fixture_file_upload(path, content_type)
assert_equal File.open(path, 'r').read, plain_file_upload.read
assert_equal File.open(path, READ_PLAIN).read, plain_file_upload.read
end
def test_fixture_file_upload
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册