mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
5603050656
A callable object passed as a constraint for a route may access the request parameters as part of its check. This causes the combined parameters hash to be cached in the environment hash. If the constraint fails then any subsequent access of the request parameters will be against that stale hash. To fix this we delete the cache after every call to `matches?`. This may have a negative performance impact if the contraint wraps a large number of routes as the parameters hash is built by merging GET, POST and path parameters. Fixes #2510.
81 lines
2.4 KiB
Ruby
81 lines
2.4 KiB
Ruby
require 'active_support/core_ext/hash/keys'
|
|
require 'active_support/core_ext/hash/indifferent_access'
|
|
|
|
module ActionDispatch
|
|
module Http
|
|
module Parameters
|
|
# Returns both GET and POST \parameters in a single hash.
|
|
def parameters
|
|
@env["action_dispatch.request.parameters"] ||= begin
|
|
params = request_parameters.merge(query_parameters)
|
|
params.merge!(path_parameters)
|
|
encode_params(params).with_indifferent_access
|
|
end
|
|
end
|
|
alias :params :parameters
|
|
|
|
def path_parameters=(parameters) #:nodoc:
|
|
@symbolized_path_params = nil
|
|
@env.delete("action_dispatch.request.parameters")
|
|
@env["action_dispatch.request.path_parameters"] = parameters
|
|
end
|
|
|
|
# The same as <tt>path_parameters</tt> with explicitly symbolized keys.
|
|
def symbolized_path_parameters
|
|
@symbolized_path_params ||= path_parameters.symbolize_keys
|
|
end
|
|
|
|
# Returns a hash with the \parameters used to form the \path of the request.
|
|
# Returned hash keys are strings:
|
|
#
|
|
# {'action' => 'my_action', 'controller' => 'my_controller'}
|
|
#
|
|
# See <tt>symbolized_path_parameters</tt> for symbolized keys.
|
|
def path_parameters
|
|
@env["action_dispatch.request.path_parameters"] ||= {}
|
|
end
|
|
|
|
def reset_parameters #:nodoc:
|
|
@env.delete("action_dispatch.request.parameters")
|
|
end
|
|
|
|
private
|
|
|
|
# TODO: Validate that the characters are UTF-8. If they aren't,
|
|
# you'll get a weird error down the road, but our form handling
|
|
# should really prevent that from happening
|
|
def encode_params(params)
|
|
if params.is_a?(String)
|
|
return params.force_encoding("UTF-8").encode!
|
|
elsif !params.is_a?(Hash)
|
|
return params
|
|
end
|
|
|
|
params.each do |k, v|
|
|
case v
|
|
when Hash
|
|
encode_params(v)
|
|
when Array
|
|
v.map! {|el| encode_params(el) }
|
|
else
|
|
encode_params(v)
|
|
end
|
|
end
|
|
end
|
|
|
|
# Convert nested Hash to HashWithIndifferentAccess
|
|
def normalize_parameters(value)
|
|
case value
|
|
when Hash
|
|
h = {}
|
|
value.each { |k, v| h[k] = normalize_parameters(v) }
|
|
h.with_indifferent_access
|
|
when Array
|
|
value.map { |e| normalize_parameters(e) }
|
|
else
|
|
value
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|