lib/rack/utils.rb in rack-1.0.0 vs lib/rack/utils.rb in rack-1.0.1
- 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
@@ -9,11 +11,11 @@
# Performs URI escaping so that you can construct proper
# query strings faster. Use this rather than the cgi.rb
# version since it's faster. (Stolen from Camping).
def escape(s)
s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/n) {
- '%'+$1.unpack('H2'*$1.size).join('%').upcase
+ '%'+$1.unpack('H2'*bytesize($1)).join('%').upcase
}.tr(' ', '+')
end
module_function :escape
# Unescapes a URI escaped string. (Stolen from Camping).
@@ -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
@@ -302,11 +306,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 = ''
@@ -324,10 +328,10 @@
until head && buf =~ rx
if !head && i = buf.index(EOL+EOL)
head = buf.slice!(0, i+2) # First \r\n
buf.slice!(0, 2) # Second \r\n
- filename = head[/Content-Disposition:.* filename="?([^\";]*)"?/ni, 1]
+ filename = head[/Content-Disposition:.* filename=(?:"((?:\\.|[^\"])*)"|([^;\s]*))/ni, 1]
content_type = head[/Content-Type: (.*)#{EOL}/ni, 1]
name = head[/Content-Disposition:.*\s+name="?([^\";]*)"?/ni, 1] || head[/Content-ID:\s*([^#{EOL}]*)/ni, 1]
if content_type || filename
body = Tempfile.new("RackMultipart")