aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_dispatch')
-rw-r--r--actionpack/lib/action_dispatch/http/headers.rb2
-rw-r--r--actionpack/lib/action_dispatch/http/mime_negotiation.rb5
-rw-r--r--actionpack/lib/action_dispatch/http/parameter_filter.rb17
-rw-r--r--actionpack/lib/action_dispatch/middleware/cookies.rb42
-rw-r--r--actionpack/lib/action_dispatch/middleware/ssl.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb3
-rw-r--r--actionpack/lib/action_dispatch/railtie.rb1
-rw-r--r--actionpack/lib/action_dispatch/request/utils.rb2
-rw-r--r--actionpack/lib/action_dispatch/routing/inspector.rb2
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb14
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/routing.rb4
-rw-r--r--actionpack/lib/action_dispatch/testing/integration.rb2
-rw-r--r--actionpack/lib/action_dispatch/testing/test_process.rb4
13 files changed, 60 insertions, 40 deletions
diff --git a/actionpack/lib/action_dispatch/http/headers.rb b/actionpack/lib/action_dispatch/http/headers.rb
index c3c2a9d8c5..6c7d24d2d0 100644
--- a/actionpack/lib/action_dispatch/http/headers.rb
+++ b/actionpack/lib/action_dispatch/http/headers.rb
@@ -121,7 +121,7 @@ module ActionDispatch
# not contained within the headers hash.
def env_name(key)
key = key.to_s
- if key =~ HTTP_HEADER
+ if HTTP_HEADER.match?(key)
key = key.upcase.tr("-", "_")
key = "HTTP_" + key unless CGI_VARIABLES.include?(key)
end
diff --git a/actionpack/lib/action_dispatch/http/mime_negotiation.rb b/actionpack/lib/action_dispatch/http/mime_negotiation.rb
index d7435fa8df..be129965d1 100644
--- a/actionpack/lib/action_dispatch/http/mime_negotiation.rb
+++ b/actionpack/lib/action_dispatch/http/mime_negotiation.rb
@@ -85,10 +85,7 @@ module ActionDispatch
if variant.all? { |v| v.is_a?(Symbol) }
@variant = ActiveSupport::ArrayInquirer.new(variant)
else
- raise ArgumentError, "request.variant must be set to a Symbol or an Array of Symbols. " \
- "For security reasons, never directly set the variant to a user-provided value, " \
- "like params[:variant].to_sym. Check user-provided value against a whitelist first, " \
- "then set the variant: request.variant = :tablet if params[:variant] == 'tablet'"
+ raise ArgumentError, "request.variant must be set to a Symbol or an Array of Symbols."
end
end
diff --git a/actionpack/lib/action_dispatch/http/parameter_filter.rb b/actionpack/lib/action_dispatch/http/parameter_filter.rb
index 1d58964862..09aab631ed 100644
--- a/actionpack/lib/action_dispatch/http/parameter_filter.rb
+++ b/actionpack/lib/action_dispatch/http/parameter_filter.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
require "active_support/core_ext/object/duplicable"
+require "active_support/core_ext/array/extract"
module ActionDispatch
module Http
@@ -38,8 +39,8 @@ module ActionDispatch
end
end
- deep_regexps, regexps = regexps.partition { |r| r.to_s.include?("\\.".freeze) }
- deep_strings, strings = strings.partition { |s| s.include?("\\.".freeze) }
+ deep_regexps = regexps.extract! { |r| r.to_s.include?("\\.".freeze) }
+ deep_strings = strings.extract! { |s| s.include?("\\.".freeze) }
regexps << Regexp.new(strings.join("|".freeze), true) unless strings.empty?
deep_regexps << Regexp.new(deep_strings.join("|".freeze), true) unless deep_strings.empty?
@@ -55,23 +56,23 @@ module ActionDispatch
@blocks = blocks
end
- def call(original_params, parents = [])
- filtered_params = original_params.class.new
+ def call(params, parents = [], original_params = params)
+ filtered_params = params.class.new
- original_params.each do |key, value|
+ params.each do |key, value|
parents.push(key) if deep_regexps
if regexps.any? { |r| key =~ r }
value = FILTERED
elsif deep_regexps && (joined = parents.join(".")) && deep_regexps.any? { |r| joined =~ r }
value = FILTERED
elsif value.is_a?(Hash)
- value = call(value, parents)
+ value = call(value, parents, original_params)
elsif value.is_a?(Array)
- value = value.map { |v| v.is_a?(Hash) ? call(v, parents) : v }
+ value = value.map { |v| v.is_a?(Hash) ? call(v, parents, original_params) : v }
elsif blocks.any?
key = key.dup if key.duplicable?
value = value.dup if value.duplicable?
- blocks.each { |b| b.call(key, value) }
+ blocks.each { |b| b.arity == 2 ? b.call(key, value) : b.call(key, value, original_params) }
end
parents.pop if deep_regexps
diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb
index c45d947904..34331b7e4b 100644
--- a/actionpack/lib/action_dispatch/middleware/cookies.rb
+++ b/actionpack/lib/action_dispatch/middleware/cookies.rb
@@ -81,6 +81,10 @@ module ActionDispatch
get_header Cookies::COOKIES_ROTATIONS
end
+ def use_cookies_with_metadata
+ get_header Cookies::USE_COOKIES_WITH_METADATA
+ end
+
# :startdoc:
end
@@ -182,6 +186,7 @@ module ActionDispatch
COOKIES_SERIALIZER = "action_dispatch.cookies_serializer".freeze
COOKIES_DIGEST = "action_dispatch.cookies_digest".freeze
COOKIES_ROTATIONS = "action_dispatch.cookies_rotations".freeze
+ USE_COOKIES_WITH_METADATA = "action_dispatch.use_cookies_with_metadata".freeze
# Cookies can typically store 4096 bytes.
MAX_COOKIE_SIZE = 4096
@@ -470,7 +475,7 @@ module ActionDispatch
def [](name)
if data = @parent_jar[name.to_s]
- parse name, data
+ parse(name, data, purpose: "cookie.#{name}") || parse(name, data)
end
end
@@ -481,7 +486,7 @@ module ActionDispatch
options = { value: options }
end
- commit(options)
+ commit(name, options)
@parent_jar[name] = options
end
@@ -497,13 +502,24 @@ module ActionDispatch
end
end
- def parse(name, data); data; end
- def commit(options); end
+ def cookie_metadata(name, options)
+ if request.use_cookies_with_metadata
+ metadata = expiry_options(options)
+ metadata[:purpose] = "cookie.#{name}"
+
+ metadata
+ else
+ {}
+ end
+ end
+
+ def parse(name, data, purpose: nil); data; end
+ def commit(name, options); end
end
class PermanentCookieJar < AbstractCookieJar # :nodoc:
private
- def commit(options)
+ def commit(name, options)
options[:expires] = 20.years.from_now
end
end
@@ -583,14 +599,14 @@ module ActionDispatch
end
private
- def parse(name, signed_message)
+ def parse(name, signed_message, purpose: nil)
deserialize(name) do |rotate|
- @verifier.verified(signed_message, on_rotation: rotate)
+ @verifier.verified(signed_message, on_rotation: rotate, purpose: purpose)
end
end
- def commit(options)
- options[:value] = @verifier.generate(serialize(options[:value]), expiry_options(options))
+ def commit(name, options)
+ options[:value] = @verifier.generate(serialize(options[:value]), cookie_metadata(name, options))
raise CookieOverflow if options[:value].bytesize > MAX_COOKIE_SIZE
end
@@ -631,16 +647,16 @@ module ActionDispatch
end
private
- def parse(name, encrypted_message)
+ def parse(name, encrypted_message, purpose: nil)
deserialize(name) do |rotate|
- @encryptor.decrypt_and_verify(encrypted_message, on_rotation: rotate)
+ @encryptor.decrypt_and_verify(encrypted_message, on_rotation: rotate, purpose: purpose)
end
rescue ActiveSupport::MessageEncryptor::InvalidMessage, ActiveSupport::MessageVerifier::InvalidSignature
parse_legacy_signed_message(name, encrypted_message)
end
- def commit(options)
- options[:value] = @encryptor.encrypt_and_sign(serialize(options[:value]), expiry_options(options))
+ def commit(name, options)
+ options[:value] = @encryptor.encrypt_and_sign(serialize(options[:value]), cookie_metadata(name, options))
raise CookieOverflow if options[:value].bytesize > MAX_COOKIE_SIZE
end
diff --git a/actionpack/lib/action_dispatch/middleware/ssl.rb b/actionpack/lib/action_dispatch/middleware/ssl.rb
index 240269d1c7..190e54223e 100644
--- a/actionpack/lib/action_dispatch/middleware/ssl.rb
+++ b/actionpack/lib/action_dispatch/middleware/ssl.rb
@@ -113,7 +113,7 @@ module ActionDispatch
cookies = cookies.split("\n".freeze)
headers["Set-Cookie".freeze] = cookies.map { |cookie|
- if cookie !~ /;\s*secure\s*(;|$)/i
+ if !/;\s*secure\s*(;|$)/i.match?(cookie)
"#{cookie}; secure"
else
cookie
diff --git a/actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb b/actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb
index 1fa0691303..0242b706b2 100644
--- a/actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb
+++ b/actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb
@@ -197,4 +197,7 @@
setupMatchPaths();
setupRouteToggleHelperLinks();
+
+ // Focus the search input after page has loaded
+ document.getElementById('search').focus();
</script>
diff --git a/actionpack/lib/action_dispatch/railtie.rb b/actionpack/lib/action_dispatch/railtie.rb
index eb6fbca6ba..efc3988bc3 100644
--- a/actionpack/lib/action_dispatch/railtie.rb
+++ b/actionpack/lib/action_dispatch/railtie.rb
@@ -21,6 +21,7 @@ module ActionDispatch
config.action_dispatch.encrypted_signed_cookie_salt = "signed encrypted cookie"
config.action_dispatch.authenticated_encrypted_cookie_salt = "authenticated encrypted cookie"
config.action_dispatch.use_authenticated_cookie_encryption = false
+ config.action_dispatch.use_cookies_with_metadata = false
config.action_dispatch.perform_deep_munge = true
config.action_dispatch.default_headers = {
diff --git a/actionpack/lib/action_dispatch/request/utils.rb b/actionpack/lib/action_dispatch/request/utils.rb
index 0ae464082d..fb0efb9a58 100644
--- a/actionpack/lib/action_dispatch/request/utils.rb
+++ b/actionpack/lib/action_dispatch/request/utils.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require "active_support/core_ext/hash/indifferent_access"
+
module ActionDispatch
class Request
class Utils # :nodoc:
diff --git a/actionpack/lib/action_dispatch/routing/inspector.rb b/actionpack/lib/action_dispatch/routing/inspector.rb
index cba49d1a0b..413e524ef6 100644
--- a/actionpack/lib/action_dispatch/routing/inspector.rb
+++ b/actionpack/lib/action_dispatch/routing/inspector.rb
@@ -83,7 +83,7 @@ module ActionDispatch
private
def normalize_filter(filter)
if filter[:controller]
- { controller: /#{filter[:controller].downcase.sub(/_?controller\z/, '').sub('::', '/')}/ }
+ { controller: /#{filter[:controller].underscore.sub(/_?controller\z/, "")}/ }
elsif filter[:grep]
{ controller: /#{filter[:grep]}/, action: /#{filter[:grep]}/,
verb: /#{filter[:grep]}/, name: /#{filter[:grep]}/, path: /#{filter[:grep]}/ }
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index aeaae3c1dd..07e3be4db8 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -279,7 +279,7 @@ module ActionDispatch
def verify_regexp_requirements(requirements)
requirements.each do |requirement|
- if requirement.source =~ ANCHOR_CHARACTERS_REGEX
+ if ANCHOR_CHARACTERS_REGEX.match?(requirement.source)
raise ArgumentError, "Regexp anchor characters are not allowed in routing requirements: #{requirement.inspect}"
end
@@ -333,7 +333,7 @@ module ActionDispatch
end
def split_to(to)
- if to =~ /#/
+ if /#/.match?(to)
to.split("#")
else
[]
@@ -342,7 +342,7 @@ module ActionDispatch
def add_controller_module(controller, modyoule)
if modyoule && !controller.is_a?(Regexp)
- if controller =~ %r{\A/}
+ if %r{\A/}.match?(controller)
controller[1..-1]
else
[modyoule, controller].compact.join("/")
@@ -553,10 +553,10 @@ module ActionDispatch
#
# match 'json_only', constraints: { format: 'json' }, via: :get
#
- # class Whitelist
+ # class PermitList
# def matches?(request) request.remote_ip == '1.2.3.4' end
# end
- # match 'path', to: 'c#a', constraints: Whitelist.new, via: :get
+ # match 'path', to: 'c#a', constraints: PermitList.new, via: :get
#
# See <tt>Scoping#constraints</tt> for more examples with its scope
# equivalent.
@@ -1588,7 +1588,7 @@ module ActionDispatch
when Symbol
options[:action] = to
when String
- if to =~ /#/
+ if /#/.match?(to)
options[:to] = to
else
options[:controller] = to
@@ -1914,7 +1914,7 @@ module ActionDispatch
default_action = options.delete(:action) || @scope[:action]
- if action =~ /^[\w\-\/]+$/
+ if /^[\w\-\/]+$/.match?(action)
default_action ||= action.tr("-", "_") unless action.include?("/")
else
action = nil
diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
index 5390581139..77cb311630 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
@@ -78,7 +78,7 @@ module ActionDispatch
# # Asserts that the generated route gives us our custom route
# assert_generates "changesets/12", { controller: 'scm', action: 'show_diff', revision: "12" }
def assert_generates(expected_path, options, defaults = {}, extras = {}, message = nil)
- if expected_path =~ %r{://}
+ if %r{://}.match?(expected_path)
fail_on(URI::InvalidURIError, message) do
uri = URI.parse(expected_path)
expected_path = uri.path.to_s.empty? ? "/" : uri.path
@@ -189,7 +189,7 @@ module ActionDispatch
request = ActionController::TestRequest.create @controller.class
- if path =~ %r{://}
+ if %r{://}.match?(path)
fail_on(URI::InvalidURIError, msg) do
uri = URI.parse(path)
request.env["rack.url_scheme"] = uri.scheme || "http"
diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb
index 7637febd1c..45439a3bb1 100644
--- a/actionpack/lib/action_dispatch/testing/integration.rb
+++ b/actionpack/lib/action_dispatch/testing/integration.rb
@@ -217,7 +217,7 @@ module ActionDispatch
method = :post
end
- if path =~ %r{://}
+ if %r{://}.match?(path)
path = build_expanded_path(path) do |location|
https! URI::HTTPS === location if location.scheme
diff --git a/actionpack/lib/action_dispatch/testing/test_process.rb b/actionpack/lib/action_dispatch/testing/test_process.rb
index 8ac50c730d..0b98f27f11 100644
--- a/actionpack/lib/action_dispatch/testing/test_process.rb
+++ b/actionpack/lib/action_dispatch/testing/test_process.rb
@@ -8,12 +8,12 @@ module ActionDispatch
module FixtureFile
# Shortcut for <tt>Rack::Test::UploadedFile.new(File.join(ActionDispatch::IntegrationTest.fixture_path, path), type)</tt>:
#
- # post :change_avatar, avatar: fixture_file_upload('files/spongebob.png', 'image/png')
+ # post :change_avatar, params: { avatar: fixture_file_upload('files/spongebob.png', 'image/png') }
#
# To upload binary files on Windows, pass <tt>:binary</tt> as the last parameter.
# This will not affect other platforms:
#
- # post :change_avatar, avatar: fixture_file_upload('files/spongebob.png', 'image/png', :binary)
+ # post :change_avatar, params: { avatar: fixture_file_upload('files/spongebob.png', 'image/png', :binary) }
def fixture_file_upload(path, mime_type = nil, binary = false)
if self.class.respond_to?(:fixture_path) && self.class.fixture_path &&
!File.exist?(path)