lib/rack/request.rb in rack-1.5.5 vs lib/rack/request.rb in rack-1.6.0.beta
- old
+ new
@@ -6,14 +6,10 @@
# constructor will be directly modified.
#
# req = Rack::Request.new(env)
# req.post?
# req.params["data"]
- #
- # The environment hash passed will store a reference to the Request object
- # instantiated so that it will only instantiate if an instance of the Request
- # object doesn't already exist.
class Request
# The environment of the request.
attr_reader :env
@@ -54,11 +50,11 @@
# { 'charset' => 'utf-8' }
def media_type_params
return {} if content_type.nil?
Hash[*content_type.split(/\s*[;,]\s*/)[1..-1].
collect { |s| s.split('=', 2) }.
- map { |k,v| [k.downcase, v] }.flatten]
+ map { |k,v| [k.downcase, strip_doublequotes(v)] }.flatten]
end
# The character set of the request body if a "charset" media type
# parameter was given, or nil if no "charset" was specified. Note
# that, per RFC2616, text/* media types that specify no explicit
@@ -99,19 +95,19 @@
elsif port = @env['HTTP_X_FORWARDED_PORT']
port.to_i
elsif @env.has_key?("HTTP_X_FORWARDED_HOST")
DEFAULT_PORTS[scheme]
elsif @env.has_key?("HTTP_X_FORWARDED_PROTO")
- DEFAULT_PORTS[@env['HTTP_X_FORWARDED_PROTO']]
+ DEFAULT_PORTS[@env['HTTP_X_FORWARDED_PROTO'].split(',')[0]]
else
@env["SERVER_PORT"].to_i
end
end
def host
# Remove port number.
- host_with_port.to_s.gsub(/:\d+\z/, '')
+ host_with_port.to_s.sub(/:\d+\z/, '')
end
def script_name=(s); @env["SCRIPT_NAME"] = s.to_s end
def path_info=(s); @env["PATH_INFO"] = s.to_s end
@@ -126,10 +122,13 @@
def head?; request_method == "HEAD" end
# Checks the HTTP request method (or verb) to see if it was of type OPTIONS
def options?; request_method == "OPTIONS" end
+ # Checks the HTTP request method (or verb) to see if it was of type LINK
+ def link?; request_method == "LINK" end
+
# Checks the HTTP request method (or verb) to see if it was of type PATCH
def patch?; request_method == "PATCH" end
# Checks the HTTP request method (or verb) to see if it was of type POST
def post?; request_method == "POST" end
@@ -138,11 +137,14 @@
def put?; request_method == "PUT" end
# Checks the HTTP request method (or verb) to see if it was of type TRACE
def trace?; request_method == "TRACE" end
+ # Checks the HTTP request method (or verb) to see if it was of type UNLINK
+ def unlink?; request_method == "UNLINK" end
+
# The set of form-data media-types. Requests that do not indicate
# one of the media types presents in this list will not be eligible
# for form-data / param parsing.
FORM_DATA_MEDIA_TYPES = [
'application/x-www-form-urlencoded',
@@ -184,12 +186,13 @@
# Returns the data received in the query string.
def GET
if @env["rack.request.query_string"] == query_string
@env["rack.request.query_hash"]
else
+ p = parse_query(query_string)
@env["rack.request.query_string"] = query_string
- @env["rack.request.query_hash"] = parse_query(query_string)
+ @env["rack.request.query_hash"] = p
end
end
# Returns the data received in the request body.
#
@@ -199,11 +202,10 @@
if @env["rack.input"].nil?
raise "Missing rack.input"
elsif @env["rack.request.form_input"].equal? @env["rack.input"]
@env["rack.request.form_hash"]
elsif form_data? || parseable_data?
- @env["rack.request.form_input"] = @env["rack.input"]
unless @env["rack.request.form_hash"] = parse_multipart(env)
form_vars = @env["rack.input"].read
# Fix for Safari Ajax postings that always append \0
# form_vars.sub!(/\0\z/, '') # performance replacement:
@@ -212,10 +214,11 @@
@env["rack.request.form_vars"] = form_vars
@env["rack.request.form_hash"] = parse_query(form_vars)
@env["rack.input"].rewind
end
+ @env["rack.request.form_input"] = @env["rack.input"]
@env["rack.request.form_hash"]
else
{}
end
end
@@ -329,20 +332,17 @@
def fullpath
query_string.empty? ? path : "#{path}?#{query_string}"
end
def accept_encoding
- @env["HTTP_ACCEPT_ENCODING"].to_s.split(/\s*,\s*/).map do |part|
- encoding, parameters = part.split(/\s*;\s*/, 2)
- quality = 1.0
- if parameters and /\Aq=([\d.]+)/ =~ parameters
- quality = $1.to_f
- end
- [encoding, quality]
- end
+ parse_http_accept_header(@env["HTTP_ACCEPT_ENCODING"])
end
+ def accept_language
+ parse_http_accept_header(@env["HTTP_ACCEPT_LANGUAGE"])
+ end
+
def trusted_proxy?(ip)
ip =~ /\A127\.0\.0\.1\Z|\A(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\.|\A::1\Z|\Afd[0-9a-f]{2}:.+|\Alocalhost\Z|\Aunix\Z|\Aunix:/i
end
def ip
@@ -351,16 +351,10 @@
return remote_addrs.first if remote_addrs.any?
forwarded_ips = split_ip_addresses(@env['HTTP_X_FORWARDED_FOR'])
- if client_ip = @env['HTTP_CLIENT_IP']
- # If forwarded_ips doesn't include the client_ip, it might be an
- # ip spoofing attempt, so we ignore HTTP_CLIENT_IP
- return client_ip if forwarded_ips.include?(client_ip)
- end
-
return reject_trusted_ip_addresses(forwarded_ips).last || @env["REMOTE_ADDR"]
end
protected
def split_ip_addresses(ip_addresses)
@@ -370,13 +364,33 @@
def reject_trusted_ip_addresses(ip_addresses)
ip_addresses.reject { |ip| trusted_proxy?(ip) }
end
def parse_query(qs)
- Utils.parse_nested_query(qs)
+ Utils.parse_nested_query(qs, '&')
end
def parse_multipart(env)
Rack::Multipart.parse_multipart(env)
end
+
+ def parse_http_accept_header(header)
+ header.to_s.split(/\s*,\s*/).map do |part|
+ attribute, parameters = part.split(/\s*;\s*/, 2)
+ quality = 1.0
+ if parameters and /\Aq=([\d.]+)/ =~ parameters
+ quality = $1.to_f
+ end
+ [attribute, quality]
+ end
+ end
+
+ private
+ def strip_doublequotes(s)
+ if s[0] == ?" && s[-1] == ?"
+ s[1..-2]
+ else
+ s
+ end
+ end
end
end