From db045dbbf60b53dbe013ef25554fd013baf88134 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Wed, 24 Nov 2004 01:04:44 +0000 Subject: Initial git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- .../lib/action_controller/cgi_ext/cgi_ext.rb | 43 ++++++++++ .../lib/action_controller/cgi_ext/cgi_methods.rb | 91 ++++++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100755 actionpack/lib/action_controller/cgi_ext/cgi_ext.rb create mode 100755 actionpack/lib/action_controller/cgi_ext/cgi_methods.rb (limited to 'actionpack/lib/action_controller/cgi_ext') diff --git a/actionpack/lib/action_controller/cgi_ext/cgi_ext.rb b/actionpack/lib/action_controller/cgi_ext/cgi_ext.rb new file mode 100755 index 0000000000..371ead695b --- /dev/null +++ b/actionpack/lib/action_controller/cgi_ext/cgi_ext.rb @@ -0,0 +1,43 @@ +require 'cgi' +require 'cgi/session' +require 'cgi/session/pstore' +require 'action_controller/cgi_ext/cgi_methods' + +# Wrapper around the CGIMethods that have been secluded to allow testing without +# an instatiated CGI object +class CGI #:nodoc: + class << self + alias :escapeHTML_fail_on_nil :escapeHTML + + def escapeHTML(string) + escapeHTML_fail_on_nil(string) unless string.nil? + end + end + + # Returns a parameter hash including values from both the request (POST/GET) + # and the query string with the latter taking precedence. + def parameters + request_parameters.update(query_parameters) + end + + def query_parameters + CGIMethods.parse_query_parameters(query_string) + end + + def request_parameters + CGIMethods.parse_request_parameters(params) + end + + def redirect(where) + header({ + "Status" => "302 Moved", + "location" => "#{where}" + }) + end + + def session(parameters = nil) + parameters = {} if parameters.nil? + parameters['database_manager'] = CGI::Session::PStore + CGI::Session.new(self, parameters) + end +end \ No newline at end of file diff --git a/actionpack/lib/action_controller/cgi_ext/cgi_methods.rb b/actionpack/lib/action_controller/cgi_ext/cgi_methods.rb new file mode 100755 index 0000000000..261490580c --- /dev/null +++ b/actionpack/lib/action_controller/cgi_ext/cgi_methods.rb @@ -0,0 +1,91 @@ +require 'cgi' + +# 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 + # 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) + parsed_params = {} + + query_string.split(/[&;]/).each { |p| + k, v = p.split('=') + + k = CGI.unescape(k) unless k.nil? + v = CGI.unescape(v) unless v.nil? + + if k =~ /(.*)\[\]$/ + if parsed_params.has_key? $1 + parsed_params[$1] << v + else + parsed_params[$1] = [v] + end + else + parsed_params[k] = v.nil? ? nil : v + end + } + + return parsed_params + end + + # 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) + parsed_params = {} + + for key, value in params + value = [value] if key =~ /.*\[\]$/ + CGIMethods.build_deep_hash( + CGIMethods.get_typed_value(value[0]), + parsed_params, + CGIMethods.get_levels(key) + ) + end + + return parsed_params + end + + private + def CGIMethods.get_typed_value(value) + if value.respond_to?(:content_type) && !value.content_type.empty? + # Uploaded file + value + elsif value.respond_to?(:read) + # Value as part of a multipart request + value.read + elsif value.class == Array + value + else + # Standard value (not a multipart request) + value.to_s + end + end + + def CGIMethods.get_levels(key_string) + return [] if key_string.nil? or key_string.empty? + + levels = [] + main, existance = /(\w+)(\[)?.?/.match(key_string).captures + levels << main + + unless existance.nil? + hash_part = key_string.sub(/\w+\[/, "") + hash_part.slice!(-1, 1) + levels += hash_part.split(/\]\[/) + end + + levels + 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]) }) + end + end +end \ No newline at end of file -- cgit v1.2.3