diff options
Diffstat (limited to 'actionpack/lib/action_controller/metal')
13 files changed, 72 insertions, 38 deletions
diff --git a/actionpack/lib/action_controller/metal/conditional_get.rb b/actionpack/lib/action_controller/metal/conditional_get.rb index 4be4557e2c..d6911ee2b5 100644 --- a/actionpack/lib/action_controller/metal/conditional_get.rb +++ b/actionpack/lib/action_controller/metal/conditional_get.rb @@ -230,6 +230,12 @@ module ActionController # This method will overwrite an existing Cache-Control header. # See https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html for more possibilities. # + # HTTP Cache-Control Extensions for Stale Content. See https://tools.ietf.org/html/rfc5861 + # It helps to cache an asset and serve it while is being revalidated and/or returning with an error. + # + # expires_in 3.hours, public: true, stale_while_revalidate: 60.seconds + # expires_in 3.hours, public: true, stale_while_revalidate: 60.seconds, stale_if_error: 5.minutes + # # The method will also ensure an HTTP Date header for client compatibility. def expires_in(seconds, options = {}) response.cache_control.merge!( diff --git a/actionpack/lib/action_controller/metal/data_streaming.rb b/actionpack/lib/action_controller/metal/data_streaming.rb index 5a82ccf668..9ef4f50df1 100644 --- a/actionpack/lib/action_controller/metal/data_streaming.rb +++ b/actionpack/lib/action_controller/metal/data_streaming.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require "action_controller/metal/exceptions" +require "action_dispatch/http/content_disposition" module ActionController #:nodoc: # Methods for sending arbitrary data and for streaming files to the browser, @@ -10,8 +11,8 @@ module ActionController #:nodoc: include ActionController::Rendering - DEFAULT_SEND_FILE_TYPE = "application/octet-stream".freeze #:nodoc: - DEFAULT_SEND_FILE_DISPOSITION = "attachment".freeze #:nodoc: + DEFAULT_SEND_FILE_TYPE = "application/octet-stream" #:nodoc: + DEFAULT_SEND_FILE_DISPOSITION = "attachment" #:nodoc: private # Sends the file. This uses a server-appropriate method (such as X-Sendfile) @@ -132,10 +133,8 @@ module ActionController #:nodoc: end disposition = options.fetch(:disposition, DEFAULT_SEND_FILE_DISPOSITION) - unless disposition.nil? - disposition = disposition.to_s - disposition += %(; filename="#{options[:filename]}") if options[:filename] - headers["Content-Disposition"] = disposition + if disposition + headers["Content-Disposition"] = ActionDispatch::Http::ContentDisposition.format(disposition: disposition, filename: options[:filename]) end headers["Content-Transfer-Encoding"] = "binary" diff --git a/actionpack/lib/action_controller/metal/flash.rb b/actionpack/lib/action_controller/metal/flash.rb index 5115c2fadf..380f2e9591 100644 --- a/actionpack/lib/action_controller/metal/flash.rb +++ b/actionpack/lib/action_controller/metal/flash.rb @@ -36,7 +36,7 @@ module ActionController #:nodoc: define_method(type) do request.flash[type] end - helper_method type + helper_method(type) if respond_to?(:helper_method) self._flash_types += [type] end diff --git a/actionpack/lib/action_controller/metal/force_ssl.rb b/actionpack/lib/action_controller/metal/force_ssl.rb index 8d53a30e93..26e6f72b66 100644 --- a/actionpack/lib/action_controller/metal/force_ssl.rb +++ b/actionpack/lib/action_controller/metal/force_ssl.rb @@ -5,8 +5,8 @@ require "active_support/core_ext/hash/slice" module ActionController # This module is deprecated in favor of +config.force_ssl+ in your environment - # config file. This will ensure all communication to non-whitelisted endpoints - # served by your application occurs over HTTPS. + # config file. This will ensure all endpoints not explicitly marked otherwise + # will have all communication served over HTTPS. module ForceSSL # :nodoc: extend ActiveSupport::Concern include AbstractController::Callbacks diff --git a/actionpack/lib/action_controller/metal/helpers.rb b/actionpack/lib/action_controller/metal/helpers.rb index 22c84e440b..0faaac1ce4 100644 --- a/actionpack/lib/action_controller/metal/helpers.rb +++ b/actionpack/lib/action_controller/metal/helpers.rb @@ -100,8 +100,7 @@ module ActionController # # => ["application", "chart", "rubygems"] def all_helpers_from_path(path) helpers = Array(path).flat_map do |_path| - extract = /^#{Regexp.quote(_path.to_s)}\/?(.*)_helper.rb$/ - names = Dir["#{_path}/**/*_helper.rb"].map { |file| file.sub(extract, '\1'.freeze) } + names = Dir["#{_path}/**/*_helper.rb"].map { |file| file[_path.to_s.size + 1..-"_helper.rb".size - 1] } names.sort! end helpers.uniq! diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb index a871ccd533..7036123d5d 100644 --- a/actionpack/lib/action_controller/metal/http_authentication.rb +++ b/actionpack/lib/action_controller/metal/http_authentication.rb @@ -127,7 +127,7 @@ module ActionController def authentication_request(controller, realm, message) message ||= "HTTP Basic: Access denied.\n" - controller.headers["WWW-Authenticate"] = %(Basic realm="#{realm.tr('"'.freeze, "".freeze)}") + controller.headers["WWW-Authenticate"] = %(Basic realm="#{realm.tr('"', "")}") controller.status = 401 controller.response_body = message end @@ -474,7 +474,7 @@ module ActionController # This removes the <tt>"</tt> characters wrapping the value. def rewrite_param_values(array_params) - array_params.each { |param| (param[1] || "".dup).gsub! %r/^"|"$/, "" } + array_params.each { |param| (param[1] || +"").gsub! %r/^"|"$/, "" } end # This method takes an authorization body and splits up the key-value @@ -511,7 +511,7 @@ module ActionController # Returns nothing. def authentication_request(controller, realm, message = nil) message ||= "HTTP Token: Access denied.\n" - controller.headers["WWW-Authenticate"] = %(Token realm="#{realm.tr('"'.freeze, "".freeze)}") + controller.headers["WWW-Authenticate"] = %(Token realm="#{realm.tr('"', "")}") controller.__send__ :render, plain: message, status: :unauthorized end end diff --git a/actionpack/lib/action_controller/metal/live.rb b/actionpack/lib/action_controller/metal/live.rb index 2f4c8fb83c..1482b2999a 100644 --- a/actionpack/lib/action_controller/metal/live.rb +++ b/actionpack/lib/action_controller/metal/live.rb @@ -86,7 +86,7 @@ module ActionController # Note: SSEs are not currently supported by IE. However, they are supported # by Chrome, Firefox, Opera, and Safari. class SSE - WHITELISTED_OPTIONS = %w( retry event id ) + PERMITTED_OPTIONS = %w( retry event id ) def initialize(stream, options = {}) @stream = stream @@ -111,13 +111,13 @@ module ActionController def perform_write(json, options) current_options = @options.merge(options).stringify_keys - WHITELISTED_OPTIONS.each do |option_name| + PERMITTED_OPTIONS.each do |option_name| if (option_value = current_options[option_name]) @stream.write "#{option_name}: #{option_value}\n" end end - message = json.gsub("\n".freeze, "\ndata: ".freeze) + message = json.gsub("\n", "\ndata: ") @stream.write "data: #{message}\n\n" end end @@ -297,7 +297,7 @@ module ActionController return unless logger logger.fatal do - message = "\n#{exception.class} (#{exception.message}):\n".dup + message = +"\n#{exception.class} (#{exception.message}):\n" message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code) message << " " << exception.backtrace.join("\n ") "#{message}\n\n" diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb index 2b55b9347c..118da11990 100644 --- a/actionpack/lib/action_controller/metal/mime_responds.rb +++ b/actionpack/lib/action_controller/metal/mime_responds.rb @@ -11,7 +11,7 @@ module ActionController #:nodoc: # @people = Person.all # end # - # That action implicitly responds to all formats, but formats can also be whitelisted: + # That action implicitly responds to all formats, but formats can also be explicitly enumerated: # # def index # @people = Person.all @@ -105,7 +105,7 @@ module ActionController #:nodoc: # # Mime::Type.register "image/jpg", :jpg # - # Respond to also allows you to specify a common block for different formats by using +any+: + # +respond_to+ also allows you to specify a common block for different formats by using +any+: # # def index # @people = Person.all diff --git a/actionpack/lib/action_controller/metal/redirecting.rb b/actionpack/lib/action_controller/metal/redirecting.rb index 4c2b5120eb..2804a06a58 100644 --- a/actionpack/lib/action_controller/metal/redirecting.rb +++ b/actionpack/lib/action_controller/metal/redirecting.rb @@ -105,7 +105,7 @@ module ActionController when String request.protocol + request.host_with_port + options when Proc - _compute_redirect_to_location request, options.call + _compute_redirect_to_location request, instance_eval(&options) else url_for(options) end.delete("\0\r\n") diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index 6d181e6456..7d0a944381 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -40,7 +40,7 @@ module ActionController def render_to_string(*) result = super if result.respond_to?(:each) - string = "".dup + string = +"" result.each { |r| string << r } string else diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb index 7ed7b9d546..cb109c6ad8 100644 --- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb +++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb @@ -45,7 +45,7 @@ module ActionController #:nodoc: # the same origin. Note however that any cross-origin third party domain # allowed via {CORS}[https://en.wikipedia.org/wiki/Cross-origin_resource_sharing] # will also be able to create XHR requests. Be sure to check your - # CORS whitelist before disabling forgery protection for XHR. + # CORS configuration before disabling forgery protection for XHR. # # CSRF protection is turned on with the <tt>protect_from_forgery</tt> method. # By default <tt>protect_from_forgery</tt> protects your session with diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb index 7af29f8dca..c1272ce667 100644 --- a/actionpack/lib/action_controller/metal/strong_parameters.rb +++ b/actionpack/lib/action_controller/metal/strong_parameters.rb @@ -58,7 +58,7 @@ module ActionController # == Action Controller \Parameters # - # Allows you to choose which attributes should be whitelisted for mass updating + # Allows you to choose which attributes should be permitted for mass updating # and thus prevent accidentally exposing that which shouldn't be exposed. # Provides two methods for this purpose: #require and #permit. The former is # used to mark parameters as required. The latter is used to set the parameter @@ -133,6 +133,15 @@ module ActionController # Returns a hash that can be used as the JSON representation for the parameters. ## + # :method: each_key + # + # :call-seq: + # each_key() + # + # Calls block once for each key in the parameters, passing the key. + # If no block is given, an enumerator is returned instead. + + ## # :method: empty? # # :call-seq: @@ -204,7 +213,7 @@ module ActionController # # Returns a new array of the values of the parameters. delegate :keys, :key?, :has_key?, :values, :has_value?, :value?, :empty?, :include?, - :as_json, :to_s, to: :@parameters + :as_json, :to_s, :each_key, to: :@parameters # By default, never raise an UnpermittedParameters exception if these # params are present. The default includes both 'controller' and 'action' @@ -339,6 +348,14 @@ module ActionController end alias_method :each, :each_pair + # Convert all hashes in values into parameters, then yield each value in + # the same way as <tt>Hash#each_value</tt>. + def each_value(&block) + @parameters.each_pair do |key, value| + yield [convert_hashes_to_parameters(key, value)] + end + end + # Attribute that keeps track of converted arrays, if any, to avoid double # looping in the common use case permit + mass-assignment. Defined in a # method to instantiate it only if needed. @@ -505,7 +522,7 @@ module ActionController # # Note that if you use +permit+ in a key that points to a hash, # it won't allow all the hash. You also need to specify which - # attributes inside the hash should be whitelisted. + # attributes inside the hash should be permitted. # # params = ActionController::Parameters.new({ # person: { @@ -904,15 +921,28 @@ module ActionController PERMITTED_SCALAR_TYPES.any? { |type| value.is_a?(type) } end - def permitted_scalar_filter(params, key) - if has_key?(key) && permitted_scalar?(self[key]) - params[key] = self[key] + # Adds existing keys to the params if their values are scalar. + # + # For example: + # + # puts self.keys #=> ["zipcode(90210i)"] + # params = {} + # + # permitted_scalar_filter(params, "zipcode") + # + # puts params.keys # => ["zipcode"] + def permitted_scalar_filter(params, permitted_key) + permitted_key = permitted_key.to_s + + if has_key?(permitted_key) && permitted_scalar?(self[permitted_key]) + params[permitted_key] = self[permitted_key] end - keys.grep(/\A#{Regexp.escape(key)}\(\d+[if]?\)\z/) do |k| - if permitted_scalar?(self[k]) - params[k] = self[k] - end + each_key do |key| + next unless key =~ /\(\d+[if]?\)\z/ + next unless $~.pre_match == permitted_key + + params[key] = self[key] if permitted_scalar?(self[key]) end end @@ -997,8 +1027,8 @@ module ActionController # # It provides an interface for protecting attributes from end-user # assignment. This makes Action Controller parameters forbidden - # to be used in Active Model mass assignment until they have been - # whitelisted. + # to be used in Active Model mass assignment until they have been explicitly + # enumerated. # # In addition, parameters can be marked as required and flow through a # predefined raise/rescue flow to end up as a <tt>400 Bad Request</tt> with no @@ -1034,7 +1064,7 @@ module ActionController # end # # In order to use <tt>accepts_nested_attributes_for</tt> with Strong \Parameters, you - # will need to specify which nested attributes should be whitelisted. You might want + # will need to specify which nested attributes should be permitted. You might want # to allow +:id+ and +:_destroy+, see ActiveRecord::NestedAttributes for more information. # # class Person @@ -1052,7 +1082,7 @@ module ActionController # private # # def person_params - # # It's mandatory to specify the nested attributes that should be whitelisted. + # # It's mandatory to specify the nested attributes that should be permitted. # # If you use `permit` with just the key that points to the nested attributes hash, # # it will return an empty hash. # params.require(:person).permit(:name, :age, pets_attributes: [ :id, :name, :category ]) diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb index 84dbb59a63..f077e765ab 100644 --- a/actionpack/lib/action_controller/metal/url_for.rb +++ b/actionpack/lib/action_controller/metal/url_for.rb @@ -44,7 +44,7 @@ module ActionController options[:original_script_name] = original_script_name else if same_origin - options[:script_name] = request.script_name.empty? ? "".freeze : request.script_name.dup + options[:script_name] = request.script_name.empty? ? "" : request.script_name.dup else options[:script_name] = script_name end |