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}]"