aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
authorJamis Buck <jamis@37signals.com>2006-03-18 05:07:27 +0000
committerJamis Buck <jamis@37signals.com>2006-03-18 05:07:27 +0000
commit459559a8bced28f25888802e40c7182392ea94cc (patch)
tree729a49dc50c7461a31368a164eabd5bff0a77dd2 /actionpack
parent93f8bd15a11d5292885d585669a61a7364d1a1b0 (diff)
downloadrails-459559a8bced28f25888802e40c7182392ea94cc.tar.gz
rails-459559a8bced28f25888802e40c7182392ea94cc.tar.bz2
rails-459559a8bced28f25888802e40c7182392ea94cc.zip
XML-formatted requests are typecast according to "type" attributes for :xml_simple
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3915 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/CHANGELOG2
-rwxr-xr-xactionpack/lib/action_controller/cgi_ext/cgi_methods.rb44
-rw-r--r--actionpack/test/controller/webservice_test.rb54
3 files changed, 98 insertions, 2 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index 609cdf0bd5..014287b924 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* XML-formatted requests are typecast according to "type" attributes for :xml_simple [Jamis Buck]
+
* Added protection against proxy setups treating requests as local even when they're not #3898 [stephen_purcell@yahoo.com]
* Added TestRequest#raw_post that simulate raw_post from CgiRequest #3042 [francois.beausoleil@gmail.com]
diff --git a/actionpack/lib/action_controller/cgi_ext/cgi_methods.rb b/actionpack/lib/action_controller/cgi_ext/cgi_methods.rb
index 776f74a100..f19e70839d 100755
--- a/actionpack/lib/action_controller/cgi_ext/cgi_methods.rb
+++ b/actionpack/lib/action_controller/cgi_ext/cgi_methods.rb
@@ -63,7 +63,11 @@ class CGIMethods #:nodoc:
when Proc
strategy.call(raw_post_data)
when :xml_simple
- XmlSimple.xml_in(raw_post_data, 'ForceArray' => false, 'keeproot' => true)
+ typecast_xml_value(XmlSimple.xml_in(raw_post_data,
+ 'forcearray' => false,
+ 'forcecontent' => true,
+ 'keeproot' => true,
+ 'contentkey' => '__content__'))
when :yaml
YAML.load(raw_post_data)
when :xml_node
@@ -77,8 +81,46 @@ class CGIMethods #:nodoc:
"raw_post_data" => raw_post_data, "format" => mime_type }
end
+ def self.typecast_xml_value(value)
+ case value
+ when Hash
+ if value.has_key?("__content__")
+ content = translate_xml_entities(value["__content__"])
+ case value["type"]
+ when "integer" then content.to_i
+ when "boolean" then content == "true"
+ when "datetime" then Time.parse(content)
+ when "date" then Date.parse(content)
+ else content
+ end
+ else
+ value.empty? ? nil : value.inject({}) do |h,(k,v)|
+ h[k] = typecast_xml_value(v)
+ h
+ end
+ end
+ when Array
+ value.map! { |i| typecast_xml_value(i) }
+ case value.length
+ when 0 then nil
+ when 1 then value.first
+ else value
+ end
+ else
+ raise "can't typecast #{value.inspect}"
+ end
+ end
+
private
+ def self.translate_xml_entities(value)
+ value.gsub(/&lt;/, "<").
+ gsub(/&gt;/, ">").
+ gsub(/&quot;/, '"').
+ gsub(/&apos;/, "'").
+ gsub(/&amp;/, "&")
+ end
+
def self.dasherize_keys(params)
case params.class.to_s
when "Hash"
diff --git a/actionpack/test/controller/webservice_test.rb b/actionpack/test/controller/webservice_test.rb
index 90691e9e9c..d49f6e7941 100644
--- a/actionpack/test/controller/webservice_test.rb
+++ b/actionpack/test/controller/webservice_test.rb
@@ -106,14 +106,66 @@ class WebServiceTest < Test::Unit::TestCase
ActionController::Base.param_parsers[Mime::XML] = :xml_simple
process('POST', 'application/xml', "<first-key>\n<sub-key>...</sub-key>\n</first-key>", true)
assert_equal 'action, controller, first_key(sub_key), full', @controller.response.body
+ assert_equal "...", @controller.params[:first_key][:sub_key]
+ end
+
+ def test_typecast_as_xml
+ ActionController::Base.param_parsers[Mime::XML] = :xml_simple
+ process('POST', 'application/xml', <<-XML)
+ <data>
+ <a type="integer">15</a>
+ <b type="boolean">false</b>
+ <c type="boolean">true</c>
+ <d type="date">2005-03-17</d>
+ <e type="datetime">2005-03-17T21:41:07Z</e>
+ <f>unparsed</f>
+ <g type="integer">1</g>
+ <g>hello</g>
+ <g type="date">1974-07-25</g>
+ </data>
+ XML
+ params = @controller.params
+ assert_equal 15, params[:data][:a]
+ assert_equal false, params[:data][:b]
+ assert_equal true, params[:data][:c]
+ assert_equal Date.new(2005,3,17), params[:data][:d]
+ assert_equal Time.utc(2005,3,17,21,41,7), params[:data][:e]
+ assert_equal "unparsed", params[:data][:f]
+ assert_equal [1, "hello", Date.new(1974,7,25)], params[:data][:g]
end
def test_dasherized_keys_as_yaml
ActionController::Base.param_parsers[Mime::YAML] = :yaml
process('POST', 'application/x-yaml', "---\nfirst-key:\n sub-key: ...\n", true)
assert_equal 'action, controller, first_key(sub_key), full', @controller.response.body
+ assert_equal "...", @controller.params[:first_key][:sub_key]
+ end
+
+ def test_typecast_as_yaml
+ ActionController::Base.param_parsers[Mime::YAML] = :yaml
+ process('POST', 'application/x-yaml', <<-YAML)
+ ---
+ data:
+ a: 15
+ b: false
+ c: true
+ d: 2005-03-17
+ e: 2005-03-17T21:41:07Z
+ f: unparsed
+ g:
+ - 1
+ - hello
+ - 1974-07-25
+ YAML
+ params = @controller.params
+ assert_equal 15, params[:data][:a]
+ assert_equal false, params[:data][:b]
+ assert_equal true, params[:data][:c]
+ assert_equal Date.new(2005,3,17), params[:data][:d]
+ assert_equal Time.utc(2005,3,17,21,41,7), params[:data][:e]
+ assert_equal "unparsed", params[:data][:f]
+ assert_equal [1, "hello", Date.new(1974,7,25)], params[:data][:g]
end
-
private