lib/rack/request.rb in rack-1.4.7 vs lib/rack/request.rb in rack-1.5.0.beta.1
- old
+ new
@@ -96,14 +96,12 @@
def port
if port = host_with_port.split(/:/)[1]
port.to_i
elsif port = @env['HTTP_X_FORWARDED_PORT']
port.to_i
- elsif ssl?
- 443
elsif @env.has_key?("HTTP_X_FORWARDED_HOST")
- 80
+ DEFAULT_PORTS[scheme]
else
@env["SERVER_PORT"].to_i
end
end
@@ -116,29 +114,29 @@
def path_info=(s); @env["PATH_INFO"] = s.to_s end
# Checks the HTTP request method (or verb) to see if it was of type DELETE
def delete?; request_method == "DELETE" end
-
+
# Checks the HTTP request method (or verb) to see if it was of type GET
def get?; request_method == "GET" end
-
+
# Checks the HTTP request method (or verb) to see if it was of type HEAD
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 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
-
+
# Checks the HTTP request method (or verb) to see if it was of type PUT
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
# The set of form-data media-types. Requests that do not indicate
@@ -155,10 +153,14 @@
PARSEABLE_DATA_MEDIA_TYPES = [
'multipart/related',
'multipart/mixed'
]
+ # Default ports depending on scheme. Used to decide whether or not
+ # to include the port in a generated URI.
+ DEFAULT_PORTS = { 'http' => 80, 'https' => 443, 'coffee' => 80 }
+
# Determine whether the request body contains form-data by checking
# the request Content-Type for one of the media-types:
# "application/x-www-form-urlencoded" or "multipart/form-data". The
# list of form-data media types can be modified through the
# +FORM_DATA_MEDIA_TYPES+ array.
@@ -215,22 +217,59 @@
{}
end
end
# The union of GET and POST data.
+ #
+ # Note that modifications will not be persisted in the env. Use update_param or delete_param if you want to destructively modify params.
def params
@params ||= self.GET.merge(self.POST)
rescue EOFError
- self.GET
+ self.GET.dup
end
+ # Destructively update a parameter, whether it's in GET and/or POST. Returns nil.
+ #
+ # The parameter is updated wherever it was previous defined, so GET, POST, or both. If it wasn't previously defined, it's inserted into GET.
+ #
+ # env['rack.input'] is not touched.
+ def update_param(k, v)
+ found = false
+ if self.GET.has_key?(k)
+ found = true
+ self.GET[k] = v
+ end
+ if self.POST.has_key?(k)
+ found = true
+ self.POST[k] = v
+ end
+ unless found
+ self.GET[k] = v
+ end
+ @params = nil
+ nil
+ end
+
+ # Destructively delete a parameter, whether it's in GET or POST. Returns the value of the deleted parameter.
+ #
+ # If the parameter is in both GET and POST, the POST value takes precedence since that's how #params works.
+ #
+ # env['rack.input'] is not touched.
+ def delete_param(k)
+ v = [ self.POST.delete(k), self.GET.delete(k) ].compact.first
+ @params = nil
+ v
+ end
+
# shortcut for request.params[key]
def [](key)
params[key.to_s]
end
# shortcut for request.params[key] = value
+ #
+ # Note that modifications will not be persisted in the env. Use update_param or delete_param if you want to destructively modify params.
def []=(key, value)
params[key.to_s] = value
end
# like Hash#values_at
@@ -269,18 +308,12 @@
def xhr?
@env["HTTP_X_REQUESTED_WITH"] == "XMLHttpRequest"
end
def base_url
- url = scheme + "://"
- url << host
-
- if scheme == "https" && port != 443 ||
- scheme == "http" && port != 80
- url << ":#{port}"
- end
-
+ url = "#{scheme}://#{host}"
+ url << ":#{port}" if port != DEFAULT_PORTS[scheme]
url
end
# Tries to return a remake of the original request URL as a string.
def url
@@ -305,30 +338,38 @@
[encoding, quality]
end
end
def trusted_proxy?(ip)
- ip =~ /^127\.0\.0\.1$|^(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\.|^::1$|^fd[0-9a-f]{2}:.+|^localhost$/i
+ ip =~ /^127\.0\.0\.1$|^(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\.|^::1$|^fd[0-9a-f]{2}:.+|^localhost$|^unix$|^unix:/i
end
def ip
- remote_addrs = @env['REMOTE_ADDR'] ? @env['REMOTE_ADDR'].split(/[,\s]+/) : []
- remote_addrs.reject! { |addr| trusted_proxy?(addr) }
-
+ remote_addrs = split_ip_addresses(@env['REMOTE_ADDR'])
+ remote_addrs = reject_trusted_ip_addresses(remote_addrs)
+
return remote_addrs.first if remote_addrs.any?
- forwarded_ips = @env['HTTP_X_FORWARDED_FOR'] ? @env['HTTP_X_FORWARDED_FOR'].strip.split(/[,\s]+/) : []
+ 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 forwarded_ips.reject { |ip| trusted_proxy?(ip) }.last || @env["REMOTE_ADDR"]
+ return reject_trusted_ip_addresses(forwarded_ips).last || @env["REMOTE_ADDR"]
end
protected
+ def split_ip_addresses(ip_addresses)
+ ip_addresses ? ip_addresses.strip.split(/[,\s]+/) : []
+ end
+
+ def reject_trusted_ip_addresses(ip_addresses)
+ ip_addresses.reject { |ip| trusted_proxy?(ip) }
+ end
+
def parse_query(qs)
Utils.parse_nested_query(qs)
end
def parse_multipart(env)