actionpack 5.1.7 → 5.2.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +132 -490
- data/README.rdoc +1 -1
- data/lib/abstract_controller.rb +2 -0
- data/lib/abstract_controller/asset_paths.rb +2 -0
- data/lib/abstract_controller/base.rb +10 -2
- data/lib/abstract_controller/caching.rb +3 -2
- data/lib/abstract_controller/caching/fragments.rb +30 -7
- data/lib/abstract_controller/callbacks.rb +25 -3
- data/lib/abstract_controller/collector.rb +2 -0
- data/lib/abstract_controller/error.rb +2 -0
- data/lib/abstract_controller/helpers.rb +4 -5
- data/lib/abstract_controller/logger.rb +2 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
- data/lib/abstract_controller/rendering.rb +9 -16
- data/lib/abstract_controller/translation.rb +2 -0
- data/lib/abstract_controller/url_for.rb +2 -0
- data/lib/action_controller.rb +3 -0
- data/lib/action_controller/api.rb +2 -0
- data/lib/action_controller/api/api_rendering.rb +2 -0
- data/lib/action_controller/base.rb +3 -0
- data/lib/action_controller/caching.rb +2 -0
- data/lib/action_controller/form_builder.rb +2 -0
- data/lib/action_controller/log_subscriber.rb +5 -3
- data/lib/action_controller/metal.rb +3 -2
- data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
- data/lib/action_controller/metal/conditional_get.rb +4 -3
- data/lib/action_controller/metal/content_security_policy.rb +26 -0
- data/lib/action_controller/metal/cookies.rb +2 -0
- data/lib/action_controller/metal/data_streaming.rb +7 -5
- data/lib/action_controller/metal/etag_with_flash.rb +2 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +3 -2
- data/lib/action_controller/metal/exceptions.rb +2 -3
- data/lib/action_controller/metal/flash.rb +3 -2
- data/lib/action_controller/metal/force_ssl.rb +2 -0
- data/lib/action_controller/metal/head.rb +2 -0
- data/lib/action_controller/metal/helpers.rb +4 -3
- data/lib/action_controller/metal/http_authentication.rb +8 -9
- data/lib/action_controller/metal/implicit_render.rb +2 -0
- data/lib/action_controller/metal/instrumentation.rb +4 -6
- data/lib/action_controller/metal/live.rb +3 -1
- data/lib/action_controller/metal/mime_responds.rb +3 -1
- data/lib/action_controller/metal/parameter_encoding.rb +2 -0
- data/lib/action_controller/metal/params_wrapper.rb +13 -9
- data/lib/action_controller/metal/redirecting.rb +21 -10
- data/lib/action_controller/metal/renderers.rb +4 -3
- data/lib/action_controller/metal/rendering.rb +2 -2
- data/lib/action_controller/metal/request_forgery_protection.rb +22 -6
- data/lib/action_controller/metal/rescue.rb +5 -3
- data/lib/action_controller/metal/streaming.rb +2 -0
- data/lib/action_controller/metal/strong_parameters.rb +19 -11
- data/lib/action_controller/metal/testing.rb +2 -6
- data/lib/action_controller/metal/url_for.rb +2 -0
- data/lib/action_controller/railtie.rb +16 -4
- data/lib/action_controller/railties/helpers.rb +2 -0
- data/lib/action_controller/renderer.rb +2 -0
- data/lib/action_controller/template_assertions.rb +2 -0
- data/lib/action_controller/test_case.rb +4 -1
- data/lib/action_dispatch.rb +3 -0
- data/lib/action_dispatch/http/cache.rb +15 -9
- data/lib/action_dispatch/http/content_security_policy.rb +233 -0
- data/lib/action_dispatch/http/filter_parameters.rb +4 -2
- data/lib/action_dispatch/http/filter_redirect.rb +2 -0
- data/lib/action_dispatch/http/headers.rb +2 -0
- data/lib/action_dispatch/http/mime_negotiation.rb +4 -13
- data/lib/action_dispatch/http/mime_type.rb +15 -13
- data/lib/action_dispatch/http/mime_types.rb +4 -2
- data/lib/action_dispatch/http/parameter_filter.rb +2 -0
- data/lib/action_dispatch/http/parameters.rb +6 -9
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +36 -16
- data/lib/action_dispatch/http/response.rb +11 -9
- data/lib/action_dispatch/http/upload.rb +2 -0
- data/lib/action_dispatch/http/url.rb +4 -5
- data/lib/action_dispatch/journey.rb +2 -0
- data/lib/action_dispatch/journey/formatter.rb +4 -2
- data/lib/action_dispatch/journey/gtg/builder.rb +2 -0
- data/lib/action_dispatch/journey/gtg/simulator.rb +2 -8
- data/lib/action_dispatch/journey/gtg/transition_table.rb +3 -2
- data/lib/action_dispatch/journey/nfa/builder.rb +2 -0
- data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
- data/lib/action_dispatch/journey/nfa/simulator.rb +2 -0
- data/lib/action_dispatch/journey/nfa/transition_table.rb +2 -0
- data/lib/action_dispatch/journey/nodes/node.rb +2 -0
- data/lib/action_dispatch/journey/parser_extras.rb +2 -0
- data/lib/action_dispatch/journey/path/pattern.rb +2 -0
- data/lib/action_dispatch/journey/route.rb +15 -6
- data/lib/action_dispatch/journey/router.rb +3 -1
- data/lib/action_dispatch/journey/router/utils.rb +14 -7
- data/lib/action_dispatch/journey/routes.rb +2 -1
- data/lib/action_dispatch/journey/scanner.rb +1 -0
- data/lib/action_dispatch/journey/visitors.rb +5 -3
- data/lib/action_dispatch/middleware/callbacks.rb +2 -0
- data/lib/action_dispatch/middleware/cookies.rb +141 -91
- data/lib/action_dispatch/middleware/debug_exceptions.rb +4 -2
- data/lib/action_dispatch/middleware/debug_locks.rb +9 -7
- data/lib/action_dispatch/middleware/exception_wrapper.rb +4 -6
- data/lib/action_dispatch/middleware/executor.rb +2 -0
- data/lib/action_dispatch/middleware/flash.rb +3 -1
- data/lib/action_dispatch/middleware/public_exceptions.rb +6 -4
- data/lib/action_dispatch/middleware/reloader.rb +2 -0
- data/lib/action_dispatch/middleware/remote_ip.rb +7 -5
- data/lib/action_dispatch/middleware/request_id.rb +2 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +3 -1
- data/lib/action_dispatch/middleware/session/cache_store.rb +2 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +13 -25
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +2 -0
- data/lib/action_dispatch/middleware/show_exceptions.rb +3 -1
- data/lib/action_dispatch/middleware/ssl.rb +42 -37
- data/lib/action_dispatch/middleware/stack.rb +2 -0
- data/lib/action_dispatch/middleware/static.rb +10 -8
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +1 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +6 -2
- data/lib/action_dispatch/railtie.rb +7 -0
- data/lib/action_dispatch/request/session.rb +8 -4
- data/lib/action_dispatch/request/utils.rb +4 -4
- data/lib/action_dispatch/routing.rb +3 -1
- data/lib/action_dispatch/routing/endpoint.rb +8 -4
- data/lib/action_dispatch/routing/inspector.rb +5 -3
- data/lib/action_dispatch/routing/mapper.rb +62 -51
- data/lib/action_dispatch/routing/polymorphic_routes.rb +2 -0
- data/lib/action_dispatch/routing/redirection.rb +7 -5
- data/lib/action_dispatch/routing/route_set.rb +26 -33
- data/lib/action_dispatch/routing/routes_proxy.rb +5 -2
- data/lib/action_dispatch/routing/url_for.rb +6 -4
- data/lib/action_dispatch/system_test_case.rb +14 -6
- data/lib/action_dispatch/system_testing/driver.rb +20 -2
- data/lib/action_dispatch/system_testing/server.rb +2 -16
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +6 -4
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
- data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +26 -0
- data/lib/action_dispatch/testing/assertion_response.rb +2 -0
- data/lib/action_dispatch/testing/assertions.rb +2 -0
- data/lib/action_dispatch/testing/assertions/response.rb +4 -2
- data/lib/action_dispatch/testing/assertions/routing.rb +5 -5
- data/lib/action_dispatch/testing/integration.rb +24 -21
- data/lib/action_dispatch/testing/request_encoder.rb +2 -0
- data/lib/action_dispatch/testing/test_process.rb +2 -0
- data/lib/action_dispatch/testing/test_request.rb +3 -1
- data/lib/action_dispatch/testing/test_response.rb +23 -3
- data/lib/action_pack.rb +2 -0
- data/lib/action_pack/gem_version.rb +5 -3
- data/lib/action_pack/version.rb +2 -0
- metadata +17 -13
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/hash/keys"
|
2
4
|
|
3
5
|
module ActionController
|
@@ -7,8 +9,7 @@ module ActionController
|
|
7
9
|
include Head
|
8
10
|
|
9
11
|
included do
|
10
|
-
class_attribute :etaggers
|
11
|
-
self.etaggers = []
|
12
|
+
class_attribute :etaggers, default: []
|
12
13
|
end
|
13
14
|
|
14
15
|
module ClassMethods
|
@@ -227,7 +228,7 @@ module ActionController
|
|
227
228
|
# expires_in 3.hours, public: true, must_revalidate: true
|
228
229
|
#
|
229
230
|
# This method will overwrite an existing Cache-Control header.
|
230
|
-
# See
|
231
|
+
# See https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html for more possibilities.
|
231
232
|
#
|
232
233
|
# The method will also ensure an HTTP Date header for client compatibility.
|
233
234
|
def expires_in(seconds, options = {})
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionController #:nodoc:
|
4
|
+
module ContentSecurityPolicy
|
5
|
+
# TODO: Documentation
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def content_security_policy(**options, &block)
|
10
|
+
before_action(options) do
|
11
|
+
if block_given?
|
12
|
+
policy = request.content_security_policy.clone
|
13
|
+
yield policy
|
14
|
+
request.content_security_policy = policy
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def content_security_policy_report_only(report_only = true, **options)
|
20
|
+
before_action(options) do
|
21
|
+
request.content_security_policy_report_only = report_only
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "action_controller/metal/exceptions"
|
2
4
|
|
3
5
|
module ActionController #:nodoc:
|
@@ -54,14 +56,14 @@ module ActionController #:nodoc:
|
|
54
56
|
#
|
55
57
|
# Read about the other Content-* HTTP headers if you'd like to
|
56
58
|
# provide the user with more information (such as Content-Description) in
|
57
|
-
#
|
59
|
+
# https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11.
|
58
60
|
#
|
59
61
|
# Also be aware that the document may be cached by proxies and browsers.
|
60
62
|
# The Pragma and Cache-Control headers declare how the file may be cached
|
61
63
|
# by intermediaries. They default to require clients to validate with
|
62
64
|
# the server before releasing cached responses. See
|
63
|
-
#
|
64
|
-
#
|
65
|
+
# https://www.mnot.net/cache_docs/ for an overview of web caching and
|
66
|
+
# https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
|
65
67
|
# for the Cache-Control header spec.
|
66
68
|
def send_file(path, options = {}) #:doc:
|
67
69
|
raise MissingFile, "Cannot read file #{path}" unless File.file?(path) && File.readable?(path)
|
@@ -111,10 +113,10 @@ module ActionController #:nodoc:
|
|
111
113
|
def send_file_headers!(options)
|
112
114
|
type_provided = options.has_key?(:type)
|
113
115
|
|
114
|
-
|
116
|
+
content_type = options.fetch(:type, DEFAULT_SEND_FILE_TYPE)
|
117
|
+
self.content_type = content_type
|
115
118
|
response.sending_file = true
|
116
119
|
|
117
|
-
content_type = options.fetch(:type, DEFAULT_SEND_FILE_TYPE)
|
118
120
|
raise ArgumentError, ":type option required" if content_type.nil?
|
119
121
|
|
120
122
|
if content_type.is_a?(Symbol)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActionController
|
2
4
|
# When our views change, they should bubble up into HTTP cache freshness
|
3
5
|
# and bust browser caches. So the template digest for the current action
|
@@ -22,8 +24,7 @@ module ActionController
|
|
22
24
|
include ActionController::ConditionalGet
|
23
25
|
|
24
26
|
included do
|
25
|
-
class_attribute :etag_with_template_digest
|
26
|
-
self.etag_with_template_digest = true
|
27
|
+
class_attribute :etag_with_template_digest, default: true
|
27
28
|
|
28
29
|
ActiveSupport.on_load :action_view, yield: true do
|
29
30
|
etag do |options|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActionController
|
2
4
|
class ActionControllerError < StandardError #:nodoc:
|
3
5
|
end
|
@@ -32,9 +34,6 @@ module ActionController
|
|
32
34
|
class NotImplemented < MethodNotAllowed #:nodoc:
|
33
35
|
end
|
34
36
|
|
35
|
-
class UnknownController < ActionControllerError #:nodoc:
|
36
|
-
end
|
37
|
-
|
38
37
|
class MissingFile < ActionControllerError #:nodoc:
|
39
38
|
end
|
40
39
|
|
@@ -1,10 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActionController #:nodoc:
|
2
4
|
module Flash
|
3
5
|
extend ActiveSupport::Concern
|
4
6
|
|
5
7
|
included do
|
6
|
-
class_attribute :_flash_types, instance_accessor: false
|
7
|
-
self._flash_types = []
|
8
|
+
class_attribute :_flash_types, instance_accessor: false, default: []
|
8
9
|
|
9
10
|
delegate :flash, to: :request
|
10
11
|
add_flash_types(:alert, :notice)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActionController
|
2
4
|
# The \Rails framework provides a large number of helpers for working with assets, dates, forms,
|
3
5
|
# numbers and model objects, to name a few. These helpers are available to all templates
|
@@ -53,9 +55,8 @@ module ActionController
|
|
53
55
|
include AbstractController::Helpers
|
54
56
|
|
55
57
|
included do
|
56
|
-
class_attribute :helpers_path, :
|
57
|
-
|
58
|
-
self.include_all_helpers = true
|
58
|
+
class_attribute :helpers_path, default: []
|
59
|
+
class_attribute :include_all_helpers, default: true
|
59
60
|
end
|
60
61
|
|
61
62
|
module ClassMethods
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "base64"
|
2
4
|
require "active_support/security_utils"
|
3
5
|
|
@@ -70,10 +72,10 @@ module ActionController
|
|
70
72
|
before_action(options.except(:name, :password, :realm)) do
|
71
73
|
authenticate_or_request_with_http_basic(options[:realm] || "Application") do |name, password|
|
72
74
|
# This comparison uses & so that it doesn't short circuit and
|
73
|
-
# uses `
|
75
|
+
# uses `secure_compare` so that length information
|
74
76
|
# isn't leaked.
|
75
|
-
ActiveSupport::SecurityUtils.
|
76
|
-
ActiveSupport::SecurityUtils.
|
77
|
+
ActiveSupport::SecurityUtils.secure_compare(name, options[:name]) &
|
78
|
+
ActiveSupport::SecurityUtils.secure_compare(password, options[:password])
|
77
79
|
end
|
78
80
|
end
|
79
81
|
end
|
@@ -246,7 +248,7 @@ module ActionController
|
|
246
248
|
def decode_credentials(header)
|
247
249
|
ActiveSupport::HashWithIndifferentAccess[header.to_s.gsub(/^Digest\s+/, "").split(",").map do |pair|
|
248
250
|
key, value = pair.split("=", 2)
|
249
|
-
[key.strip, value.to_s.gsub(/^"|"$/, "").delete('
|
251
|
+
[key.strip, value.to_s.gsub(/^"|"$/, "").delete("'")]
|
250
252
|
end]
|
251
253
|
end
|
252
254
|
|
@@ -348,10 +350,7 @@ module ActionController
|
|
348
350
|
# authenticate_or_request_with_http_token do |token, options|
|
349
351
|
# # Compare the tokens in a time-constant manner, to mitigate
|
350
352
|
# # timing attacks.
|
351
|
-
# ActiveSupport::SecurityUtils.secure_compare(
|
352
|
-
# ::Digest::SHA256.hexdigest(token),
|
353
|
-
# ::Digest::SHA256.hexdigest(TOKEN)
|
354
|
-
# )
|
353
|
+
# ActiveSupport::SecurityUtils.secure_compare(token, TOKEN)
|
355
354
|
# end
|
356
355
|
# end
|
357
356
|
# end
|
@@ -475,7 +474,7 @@ module ActionController
|
|
475
474
|
|
476
475
|
# This removes the <tt>"</tt> characters wrapping the value.
|
477
476
|
def rewrite_param_values(array_params)
|
478
|
-
array_params.each { |param| (param[1] || "").gsub! %r/^"|"$/, "" }
|
477
|
+
array_params.each { |param| (param[1] || "".dup).gsub! %r/^"|"$/, "" }
|
479
478
|
end
|
480
479
|
|
481
480
|
# This method takes an authorization body and splits up the key-value
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "benchmark"
|
2
4
|
require "abstract_controller/logger"
|
3
5
|
|
@@ -81,16 +83,13 @@ module ActionController
|
|
81
83
|
# def cleanup_view_runtime
|
82
84
|
# super - time_taken_in_something_expensive
|
83
85
|
# end
|
84
|
-
#
|
85
|
-
# :api: plugin
|
86
|
-
def cleanup_view_runtime
|
86
|
+
def cleanup_view_runtime # :doc:
|
87
87
|
yield
|
88
88
|
end
|
89
89
|
|
90
90
|
# Every time after an action is processed, this method is invoked
|
91
91
|
# with the payload, so you can add more information.
|
92
|
-
# :
|
93
|
-
def append_info_to_payload(payload)
|
92
|
+
def append_info_to_payload(payload) # :doc:
|
94
93
|
payload[:view_runtime] = view_runtime
|
95
94
|
end
|
96
95
|
|
@@ -98,7 +97,6 @@ module ActionController
|
|
98
97
|
# A hook which allows other frameworks to log what happened during
|
99
98
|
# controller process action. This method should return an array
|
100
99
|
# with the messages to be added.
|
101
|
-
# :api: plugin
|
102
100
|
def log_process_action(payload) #:nodoc:
|
103
101
|
messages, view_runtime = [], payload[:view_runtime]
|
104
102
|
messages << ("Views: %.1fms" % view_runtime.to_f) if view_runtime
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "action_dispatch/http/response"
|
2
4
|
require "delegate"
|
3
5
|
require "active_support/json"
|
@@ -295,7 +297,7 @@ module ActionController
|
|
295
297
|
return unless logger
|
296
298
|
|
297
299
|
logger.fatal do
|
298
|
-
message = "\n#{exception.class} (#{exception.message}):\n"
|
300
|
+
message = "\n#{exception.class} (#{exception.message}):\n".dup
|
299
301
|
message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code)
|
300
302
|
message << " " << exception.backtrace.join("\n ")
|
301
303
|
"#{message}\n\n"
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "abstract_controller/collector"
|
2
4
|
|
3
5
|
module ActionController #:nodoc:
|
@@ -182,7 +184,7 @@ module ActionController #:nodoc:
|
|
182
184
|
# request.variant = [:tablet, :phone]
|
183
185
|
#
|
184
186
|
# This will work similarly to formats and MIME types negotiation. If there
|
185
|
-
# is no +:tablet+ variant declared, +:phone+ variant will be
|
187
|
+
# is no +:tablet+ variant declared, the +:phone+ variant will be used:
|
186
188
|
#
|
187
189
|
# respond_to do |format|
|
188
190
|
# format.html.none
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/hash/slice"
|
2
4
|
require "active_support/core_ext/hash/except"
|
3
5
|
require "active_support/core_ext/module/anonymous"
|
@@ -110,6 +112,14 @@ module ActionController
|
|
110
112
|
else
|
111
113
|
self.include = m.attribute_names
|
112
114
|
end
|
115
|
+
|
116
|
+
if m.respond_to?(:nested_attributes_options) && m.nested_attributes_options.keys.any?
|
117
|
+
self.include += m.nested_attributes_options.keys.map do |key|
|
118
|
+
key.to_s.concat("_attributes")
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
self.include
|
113
123
|
end
|
114
124
|
end
|
115
125
|
end
|
@@ -159,8 +169,7 @@ module ActionController
|
|
159
169
|
end
|
160
170
|
|
161
171
|
included do
|
162
|
-
class_attribute :_wrapper_options
|
163
|
-
self._wrapper_options = Options.from_hash(format: [])
|
172
|
+
class_attribute :_wrapper_options, default: Options.from_hash(format: [])
|
164
173
|
end
|
165
174
|
|
166
175
|
module ClassMethods
|
@@ -233,12 +242,7 @@ module ActionController
|
|
233
242
|
# by the metal call stack.
|
234
243
|
def process_action(*args)
|
235
244
|
if _wrapper_enabled?
|
236
|
-
|
237
|
-
wrapped_hash = _extract_parameters(request.parameters)
|
238
|
-
else
|
239
|
-
wrapped_hash = _wrap_parameters request.request_parameters
|
240
|
-
end
|
241
|
-
|
245
|
+
wrapped_hash = _wrap_parameters request.request_parameters
|
242
246
|
wrapped_keys = request.request_parameters.keys
|
243
247
|
wrapped_filtered_hash = _wrap_parameters request.filtered_parameters.slice(*wrapped_keys)
|
244
248
|
|
@@ -283,7 +287,7 @@ module ActionController
|
|
283
287
|
return false unless request.has_content_type?
|
284
288
|
|
285
289
|
ref = request.content_mime_type.ref
|
286
|
-
_wrapper_formats.include?(ref) && _wrapper_key && !request.
|
290
|
+
_wrapper_formats.include?(ref) && _wrapper_key && !request.parameters.key?(_wrapper_key)
|
287
291
|
end
|
288
292
|
end
|
289
293
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActionController
|
2
4
|
module Redirecting
|
3
5
|
extend ActiveSupport::Concern
|
@@ -29,7 +31,7 @@ module ActionController
|
|
29
31
|
# redirect_to post_url(@post), status: 301
|
30
32
|
# redirect_to action: 'atom', status: 302
|
31
33
|
#
|
32
|
-
# The status code can either be a standard {HTTP Status code}[
|
34
|
+
# The status code can either be a standard {HTTP Status code}[https://www.iana.org/assignments/http-status-codes] as an
|
33
35
|
# integer, or a symbol representing the downcased, underscored and symbolized description.
|
34
36
|
# Note that the status code must be a 3xx HTTP code, or redirection will not occur.
|
35
37
|
#
|
@@ -66,7 +68,7 @@ module ActionController
|
|
66
68
|
# if possible, otherwise redirects to the provided default fallback
|
67
69
|
# location.
|
68
70
|
#
|
69
|
-
# The referrer information is pulled from the HTTP
|
71
|
+
# The referrer information is pulled from the HTTP +Referer+ (sic) header on
|
70
72
|
# the request. This is an optional header and its presence on the request is
|
71
73
|
# subject to browser security settings and user preferences. If the request
|
72
74
|
# is missing this header, the <tt>fallback_location</tt> will be used.
|
@@ -77,15 +79,18 @@ module ActionController
|
|
77
79
|
# redirect_back fallback_location: "/images/screenshot.jpg"
|
78
80
|
# redirect_back fallback_location: posts_url
|
79
81
|
# redirect_back fallback_location: proc { edit_post_url(@post) }
|
82
|
+
# redirect_back fallback_location: '/', allow_other_host: false
|
83
|
+
#
|
84
|
+
# ==== Options
|
85
|
+
# * <tt>:fallback_location</tt> - The default fallback location that will be used on missing +Referer+ header.
|
86
|
+
# * <tt>:allow_other_host</tt> - Allows or disallow redirection to the host that is different to the current host
|
80
87
|
#
|
81
|
-
# All options that can be passed to <tt>redirect_to</tt> are accepted as
|
88
|
+
# All other options that can be passed to <tt>redirect_to</tt> are accepted as
|
82
89
|
# options and the behavior is identical.
|
83
|
-
def redirect_back(fallback_location:, **args)
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
redirect_to fallback_location, **args
|
88
|
-
end
|
90
|
+
def redirect_back(fallback_location:, allow_other_host: true, **args)
|
91
|
+
referer = request.headers["Referer"]
|
92
|
+
redirect_to_referer = referer && (allow_other_host || _url_host_allowed?(referer))
|
93
|
+
redirect_to redirect_to_referer ? referer : fallback_location, **args
|
89
94
|
end
|
90
95
|
|
91
96
|
def _compute_redirect_to_location(request, options) #:nodoc:
|
@@ -93,7 +98,7 @@ module ActionController
|
|
93
98
|
# The scheme name consist of a letter followed by any combination of
|
94
99
|
# letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
|
95
100
|
# characters; and is terminated by a colon (":").
|
96
|
-
# See
|
101
|
+
# See https://tools.ietf.org/html/rfc3986#section-3.1
|
97
102
|
# The protocol relative scheme starts with a double slash "//".
|
98
103
|
when /\A([a-z][a-z\d\-+\.]*:|\/\/).*/i
|
99
104
|
options
|
@@ -118,5 +123,11 @@ module ActionController
|
|
118
123
|
302
|
119
124
|
end
|
120
125
|
end
|
126
|
+
|
127
|
+
def _url_host_allowed?(url)
|
128
|
+
URI(url.to_s).host == request.host
|
129
|
+
rescue ArgumentError, URI::Error
|
130
|
+
false
|
131
|
+
end
|
121
132
|
end
|
122
133
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "set"
|
2
4
|
|
3
5
|
module ActionController
|
@@ -26,8 +28,7 @@ module ActionController
|
|
26
28
|
RENDERERS = Set.new
|
27
29
|
|
28
30
|
included do
|
29
|
-
class_attribute :_renderers
|
30
|
-
self._renderers = Set.new.freeze
|
31
|
+
class_attribute :_renderers, default: Set.new.freeze
|
31
32
|
end
|
32
33
|
|
33
34
|
# Used in <tt>ActionController::Base</tt>
|
@@ -84,7 +85,7 @@ module ActionController
|
|
84
85
|
def self.remove(key)
|
85
86
|
RENDERERS.delete(key.to_sym)
|
86
87
|
method_name = _render_with_renderer_method_name(key)
|
87
|
-
|
88
|
+
remove_possible_method(method_name)
|
88
89
|
end
|
89
90
|
|
90
91
|
def self._render_with_renderer_method_name(key)
|