mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Set RAW_POST_DATA when request parameters are parsed.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@6823 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
parent
7b99b40352
commit
4bd3e3aa1b
3 changed files with 44 additions and 45 deletions
|
@ -72,7 +72,7 @@ module ActionController #:nodoc:
|
|||
end
|
||||
|
||||
def request_parameters
|
||||
@request_parameters ||= self.class.parse_formatted_request_parameters(body, content_type_with_parameters, content_length, env)
|
||||
@request_parameters ||= parse_formatted_request_parameters
|
||||
end
|
||||
|
||||
def cookies
|
||||
|
|
|
@ -231,11 +231,14 @@ module ActionController
|
|||
end
|
||||
|
||||
|
||||
# Receive the raw post data.
|
||||
# This is useful for services such as REST, XMLRPC and SOAP
|
||||
# which communicate over HTTP POST but don't use the traditional parameter format.
|
||||
# Read the request body. This is useful for web services that need to
|
||||
# work with raw requests directly.
|
||||
def raw_post
|
||||
@env['RAW_POST_DATA'] ||= body.read
|
||||
unless env.include? 'RAW_POST_DATA'
|
||||
env['RAW_POST_DATA'] = body.read(content_length)
|
||||
body.rewind if body.respond_to?(:rewind)
|
||||
end
|
||||
env['RAW_POST_DATA']
|
||||
end
|
||||
|
||||
# Returns both GET and POST parameters in a single hash.
|
||||
|
@ -312,37 +315,26 @@ module ActionController
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
class << self
|
||||
def extract_content_type_without_parameters(content_type_with_parameters)
|
||||
$1.strip.downcase if content_type_with_parameters =~ /^([^,\;]*)/
|
||||
end
|
||||
|
||||
def parse_formatted_request_parameters(body, content_type_with_parameters, content_length, env = {})
|
||||
content_length = content_length.to_i
|
||||
def parse_formatted_request_parameters
|
||||
return {} if content_length.zero?
|
||||
|
||||
content_type, boundary = extract_multipart_boundary(content_type_with_parameters.to_s)
|
||||
content_type, boundary = self.class.extract_multipart_boundary(content_type_with_parameters)
|
||||
return {} if content_type.blank?
|
||||
|
||||
mime_type = Mime::Type.lookup(content_type)
|
||||
strategy = ActionController::Base.param_parsers[mime_type]
|
||||
|
||||
# Only multipart form parsing expects a stream.
|
||||
if strategy && strategy != :multipart_form
|
||||
data = body.read(content_length)
|
||||
body.rewind if body.respond_to?(:rewind)
|
||||
body = data
|
||||
end
|
||||
body = raw_post if strategy && strategy != :multipart_form
|
||||
|
||||
case strategy
|
||||
when Proc
|
||||
strategy.call(body)
|
||||
when :url_encoded_form
|
||||
clean_up_ajax_request_body! body
|
||||
parse_query_parameters(body)
|
||||
self.class.clean_up_ajax_request_body! body
|
||||
self.class.parse_query_parameters(body)
|
||||
when :multipart_form
|
||||
parse_multipart_form_parameters(body, boundary, content_length, env)
|
||||
self.class.parse_multipart_form_parameters(body, boundary, content_length, env)
|
||||
when :xml_simple, :xml_node
|
||||
body.blank? ? {} : Hash.from_xml(body).with_indifferent_access
|
||||
when :yaml
|
||||
|
@ -359,6 +351,7 @@ module ActionController
|
|||
"backtrace" => e.backtrace }
|
||||
end
|
||||
|
||||
class << self
|
||||
def parse_query_parameters(query_string)
|
||||
return {} if query_string.blank?
|
||||
|
||||
|
@ -402,6 +395,24 @@ module ActionController
|
|||
parse_request_parameters(read_multipart(body, boundary, content_length, env))
|
||||
end
|
||||
|
||||
def extract_multipart_boundary(content_type_with_parameters)
|
||||
if content_type_with_parameters =~ MULTIPART_BOUNDARY
|
||||
['multipart/form-data', $1.dup]
|
||||
else
|
||||
extract_content_type_without_parameters(content_type_with_parameters)
|
||||
end
|
||||
end
|
||||
|
||||
def extract_content_type_without_parameters(content_type_with_parameters)
|
||||
$1.strip.downcase if content_type_with_parameters =~ /^([^,\;]*)/
|
||||
end
|
||||
|
||||
def clean_up_ajax_request_body!(body)
|
||||
body.chop! if body[-1] == 0
|
||||
body.gsub!(/&_=$/, '')
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
def get_typed_value(value)
|
||||
case value
|
||||
|
@ -454,20 +465,6 @@ module ActionController
|
|||
|
||||
MULTIPART_BOUNDARY = %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n
|
||||
|
||||
def extract_multipart_boundary(content_type_with_parameters)
|
||||
if content_type_with_parameters =~ MULTIPART_BOUNDARY
|
||||
['multipart/form-data', $1.dup]
|
||||
else
|
||||
extract_content_type_without_parameters(content_type_with_parameters)
|
||||
end
|
||||
end
|
||||
|
||||
def clean_up_ajax_request_body!(body)
|
||||
body.chop! if body[-1] == 0
|
||||
body.gsub!(/&_=$/, '')
|
||||
end
|
||||
|
||||
|
||||
EOL = "\015\012"
|
||||
|
||||
def read_multipart(body, boundary, content_length, env)
|
||||
|
|
|
@ -708,9 +708,7 @@ class MultipartRequestParameterParsingTest < Test::Unit::TestCase
|
|||
private
|
||||
def process(name)
|
||||
File.open(File.join(FIXTURE_PATH, name), 'rb') do |file|
|
||||
content_length = file.stat.size.to_s
|
||||
content_type = 'multipart/form-data, boundary=AaB03x'
|
||||
ActionController::AbstractRequest.parse_formatted_request_parameters(file, content_type, content_length)
|
||||
ActionController::AbstractRequest.parse_multipart_form_parameters(file, 'AaB03x', file.stat.size, {})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -718,9 +716,7 @@ end
|
|||
|
||||
class XmlParamsParsingTest < Test::Unit::TestCase
|
||||
def test_single_file
|
||||
body = "<person><name>David</name><avatar type='file' name='me.jpg' content_type='image/jpg'>#{Base64.encode64('ABC')}</avatar></person>"
|
||||
|
||||
person = ActionController::AbstractRequest.parse_formatted_request_parameters(StringIO.new(body), 'application/xml', body.size)
|
||||
person = parse_body("<person><name>David</name><avatar type='file' name='me.jpg' content_type='image/jpg'>#{Base64.encode64('ABC')}</avatar></person>")
|
||||
|
||||
assert_equal "image/jpg", person['person']['avatar'].content_type
|
||||
assert_equal "me.jpg", person['person']['avatar'].original_filename
|
||||
|
@ -728,7 +724,7 @@ class XmlParamsParsingTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_multiple_files
|
||||
body = <<-end_body
|
||||
person = parse_body(<<-end_body)
|
||||
<person>
|
||||
<name>David</name>
|
||||
<avatars>
|
||||
|
@ -738,8 +734,6 @@ class XmlParamsParsingTest < Test::Unit::TestCase
|
|||
</person>
|
||||
end_body
|
||||
|
||||
person = ActionController::AbstractRequest.parse_formatted_request_parameters(StringIO.new(body), 'application/xml', body.size)
|
||||
|
||||
assert_equal "image/jpg", person['person']['avatars']['avatar'].first.content_type
|
||||
assert_equal "me.jpg", person['person']['avatars']['avatar'].first.original_filename
|
||||
assert_equal "ABC", person['person']['avatars']['avatar'].first.read
|
||||
|
@ -748,4 +742,12 @@ class XmlParamsParsingTest < Test::Unit::TestCase
|
|||
assert_equal "you.gif", person['person']['avatars']['avatar'].last.original_filename
|
||||
assert_equal "DEF", person['person']['avatars']['avatar'].last.read
|
||||
end
|
||||
|
||||
private
|
||||
def parse_body(body)
|
||||
env = { 'CONTENT_TYPE' => 'application/xml',
|
||||
'CONTENT_LENGTH' => body.size.to_s }
|
||||
cgi = ActionController::Integration::Session::MockCGI.new(env, body)
|
||||
ActionController::CgiRequest.new(cgi).request_parameters
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue