diff options
Diffstat (limited to 'actionpack/lib/action_dispatch/http')
6 files changed, 37 insertions, 26 deletions
diff --git a/actionpack/lib/action_dispatch/http/filter_parameters.rb b/actionpack/lib/action_dispatch/http/filter_parameters.rb index e5874a39f6..e584b84d92 100644 --- a/actionpack/lib/action_dispatch/http/filter_parameters.rb +++ b/actionpack/lib/action_dispatch/http/filter_parameters.rb @@ -51,28 +51,28 @@ module ActionDispatch @filtered_path ||= query_string.empty? ? path : "#{path}?#{filtered_query_string}" end - protected + private - def parameter_filter + def parameter_filter # :doc: parameter_filter_for fetch_header("action_dispatch.parameter_filter") { return NULL_PARAM_FILTER } end - def env_filter + def env_filter # :doc: user_key = fetch_header("action_dispatch.parameter_filter") { return NULL_ENV_FILTER } parameter_filter_for(Array(user_key) + ENV_MATCH) end - def parameter_filter_for(filters) + def parameter_filter_for(filters) # :doc: ParameterFilter.new(filters) end KV_RE = "[^&;=]+" PAIR_RE = %r{(#{KV_RE})=(#{KV_RE})} - def filtered_query_string + def filtered_query_string # :doc: query_string.gsub(PAIR_RE) do |_| parameter_filter.filter([[$1, $2]]).first.join("=") end diff --git a/actionpack/lib/action_dispatch/http/mime_negotiation.rb b/actionpack/lib/action_dispatch/http/mime_negotiation.rb index e5f20003a3..c4fe3a5c09 100644 --- a/actionpack/lib/action_dispatch/http/mime_negotiation.rb +++ b/actionpack/lib/action_dispatch/http/mime_negotiation.rb @@ -150,20 +150,20 @@ module ActionDispatch order.include?(Mime::ALL) ? format : nil end - protected + private BROWSER_LIKE_ACCEPTS = /,\s*\*\/\*|\*\/\*\s*,/ - def valid_accept_header + def valid_accept_header # :doc: (xhr? && (accept.present? || content_mime_type)) || (accept.present? && accept !~ BROWSER_LIKE_ACCEPTS) end - def use_accept_header + def use_accept_header # :doc: !self.class.ignore_accept_header end - def format_from_path_extension + def format_from_path_extension # :doc: path = get_header("action_dispatch.original_path") || get_header("PATH_INFO") if match = path && path.match(/\.(\w+)\z/) Mime[match.captures.first] diff --git a/actionpack/lib/action_dispatch/http/mime_type.rb b/actionpack/lib/action_dispatch/http/mime_type.rb index 58eb8d0baf..1583a8f87f 100644 --- a/actionpack/lib/action_dispatch/http/mime_type.rb +++ b/actionpack/lib/action_dispatch/http/mime_type.rb @@ -1,7 +1,6 @@ # -*- frozen-string-literal: true -*- require "singleton" -require "active_support/core_ext/module/attribute_accessors" require "active_support/core_ext/string/starts_ends_with" module Mime @@ -278,6 +277,8 @@ module Mime def all?; false; end + # TODO Change this to private once we've dropped Ruby 2.2 support. + # Workaround for Ruby 2.2 "private attribute?" warning. protected attr_reader :string, :synonyms @@ -295,8 +296,8 @@ module Mime end end - def respond_to_missing?(method, include_private = false) #:nodoc: - method.to_s.ends_with? "?" + def respond_to_missing?(method, include_private = false) + (method.to_s.ends_with? "?") || super end end diff --git a/actionpack/lib/action_dispatch/http/parameters.rb b/actionpack/lib/action_dispatch/http/parameters.rb index ddd15b748b..8f21eca440 100644 --- a/actionpack/lib/action_dispatch/http/parameters.rb +++ b/actionpack/lib/action_dispatch/http/parameters.rb @@ -22,6 +22,7 @@ module ActionDispatch included do class << self + # Returns the parameter parsers. attr_reader :parameter_parsers end @@ -29,7 +30,16 @@ module ActionDispatch end module ClassMethods - def parameter_parsers=(parsers) # :nodoc: + # Configure the parameter parser for a given mime type. + # + # It accepts a hash where the key is the symbol of the mime type + # and the value is a proc. + # + # original_parsers = ActionDispatch::Request.parameter_parsers + # xml_parser = -> (raw_post) { Hash.from_xml(raw_post) || {} } + # new_parsers = original_parsers.merge(xml: xml_parser) + # ActionDispatch::Request.parameter_parsers = new_parsers + def parameter_parsers=(parsers) @parameter_parsers = parsers.transform_keys { |key| key.respond_to?(:symbol) ? key.symbol : key } end end @@ -45,7 +55,7 @@ module ActionDispatch query_parameters.dup end params.merge!(path_parameters) - params = set_custom_encoding(params) + params = set_binary_encoding(params) set_header("action_dispatch.request.parameters", params) params end @@ -73,21 +83,16 @@ module ActionDispatch private - def set_custom_encoding(params) + def set_binary_encoding(params) action = params[:action] - params.each do |k, v| - if v.is_a?(String) && v.encoding != encoding_template(action, k) - params[k] = v.force_encoding(encoding_template(action, k)) + if controller_class.binary_params_for?(action) + ActionDispatch::Request::Utils.each_param_value(params) do |param| + param.force_encoding ::Encoding::ASCII_8BIT end end - params end - def encoding_template(action, param) - controller_class.encoding_for_param(action, param) - end - def parse_formatted_parameters(parsers) return yield if content_length.zero? || content_mime_type.nil? diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index 9986d6e1e9..19fa42ce12 100644 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -69,7 +69,7 @@ module ActionDispatch PASS_NOT_FOUND = Class.new { # :nodoc: def self.action(_); self; end def self.call(_); [404, { "X-Cascade" => "pass" }, []]; end - def self.encoding_for_param(action, param); ::Encoding::UTF_8; end + def self.binary_params_for?(action); false; end } def controller_class @@ -85,6 +85,9 @@ module ActionDispatch end end + # Returns true if the request has a header matching the given key parameter. + # + # request.key? :ip_spoofing_check # => true def key?(key) has_header? key end diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index f71c6afd6c..dc159596c4 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -227,7 +227,9 @@ module ActionDispatch # :nodoc: return unless content_type new_header_info = parse_content_type(content_type.to_s) prev_header_info = parsed_content_type_header - set_content_type new_header_info.mime_type, new_header_info.charset || prev_header_info.charset || self.class.default_charset + charset = new_header_info.charset || prev_header_info.charset + charset ||= self.class.default_charset unless prev_header_info.mime_type + set_content_type new_header_info.mime_type, charset end # Sets the HTTP response's content MIME type. For example, in the controller @@ -423,7 +425,7 @@ module ActionDispatch # :nodoc: def set_content_type(content_type, charset) type = (content_type || "").dup - type << "; charset=#{charset}" if charset + type << "; charset=#{charset.to_s.downcase}" if charset set_header CONTENT_TYPE, type end |