From 3efb0bcdafc524cbbb002455b9bbc1233e43a868 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 18 Sep 2015 11:19:04 -0700 Subject: move parameter parsing to the request object All parameter parsing should be on the request object because the request object is the object that we ask for parameters. --- actionpack/lib/action_dispatch/http/request.rb | 35 +++++++++++++++++++++- .../action_dispatch/middleware/params_parser.rb | 24 ++------------- 2 files changed, 37 insertions(+), 22 deletions(-) (limited to 'actionpack/lib') diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index b2566c4820..68a8ca707a 100644 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -348,13 +348,29 @@ module ActionDispatch # Override Rack's POST method to support indifferent access def POST fetch_header("action_dispatch.request.request_parameters") do - self.request_parameters = Request::Utils.normalize_encode_params(super || {}) + default = ->() { + Request::Utils.normalize_encode_params(super || {}) + } + pr = parse_formatted_parameters(self, params_parsers, default) do |params| + params + end + self.request_parameters = pr end rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e raise ActionController::BadRequest.new(:request, e) end alias :request_parameters :POST + def params_parsers + fetch_header "action_dispatch.request.params_parsers" do + {} + end + end + + def params_parsers= hash + set_header "action_dispatch.request.params_parsers", hash + end + # Returns the authorization header regardless of whether it was specified directly or through one of the # proxy alternatives. def authorization @@ -383,5 +399,22 @@ module ActionDispatch HTTP_METHOD_LOOKUP[name] || raise(ActionController::UnknownHttpMethod, "#{name}, accepted HTTP methods are #{HTTP_METHODS[0...-1].join(', ')}, and #{HTTP_METHODS[-1]}") name end + + def parse_formatted_parameters(request, parsers, default = ->() { nil }) + return default.call if request.content_length.zero? + + strategy = parsers.fetch(request.content_mime_type) { return default.call } + + yield strategy.call(request.raw_post) + + rescue Rack::QueryParser::InvalidParameterError + raise + rescue => e # JSON or Ruby code block errors + my_logger = logger || ActiveSupport::Logger.new($stderr) + my_logger.debug "Error occurred while parsing request parameters.\nContents:\n\n#{request.raw_post}" + request.request_parameters = {} + + raise ParamsParser::ParseError.new(e.message, e) + end end end diff --git a/actionpack/lib/action_dispatch/middleware/params_parser.rb b/actionpack/lib/action_dispatch/middleware/params_parser.rb index 9cde9c9b98..a658a414a5 100644 --- a/actionpack/lib/action_dispatch/middleware/params_parser.rb +++ b/actionpack/lib/action_dispatch/middleware/params_parser.rb @@ -37,29 +37,11 @@ module ActionDispatch def call(env) request = Request.new(env) - parse_formatted_parameters(request, @parsers) do |params| - request.request_parameters = params - end + request.params_parsers = @parsers + + request.request_parameters @app.call(env) end - - private - def parse_formatted_parameters(request, parsers) - return if request.content_length.zero? - - strategy = parsers.fetch(request.content_mime_type) { return nil } - - yield strategy.call(request.raw_post) - - rescue => e # JSON or Ruby code block errors - logger(request).debug "Error occurred while parsing request parameters.\nContents:\n\n#{request.raw_post}" - - raise ParseError.new(e.message, e) - end - - def logger(request) - request.logger || ActiveSupport::Logger.new($stderr) - end end end -- cgit v1.2.3