Skip to content

Commit e729949

Browse files
committed
Merge pull request rails#23816 from rails/params_parser_api
Make sure the parameter parsers register API work with overidden mime types.
2 parents 7a36686 + 4f30df4 commit e729949

File tree

5 files changed

+47
-9
lines changed

5 files changed

+47
-9
lines changed

actionpack/lib/action_controller/test_case.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def initialize(env, session)
5252
self.session = session
5353
self.session_options = TestSession::DEFAULT_OPTIONS
5454
@custom_param_parsers = {
55-
Mime[:xml] => lambda { |raw_post| Hash.from_xml(raw_post)['hash'] }
55+
xml: lambda { |raw_post| Hash.from_xml(raw_post)['hash'] }
5656
}
5757
end
5858

@@ -105,7 +105,7 @@ def assign_parameters(routes, controller_path, action, parameters, generated_pat
105105
when :url_encoded_form
106106
data = non_path_parameters.to_query
107107
else
108-
@custom_param_parsers[content_mime_type] = ->(_) { non_path_parameters }
108+
@custom_param_parsers[content_mime_type.symbol] = ->(_) { non_path_parameters }
109109
data = non_path_parameters.to_query
110110
end
111111
end

actionpack/lib/action_dispatch/http/parameters.rb

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,31 @@
11
module ActionDispatch
22
module Http
33
module Parameters
4+
extend ActiveSupport::Concern
5+
46
PARAMETERS_KEY = 'action_dispatch.request.path_parameters'
57

68
DEFAULT_PARSERS = {
7-
Mime[:json] => lambda { |raw_post|
9+
Mime[:json].symbol => -> (raw_post) {
810
data = ActiveSupport::JSON.decode(raw_post)
911
data.is_a?(Hash) ? data : {:_json => data}
1012
}
1113
}
1214

13-
def self.included(klass)
14-
class << klass
15-
attr_accessor :parameter_parsers
15+
included do
16+
class << self
17+
attr_reader :parameter_parsers
1618
end
1719

18-
klass.parameter_parsers = DEFAULT_PARSERS
20+
self.parameter_parsers = DEFAULT_PARSERS
1921
end
22+
23+
module ClassMethods
24+
def parameter_parsers=(parsers) # :nodoc:
25+
@parameter_parsers = parsers.transform_keys { |key| key.respond_to?(:symbol) ? key.symbol : key }
26+
end
27+
end
28+
2029
# Returns both GET and POST \parameters in a single hash.
2130
def parameters
2231
params = get_header("action_dispatch.request.parameters")
@@ -51,7 +60,7 @@ def path_parameters
5160
def parse_formatted_parameters(parsers)
5261
return yield if content_length.zero?
5362

54-
strategy = parsers.fetch(content_mime_type) { return yield }
63+
strategy = parsers.fetch(content_mime_type.symbol) { return yield }
5564

5665
begin
5766
strategy.call(raw_post)

actionpack/lib/action_dispatch/middleware/params_parser.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ def original_exception
3737
# The +parsers+ argument can take Hash of parsers where key is identifying
3838
# content mime type, and value is a lambda that is going to process data.
3939
def self.new(app, parsers = {})
40+
parsers = parsers.transform_keys { |key| key.respond_to?(:symbol) ? key.symbol : key }
4041
ActionDispatch::Request.parameter_parsers = ActionDispatch::Request::DEFAULT_PARSERS.merge(parsers)
4142
app
4243
end

actionpack/test/controller/webservice_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def test_dasherized_keys_as_json
9999
def test_parsing_json_doesnot_rescue_exception
100100
req = Class.new(ActionDispatch::Request) do
101101
def params_parsers
102-
{ Mime[:json] => Proc.new { |data| raise Interrupt } }
102+
{ json: Proc.new { |data| raise Interrupt } }
103103
end
104104

105105
def content_length; get_header('rack.input').length; end

actionpack/test/dispatch/request/json_params_parsing_test.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,34 @@ def teardown
150150
)
151151
end
152152

153+
test "parses json params after custom json mime type registered" do
154+
begin
155+
Mime::Type.unregister :json
156+
Mime::Type.register "application/json", :json, %w(application/vnd.api+json)
157+
assert_parses(
158+
{"user" => {"username" => "meinac"}, "username" => "meinac"},
159+
"{\"username\": \"meinac\"}", { 'CONTENT_TYPE' => 'application/json' }
160+
)
161+
ensure
162+
Mime::Type.unregister :json
163+
Mime::Type.register "application/json", :json, %w( text/x-json application/jsonrequest )
164+
end
165+
end
166+
167+
test "parses json params after custom json mime type registered with synonym" do
168+
begin
169+
Mime::Type.unregister :json
170+
Mime::Type.register "application/json", :json, %w(application/vnd.api+json)
171+
assert_parses(
172+
{"user" => {"username" => "meinac"}, "username" => "meinac"},
173+
"{\"username\": \"meinac\"}", { 'CONTENT_TYPE' => 'application/vnd.api+json' }
174+
)
175+
ensure
176+
Mime::Type.unregister :json
177+
Mime::Type.register "application/json", :json, %w( text/x-json application/jsonrequest )
178+
end
179+
end
180+
153181
private
154182
def assert_parses(expected, actual, headers = {})
155183
with_test_routing(UsersController) do

0 commit comments

Comments
 (0)