Class: CGIMethods

Inherits:
Object
  • Object
show all
Defined in:
lib/action_controller/cgi_ext/cgi_methods.rb

Overview

Static methods for parsing the query and request parameters that can be used in a CGI extension class or testing in isolation.

Class Method Summary collapse

Class Method Details

.parse_formatted_request_parameters(mime_type, raw_post_data) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/action_controller/cgi_ext/cgi_methods.rb', line 61

def self.parse_formatted_request_parameters(mime_type, raw_post_data)
  params = 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__'))
    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

.parse_query_parameters(query_string) ⇒ Object

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.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/action_controller/cgi_ext/cgi_methods.rb', line 11

def CGIMethods.parse_query_parameters(query_string)
  parsed_params = {}
  
  query_string.split(/[&;]/).each { |p| 
    # Ignore repeated delimiters.
    next if p.empty?

    k, v = p.split('=',2)
    v = nil if (v && v.empty?)

    k = CGI.unescape(k) if k
    v = CGI.unescape(v) if v

    unless k.include?(?[)
      parsed_params[k] = v
    else
      keys = split_key(k)
      last_key = keys.pop
      last_key = keys.pop if (use_array = last_key.empty?)
      parent = keys.inject(parsed_params) {|h, k| h[k] ||= {}}
      
      if use_array then (parent[last_key] ||= []) << v
      else parent[last_key] = v
      end
    end
  }
  
  parsed_params
end

.parse_request_parameters(params) ⇒ Object

Returns the request (POST/GET) parameters in a parsed form where pairs such as “customer[street]” / “Somewhere cool!” are translated into a full hash hierarchy, like { “customer” => { “address” => { “street” => “Somewhere cool!” } } }



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/action_controller/cgi_ext/cgi_methods.rb', line 44

def CGIMethods.parse_request_parameters(params)
  parsed_params = {}

  for key, value in params
    value = [value] if key =~ /.*\[\]$/
    unless key.include?('[')
      # much faster to test for the most common case first (GET)
      # and avoid the call to build_deep_hash
      parsed_params[key] = get_typed_value(value[0])
    else
      build_deep_hash(get_typed_value(value[0]), parsed_params, get_levels(key))
    end
  end

  parsed_params
end

.typecast_xml_value(value) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/action_controller/cgi_ext/cgi_methods.rb', line 85

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