1
0
Fork 0
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:
Jeremy Kemper 2007-05-23 19:09:37 +00:00
parent 7b99b40352
commit 4bd3e3aa1b
3 changed files with 44 additions and 45 deletions

View file

@ -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

View file

@ -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)

View file

@ -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