aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller/cgi_ext
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2004-11-24 01:04:44 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2004-11-24 01:04:44 +0000
commitdb045dbbf60b53dbe013ef25554fd013baf88134 (patch)
tree257830e3c76458c8ff3d1329de83f32b23926028 /actionpack/lib/action_controller/cgi_ext
downloadrails-db045dbbf60b53dbe013ef25554fd013baf88134.tar.gz
rails-db045dbbf60b53dbe013ef25554fd013baf88134.tar.bz2
rails-db045dbbf60b53dbe013ef25554fd013baf88134.zip
Initial
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'actionpack/lib/action_controller/cgi_ext')
-rwxr-xr-xactionpack/lib/action_controller/cgi_ext/cgi_ext.rb43
-rwxr-xr-xactionpack/lib/action_controller/cgi_ext/cgi_methods.rb91
2 files changed, 134 insertions, 0 deletions
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