vendor/rack-1.0.0-git/lib/rack/utils.rb in passenger-2.2.2 vs vendor/rack-1.0.0-git/lib/rack/utils.rb in passenger-2.2.3

- old
+ new

@@ -1,5 +1,7 @@ +# -*- encoding: binary -*- + require 'set' require 'tempfile' module Rack # Rack::Utils contains a grab-bag of useful methods for writing web @@ -22,20 +24,22 @@ [$1.delete('%')].pack('H*') } end module_function :unescape + DEFAULT_SEP = /[&;] */n + # Stolen from Mongrel, with some small modifications: # Parses a query string by breaking it up at the '&' # and ';' characters. You can also use this to parse # cookies by changing the characters used in the second # parameter (which defaults to '&;'). - def parse_query(qs, d = '&;') + def parse_query(qs, d = nil) params = {} - (qs || '').split(/[#{d}] */n).each do |p| - k, v = unescape(p).split('=', 2) + (qs || '').split(d ? /[#{d}] */n : DEFAULT_SEP).each do |p| + k, v = p.split('=', 2).map { |x| unescape(x) } if cur = params[k] if cur.class == Array params[k] << v else @@ -48,24 +52,24 @@ return params end module_function :parse_query - def parse_nested_query(qs, d = '&;') + def parse_nested_query(qs, d = nil) params = {} - (qs || '').split(/[#{d}] */n).each do |p| + (qs || '').split(d ? /[#{d}] */n : DEFAULT_SEP).each do |p| k, v = unescape(p).split('=', 2) normalize_params(params, k, v) end return params end module_function :parse_nested_query def normalize_params(params, name, v = nil) - name =~ %r([\[\]]*([^\[\]]+)\]*) + name =~ %r(\A[\[\]]*([^\[\]]+)\]*) k = $1 || '' after = $' || '' return if k.empty? @@ -97,11 +101,11 @@ def build_query(params) params.map { |k, v| if v.class == Array build_query(v.map { |x| [k, x] }) else - escape(k) + "=" + escape(v) + "#{escape(k)}=#{escape(v)}" end }.join("&") end module_function :build_query @@ -221,25 +225,27 @@ hash end end def [](k) - super @names[k.downcase] + super(@names[k] ||= @names[k.downcase]) end def []=(k, v) delete k - @names[k.downcase] = k + @names[k] = @names[k.downcase] = k super k, v end def delete(k) - super @names.delete(k.downcase) + canonical = k.downcase + super @names.delete(canonical) + @names.delete_if { |name,| name.downcase == canonical } end def include?(k) - @names.has_key? k.downcase + @names.include?(k) || @names.include?(k.downcase) end alias_method :has_key?, :include? alias_method :member?, :include? alias_method :key?, :include? @@ -349,11 +355,11 @@ buf = "" content_length = env['CONTENT_LENGTH'].to_i input = env['rack.input'] input.rewind - boundary_size = boundary.size + EOL.size + boundary_size = Utils.bytesize(boundary) + EOL.size bufsize = 16384 content_length -= boundary_size read_buffer = '' @@ -439,9 +445,29 @@ params end end def self.build_multipart(params, first = true) + if first + unless params.is_a?(Hash) + raise ArgumentError, "value must be a Hash" + end + + multipart = false + query = lambda { |value| + case value + when Array + value.each(&query) + when Hash + value.values.each(&query) + when UploadedFile + multipart = true + end + } + params.values.each(&query) + return nil unless multipart + end + flattened_params = Hash.new params.each do |key, value| k = first ? key.to_s : "[#{key}]"