aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller/cgi_ext/cgi_methods.rb
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2006-06-16 10:07:13 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2006-06-16 10:07:13 +0000
commit36dc94a6a1e742848c5a80975b8bf5d216f54022 (patch)
tree4e22f73746eded676c8109c36683380418b893df /actionpack/lib/action_controller/cgi_ext/cgi_methods.rb
parent7c326a3b54aaeb572a69dabb62fdc453d4814cf3 (diff)
downloadrails-36dc94a6a1e742848c5a80975b8bf5d216f54022.tar.gz
rails-36dc94a6a1e742848c5a80975b8bf5d216f54022.tar.bz2
rails-36dc94a6a1e742848c5a80975b8bf5d216f54022.zip
Added Hash.create_from_xml(string) which will create a hash from a XML string and even typecast if possible [DHH]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4453 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'actionpack/lib/action_controller/cgi_ext/cgi_methods.rb')
-rwxr-xr-xactionpack/lib/action_controller/cgi_ext/cgi_methods.rb208
1 files changed, 74 insertions, 134 deletions
diff --git a/actionpack/lib/action_controller/cgi_ext/cgi_methods.rb b/actionpack/lib/action_controller/cgi_ext/cgi_methods.rb
index be5923e8de..1af837c39a 100755
--- a/actionpack/lib/action_controller/cgi_ext/cgi_methods.rb
+++ b/actionpack/lib/action_controller/cgi_ext/cgi_methods.rb
@@ -1,14 +1,13 @@
require 'cgi'
-require 'action_controller/vendor/xml_simple'
require 'action_controller/vendor/xml_node'
# Static methods for parsing the query and request parameters that can be used in
# a CGI extension class or testing in isolation.
class CGIMethods #:nodoc:
- public
+ class << self
# Returns a hash with the pairs from the query string. The implicit hash construction that is done in
# parse_request_params is not done here.
- def CGIMethods.parse_query_parameters(query_string)
+ def parse_query_parameters(query_string)
parsed_params = {}
query_string.split(/[&;]/).each { |p|
@@ -41,7 +40,7 @@ class CGIMethods #:nodoc:
# Returns the request (POST/GET) parameters in a parsed form where pairs such as "customer[address][street]" /
# "Somewhere cool!" are translated into a full hash hierarchy, like
# { "customer" => { "address" => { "street" => "Somewhere cool!" } } }
- def CGIMethods.parse_request_parameters(params)
+ def parse_request_parameters(params)
parsed_params = {}
for key, value in params
@@ -59,162 +58,103 @@ class CGIMethods #:nodoc:
parsed_params
end
- def self.parse_formatted_request_parameters(mime_type, raw_post_data)
- params = case strategy = ActionController::Base.param_parsers[mime_type]
+ def parse_formatted_request_parameters(mime_type, raw_post_data)
+ case strategy = ActionController::Base.param_parsers[mime_type]
when Proc
strategy.call(raw_post_data)
when :xml_simple
- raw_post_data.blank? ? nil :
- typecast_xml_value(XmlSimple.xml_in(raw_post_data,
- 'forcearray' => false,
- 'forcecontent' => true,
- 'keeproot' => true,
- 'contentkey' => '__content__'))
+ raw_post_data.blank? ? {} : Hash.create_from_xml(raw_post_data)
when :yaml
YAML.load(raw_post_data)
when :xml_node
node = XmlNode.from_xml(raw_post_data)
{ node.node_name => node }
end
-
- dasherize_keys(params || {})
rescue Object => e
{ "exception" => "#{e.message} (#{e.class})", "backtrace" => e.backtrace,
"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"
- params.inject({}) do |h,(k,v)|
- h[k.to_s.tr("-", "_")] = dasherize_keys(v)
- h
- end
- when "Array"
- params.map { |v| dasherize_keys(v) }
- else
- params
- end
- end
-
- # Splits the given key into several pieces. Example keys are 'name', 'person[name]',
- # 'person[name][first]', and 'people[]'. In each instance, an Array instance is returned.
- # 'person[name][first]' produces ['person', 'name', 'first']; 'people[]' produces ['people', '']
- def CGIMethods.split_key(key)
- if /^([^\[]+)((?:\[[^\]]*\])+)$/ =~ key
- keys = [$1]
+ private
+ # Splits the given key into several pieces. Example keys are 'name', 'person[name]',
+ # 'person[name][first]', and 'people[]'. In each instance, an Array instance is returned.
+ # 'person[name][first]' produces ['person', 'name', 'first']; 'people[]' produces ['people', '']
+ def split_key(key)
+ if /^([^\[]+)((?:\[[^\]]*\])+)$/ =~ key
+ keys = [$1]
- keys.concat($2[1..-2].split(']['))
- keys << '' if key[-2..-1] == '[]' # Have to add it since split will drop empty strings
+ keys.concat($2[1..-2].split(']['))
+ keys << '' if key[-2..-1] == '[]' # Have to add it since split will drop empty strings
- keys
- else
- [key]
+ keys
+ else
+ [key]
+ end
end
- end
- def CGIMethods.get_typed_value(value)
- # test most frequent case first
- if value.is_a?(String)
- value
- elsif value.respond_to?(:content_type) && ! value.content_type.blank?
- # Uploaded file
- unless value.respond_to?(:full_original_filename)
- class << value
- alias_method :full_original_filename, :original_filename
-
- # Take the basename of the upload's original filename.
- # This handles the full Windows paths given by Internet Explorer
- # (and perhaps other broken user agents) without affecting
- # those which give the lone filename.
- # The Windows regexp is adapted from Perl's File::Basename.
- def original_filename
- if md = /^(?:.*[:\\\/])?(.*)/m.match(full_original_filename)
- md.captures.first
- else
- File.basename full_original_filename
+ def get_typed_value(value)
+ # test most frequent case first
+ if value.is_a?(String)
+ value
+ elsif value.respond_to?(:content_type) && ! value.content_type.blank?
+ # Uploaded file
+ unless value.respond_to?(:full_original_filename)
+ class << value
+ alias_method :full_original_filename, :original_filename
+
+ # Take the basename of the upload's original filename.
+ # This handles the full Windows paths given by Internet Explorer
+ # (and perhaps other broken user agents) without affecting
+ # those which give the lone filename.
+ # The Windows regexp is adapted from Perl's File::Basename.
+ def original_filename
+ if md = /^(?:.*[:\\\/])?(.*)/m.match(full_original_filename)
+ md.captures.first
+ else
+ File.basename full_original_filename
+ end
end
end
end
- end
- # Return the same value after overriding original_filename.
- value
+ # Return the same value after overriding original_filename.
+ value
- elsif value.respond_to?(:read)
- # Value as part of a multipart request
- result = value.read
- value.rewind
- result
- elsif value.class == Array
- value.collect { |v| CGIMethods.get_typed_value(v) }
- else
- # other value (neither string nor a multipart request)
- value.to_s
+ elsif value.respond_to?(:read)
+ # Value as part of a multipart request
+ result = value.read
+ value.rewind
+ result
+ elsif value.class == Array
+ value.collect { |v| get_typed_value(v) }
+ else
+ # other value (neither string nor a multipart request)
+ value.to_s
+ end
end
- end
- PARAMS_HASH_RE = /^([^\[]+)(\[.*\])?(.)?.*$/
- def CGIMethods.get_levels(key)
- all, main, bracketed, trailing = PARAMS_HASH_RE.match(key).to_a
- if main.nil?
- []
- elsif trailing
- [key]
- elsif bracketed
- [main] + bracketed.slice(1...-1).split('][')
- else
- [main]
+ PARAMS_HASH_RE = /^([^\[]+)(\[.*\])?(.)?.*$/
+ def get_levels(key)
+ all, main, bracketed, trailing = PARAMS_HASH_RE.match(key).to_a
+ if main.nil?
+ []
+ elsif trailing
+ [key]
+ elsif bracketed
+ [main] + bracketed.slice(1...-1).split('][')
+ else
+ [main]
+ end
end
- end
- def CGIMethods.build_deep_hash(value, hash, levels)
- if levels.length == 0
- value
- elsif hash.nil?
- { levels.first => CGIMethods.build_deep_hash(value, nil, levels[1..-1]) }
- else
- hash.update({ levels.first => CGIMethods.build_deep_hash(value, hash[levels.first], levels[1..-1]) })
+ def build_deep_hash(value, hash, levels)
+ if levels.length == 0
+ value
+ elsif hash.nil?
+ { levels.first => build_deep_hash(value, nil, levels[1..-1]) }
+ else
+ hash.update({ levels.first => build_deep_hash(value, hash[levels.first], levels[1..-1]) })
+ end
end
- end
+ end
end