Merge pull request #23816 from rails/params_parser_api
Make sure the parameter parsers register API work with overidden mime types.
This commit is contained in:
commit
e729949787
@ -52,7 +52,7 @@ def initialize(env, session)
|
||||
self.session = session
|
||||
self.session_options = TestSession::DEFAULT_OPTIONS
|
||||
@custom_param_parsers = {
|
||||
Mime[:xml] => lambda { |raw_post| Hash.from_xml(raw_post)['hash'] }
|
||||
xml: lambda { |raw_post| Hash.from_xml(raw_post)['hash'] }
|
||||
}
|
||||
end
|
||||
|
||||
@ -105,7 +105,7 @@ def assign_parameters(routes, controller_path, action, parameters, generated_pat
|
||||
when :url_encoded_form
|
||||
data = non_path_parameters.to_query
|
||||
else
|
||||
@custom_param_parsers[content_mime_type] = ->(_) { non_path_parameters }
|
||||
@custom_param_parsers[content_mime_type.symbol] = ->(_) { non_path_parameters }
|
||||
data = non_path_parameters.to_query
|
||||
end
|
||||
end
|
||||
|
@ -1,22 +1,31 @@
|
||||
module ActionDispatch
|
||||
module Http
|
||||
module Parameters
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
PARAMETERS_KEY = 'action_dispatch.request.path_parameters'
|
||||
|
||||
DEFAULT_PARSERS = {
|
||||
Mime[:json] => lambda { |raw_post|
|
||||
Mime[:json].symbol => -> (raw_post) {
|
||||
data = ActiveSupport::JSON.decode(raw_post)
|
||||
data.is_a?(Hash) ? data : {:_json => data}
|
||||
}
|
||||
}
|
||||
|
||||
def self.included(klass)
|
||||
class << klass
|
||||
attr_accessor :parameter_parsers
|
||||
included do
|
||||
class << self
|
||||
attr_reader :parameter_parsers
|
||||
end
|
||||
|
||||
klass.parameter_parsers = DEFAULT_PARSERS
|
||||
self.parameter_parsers = DEFAULT_PARSERS
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def parameter_parsers=(parsers) # :nodoc:
|
||||
@parameter_parsers = parsers.transform_keys { |key| key.respond_to?(:symbol) ? key.symbol : key }
|
||||
end
|
||||
end
|
||||
|
||||
# Returns both GET and POST \parameters in a single hash.
|
||||
def parameters
|
||||
params = get_header("action_dispatch.request.parameters")
|
||||
@ -51,7 +60,7 @@ def path_parameters
|
||||
def parse_formatted_parameters(parsers)
|
||||
return yield if content_length.zero?
|
||||
|
||||
strategy = parsers.fetch(content_mime_type) { return yield }
|
||||
strategy = parsers.fetch(content_mime_type.symbol) { return yield }
|
||||
|
||||
begin
|
||||
strategy.call(raw_post)
|
||||
|
@ -37,6 +37,7 @@ def original_exception
|
||||
# The +parsers+ argument can take Hash of parsers where key is identifying
|
||||
# content mime type, and value is a lambda that is going to process data.
|
||||
def self.new(app, parsers = {})
|
||||
parsers = parsers.transform_keys { |key| key.respond_to?(:symbol) ? key.symbol : key }
|
||||
ActionDispatch::Request.parameter_parsers = ActionDispatch::Request::DEFAULT_PARSERS.merge(parsers)
|
||||
app
|
||||
end
|
||||
|
@ -99,7 +99,7 @@ def test_dasherized_keys_as_json
|
||||
def test_parsing_json_doesnot_rescue_exception
|
||||
req = Class.new(ActionDispatch::Request) do
|
||||
def params_parsers
|
||||
{ Mime[:json] => Proc.new { |data| raise Interrupt } }
|
||||
{ json: Proc.new { |data| raise Interrupt } }
|
||||
end
|
||||
|
||||
def content_length; get_header('rack.input').length; end
|
||||
|
@ -150,6 +150,34 @@ def teardown
|
||||
)
|
||||
end
|
||||
|
||||
test "parses json params after custom json mime type registered" do
|
||||
begin
|
||||
Mime::Type.unregister :json
|
||||
Mime::Type.register "application/json", :json, %w(application/vnd.api+json)
|
||||
assert_parses(
|
||||
{"user" => {"username" => "meinac"}, "username" => "meinac"},
|
||||
"{\"username\": \"meinac\"}", { 'CONTENT_TYPE' => 'application/json' }
|
||||
)
|
||||
ensure
|
||||
Mime::Type.unregister :json
|
||||
Mime::Type.register "application/json", :json, %w( text/x-json application/jsonrequest )
|
||||
end
|
||||
end
|
||||
|
||||
test "parses json params after custom json mime type registered with synonym" do
|
||||
begin
|
||||
Mime::Type.unregister :json
|
||||
Mime::Type.register "application/json", :json, %w(application/vnd.api+json)
|
||||
assert_parses(
|
||||
{"user" => {"username" => "meinac"}, "username" => "meinac"},
|
||||
"{\"username\": \"meinac\"}", { 'CONTENT_TYPE' => 'application/vnd.api+json' }
|
||||
)
|
||||
ensure
|
||||
Mime::Type.unregister :json
|
||||
Mime::Type.register "application/json", :json, %w( text/x-json application/jsonrequest )
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def assert_parses(expected, actual, headers = {})
|
||||
with_test_routing(UsersController) do
|
||||
|
Loading…
Reference in New Issue
Block a user