From 5d0f633239e4f099755c36079d88d082dfdde543 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Wed, 29 Dec 2004 21:07:50 +0000 Subject: Moved the cookies fix to cgi_ext git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@274 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- .../cgi_ext/cookie_performance_fix.rb | 121 +++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 actionpack/lib/action_controller/cgi_ext/cookie_performance_fix.rb (limited to 'actionpack/lib/action_controller/cgi_ext') diff --git a/actionpack/lib/action_controller/cgi_ext/cookie_performance_fix.rb b/actionpack/lib/action_controller/cgi_ext/cookie_performance_fix.rb new file mode 100644 index 0000000000..225cea1905 --- /dev/null +++ b/actionpack/lib/action_controller/cgi_ext/cookie_performance_fix.rb @@ -0,0 +1,121 @@ +CGI.module_eval { remove_const "Cookie" } + +class CGI #:nodoc: + # This is a cookie class that fixes the performance problems with the default one that ships with 1.8.1 and below. + # It replaces the inheritance on SimpleDelegator with DelegateClass(Array) following the suggestion from Matz on + # http://groups.google.com/groups?th=e3a4e68ba042f842&seekm=c3sioe%241qvm%241%40news.cybercity.dk#link14 + class Cookie < DelegateClass(Array) + # Create a new CGI::Cookie object. + # + # The contents of the cookie can be specified as a +name+ and one + # or more +value+ arguments. Alternatively, the contents can + # be specified as a single hash argument. The possible keywords of + # this hash are as follows: + # + # name:: the name of the cookie. Required. + # value:: the cookie's value or list of values. + # path:: the path for which this cookie applies. Defaults to the + # base directory of the CGI script. + # domain:: the domain for which this cookie applies. + # expires:: the time at which this cookie expires, as a +Time+ object. + # secure:: whether this cookie is a secure cookie or not (default to + # false). Secure cookies are only transmitted to HTTPS + # servers. + # + # These keywords correspond to attributes of the cookie object. + def initialize(name = "", *value) + options = if name.kind_of?(String) + { "name" => name, "value" => value } + else + name + end + unless options.has_key?("name") + raise ArgumentError, "`name' required" + end + + @name = options["name"] + @value = Array(options["value"]) + # simple support for IE + if options["path"] + @path = options["path"] + else + %r|^(.*/)|.match(ENV["SCRIPT_NAME"]) + @path = ($1 or "") + end + @domain = options["domain"] + @expires = options["expires"] + @secure = options["secure"] == true ? true : false + + super(@value) + end + + def __setobj__(obj) + @_dc_obj = obj + end + + attr_accessor("name", "value", "path", "domain", "expires") + attr_reader("secure") + + # Set whether the Cookie is a secure cookie or not. + # + # +val+ must be a boolean. + def secure=(val) + @secure = val if val == true or val == false + @secure + end + + # Convert the Cookie to its string representation. + def to_s + buf = "" + buf += @name + '=' + + if @value.kind_of?(String) + buf += CGI::escape(@value) + else + buf += @value.collect{|v| CGI::escape(v) }.join("&") + end + + if @domain + buf += '; domain=' + @domain + end + + if @path + buf += '; path=' + @path + end + + if @expires + buf += '; expires=' + CGI::rfc1123_date(@expires) + end + + if @secure == true + buf += '; secure' + end + + buf + end + + # Parse a raw cookie string into a hash of cookie-name=>Cookie + # pairs. + # + # cookies = CGI::Cookie::parse("raw_cookie_string") + # # { "name1" => cookie1, "name2" => cookie2, ... } + # + def self.parse(raw_cookie) + cookies = Hash.new([]) + return cookies unless raw_cookie + + raw_cookie.split(/; /).each do |pairs| + name, values = pairs.split('=',2) + next unless name and values + name = CGI::unescape(name) + values ||= "" + values = values.split('&').collect{|v| CGI::unescape(v) } + unless cookies.has_key?(name) + cookies[name] = new({ "name" => name, "value" => values }) + end + end + + cookies + end + end # class Cookie +end \ No newline at end of file -- cgit v1.2.3