actionpack 5.2.1 → 7.0.2.4
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 +4 -4
- data/CHANGELOG.md +264 -220
- data/MIT-LICENSE +1 -1
- data/README.rdoc +6 -6
- data/lib/abstract_controller/asset_paths.rb +1 -1
- data/lib/abstract_controller/base.rb +24 -4
- data/lib/abstract_controller/caching/fragments.rb +8 -24
- data/lib/abstract_controller/caching.rb +2 -2
- data/lib/abstract_controller/callbacks.rb +34 -8
- data/lib/abstract_controller/collector.rb +5 -4
- data/lib/abstract_controller/error.rb +1 -1
- data/lib/abstract_controller/helpers.rb +107 -90
- data/lib/abstract_controller/logger.rb +1 -1
- data/lib/abstract_controller/railties/routes_helpers.rb +19 -1
- data/lib/abstract_controller/rendering.rb +9 -9
- data/lib/abstract_controller/translation.rb +12 -5
- data/lib/abstract_controller/url_for.rb +4 -6
- data/lib/abstract_controller.rb +2 -0
- data/lib/action_controller/api.rb +5 -4
- data/lib/action_controller/base.rb +6 -9
- data/lib/action_controller/caching.rb +1 -3
- data/lib/action_controller/log_subscriber.rb +13 -9
- data/lib/action_controller/metal/basic_implicit_render.rb +1 -1
- data/lib/action_controller/metal/conditional_get.rb +57 -6
- data/lib/action_controller/metal/content_security_policy.rb +2 -3
- data/lib/action_controller/metal/cookies.rb +4 -2
- data/lib/action_controller/metal/data_streaming.rb +9 -18
- data/lib/action_controller/metal/default_headers.rb +17 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +4 -6
- data/lib/action_controller/metal/exceptions.rb +55 -12
- data/lib/action_controller/metal/flash.rb +10 -6
- data/lib/action_controller/metal/head.rb +7 -4
- data/lib/action_controller/metal/helpers.rb +15 -6
- data/lib/action_controller/metal/http_authentication.rb +41 -39
- data/lib/action_controller/metal/implicit_render.rb +5 -15
- data/lib/action_controller/metal/instrumentation.rb +59 -55
- data/lib/action_controller/metal/live.rb +80 -33
- data/lib/action_controller/metal/logging.rb +20 -0
- data/lib/action_controller/metal/mime_responds.rb +22 -7
- data/lib/action_controller/metal/parameter_encoding.rb +35 -4
- data/lib/action_controller/metal/params_wrapper.rb +50 -31
- data/lib/action_controller/metal/permissions_policy.rb +46 -0
- data/lib/action_controller/metal/redirecting.rb +93 -23
- data/lib/action_controller/metal/renderers.rb +4 -4
- data/lib/action_controller/metal/rendering.rb +14 -9
- data/lib/action_controller/metal/request_forgery_protection.rb +160 -58
- data/lib/action_controller/metal/rescue.rb +2 -2
- data/lib/action_controller/metal/streaming.rb +1 -4
- data/lib/action_controller/metal/strong_parameters.rb +236 -88
- data/lib/action_controller/metal/testing.rb +9 -2
- data/lib/action_controller/metal/url_for.rb +1 -1
- data/lib/action_controller/metal.rb +16 -17
- data/lib/action_controller/railtie.rb +49 -6
- data/lib/action_controller/railties/helpers.rb +1 -1
- data/lib/action_controller/renderer.rb +37 -13
- data/lib/action_controller/template_assertions.rb +1 -1
- data/lib/action_controller/test_case.rb +98 -68
- data/lib/action_controller.rb +4 -5
- data/lib/action_dispatch/http/cache.rb +45 -32
- data/lib/action_dispatch/http/content_disposition.rb +45 -0
- data/lib/action_dispatch/http/content_security_policy.rb +69 -56
- data/lib/action_dispatch/http/filter_parameters.rb +14 -8
- data/lib/action_dispatch/http/filter_redirect.rb +2 -3
- data/lib/action_dispatch/http/headers.rb +4 -4
- data/lib/action_dispatch/http/mime_negotiation.rb +44 -16
- data/lib/action_dispatch/http/mime_type.rb +47 -30
- data/lib/action_dispatch/http/parameters.rb +18 -27
- data/lib/action_dispatch/http/permissions_policy.rb +173 -0
- data/lib/action_dispatch/http/request.rb +49 -35
- data/lib/action_dispatch/http/response.rb +34 -26
- data/lib/action_dispatch/http/upload.rb +9 -1
- data/lib/action_dispatch/http/url.rb +86 -94
- data/lib/action_dispatch/journey/formatter.rb +55 -31
- data/lib/action_dispatch/journey/gtg/builder.rb +30 -46
- data/lib/action_dispatch/journey/gtg/simulator.rb +15 -8
- data/lib/action_dispatch/journey/gtg/transition_table.rb +78 -21
- data/lib/action_dispatch/journey/nfa/dot.rb +0 -11
- data/lib/action_dispatch/journey/nodes/node.rb +83 -16
- data/lib/action_dispatch/journey/parser.rb +13 -13
- data/lib/action_dispatch/journey/parser.y +1 -1
- data/lib/action_dispatch/journey/path/pattern.rb +42 -34
- data/lib/action_dispatch/journey/route.rb +14 -31
- data/lib/action_dispatch/journey/router/utils.rb +16 -14
- data/lib/action_dispatch/journey/router.rb +27 -35
- data/lib/action_dispatch/journey/routes.rb +3 -5
- data/lib/action_dispatch/journey/scanner.rb +10 -4
- data/lib/action_dispatch/journey/visitors.rb +1 -4
- data/lib/action_dispatch/journey/visualizer/fsm.js +49 -24
- data/lib/action_dispatch/journey/visualizer/index.html.erb +1 -1
- data/lib/action_dispatch/journey.rb +0 -2
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +45 -0
- data/lib/action_dispatch/middleware/callbacks.rb +2 -4
- data/lib/action_dispatch/middleware/cookies.rb +136 -113
- data/lib/action_dispatch/middleware/debug_exceptions.rb +47 -68
- data/lib/action_dispatch/middleware/debug_locks.rb +8 -8
- data/lib/action_dispatch/middleware/debug_view.rb +66 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +79 -30
- data/lib/action_dispatch/middleware/executor.rb +4 -1
- data/lib/action_dispatch/middleware/flash.rb +10 -12
- data/lib/action_dispatch/middleware/host_authorization.rb +159 -0
- data/lib/action_dispatch/middleware/public_exceptions.rb +6 -3
- data/lib/action_dispatch/middleware/remote_ip.rb +30 -20
- data/lib/action_dispatch/middleware/request_id.rb +5 -6
- data/lib/action_dispatch/middleware/server_timing.rb +33 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +16 -3
- data/lib/action_dispatch/middleware/session/cache_store.rb +11 -6
- data/lib/action_dispatch/middleware/session/cookie_store.rb +24 -19
- data/lib/action_dispatch/middleware/show_exceptions.rb +20 -11
- data/lib/action_dispatch/middleware/ssl.rb +20 -15
- data/lib/action_dispatch/middleware/stack.rb +79 -7
- data/lib/action_dispatch/middleware/static.rb +150 -94
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
- data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +6 -11
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +4 -2
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +46 -36
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +8 -0
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +7 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +25 -6
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +9 -6
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +4 -1
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +121 -15
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +5 -5
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +5 -5
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +16 -2
- data/lib/action_dispatch/railtie.rb +16 -4
- data/lib/action_dispatch/request/session.rb +59 -22
- data/lib/action_dispatch/request/utils.rb +28 -2
- data/lib/action_dispatch/routing/inspector.rb +102 -54
- data/lib/action_dispatch/routing/mapper.rb +184 -156
- data/lib/action_dispatch/routing/polymorphic_routes.rb +21 -19
- data/lib/action_dispatch/routing/redirection.rb +4 -6
- data/lib/action_dispatch/routing/route_set.rb +83 -73
- data/lib/action_dispatch/routing/routes_proxy.rb +1 -1
- data/lib/action_dispatch/routing/url_for.rb +2 -3
- data/lib/action_dispatch/routing.rb +23 -22
- data/lib/action_dispatch/system_test_case.rb +65 -16
- data/lib/action_dispatch/system_testing/browser.rb +43 -16
- data/lib/action_dispatch/system_testing/driver.rb +42 -10
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +58 -12
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +3 -10
- data/lib/action_dispatch/testing/assertion_response.rb +0 -1
- data/lib/action_dispatch/testing/assertions/response.rb +4 -7
- data/lib/action_dispatch/testing/assertions/routing.rb +20 -8
- data/lib/action_dispatch/testing/assertions.rb +3 -6
- data/lib/action_dispatch/testing/integration.rb +61 -30
- data/lib/action_dispatch/testing/request_encoder.rb +2 -2
- data/lib/action_dispatch/testing/test_process.rb +8 -6
- data/lib/action_dispatch/testing/test_request.rb +3 -3
- data/lib/action_dispatch/testing/test_response.rb +4 -32
- data/lib/action_dispatch.rb +15 -7
- data/lib/action_pack/gem_version.rb +4 -4
- data/lib/action_pack.rb +1 -1
- metadata +44 -25
- data/lib/action_controller/metal/force_ssl.rb +0 -99
- data/lib/action_dispatch/http/parameter_filter.rb +0 -86
- data/lib/action_dispatch/journey/nfa/builder.rb +0 -78
- data/lib/action_dispatch/journey/nfa/simulator.rb +0 -49
- data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -120
- data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +0 -26
@@ -2,10 +2,17 @@
|
|
2
2
|
|
3
3
|
module ActionController
|
4
4
|
module Testing
|
5
|
-
extend ActiveSupport::Concern
|
6
|
-
|
7
5
|
# Behavior specific to functional tests
|
8
6
|
module Functional # :nodoc:
|
7
|
+
def clear_instance_variables_between_requests
|
8
|
+
if defined?(@_ivars)
|
9
|
+
new_ivars = instance_variables - @_ivars
|
10
|
+
new_ivars.each { |ivar| remove_instance_variable(ivar) }
|
11
|
+
end
|
12
|
+
|
13
|
+
@_ivars = instance_variables
|
14
|
+
end
|
15
|
+
|
9
16
|
def recycle!
|
10
17
|
@_url_options = nil
|
11
18
|
self.formats = nil
|
@@ -44,7 +44,7 @@ module ActionController
|
|
44
44
|
options[:original_script_name] = original_script_name
|
45
45
|
else
|
46
46
|
if same_origin
|
47
|
-
options[:script_name] = request.script_name.empty? ? ""
|
47
|
+
options[:script_name] = request.script_name.empty? ? "" : request.script_name.dup
|
48
48
|
else
|
49
49
|
options[:script_name] = script_name
|
50
50
|
end
|
@@ -2,8 +2,6 @@
|
|
2
2
|
|
3
3
|
require "active_support/core_ext/array/extract_options"
|
4
4
|
require "action_dispatch/middleware/stack"
|
5
|
-
require "action_dispatch/http/request"
|
6
|
-
require "action_dispatch/http/response"
|
7
5
|
|
8
6
|
module ActionController
|
9
7
|
# Extend ActionDispatch middleware stack to make it aware of options
|
@@ -13,8 +11,8 @@ module ActionController
|
|
13
11
|
# use AuthenticationMiddleware, except: [:index, :show]
|
14
12
|
# end
|
15
13
|
#
|
16
|
-
class MiddlewareStack < ActionDispatch::MiddlewareStack
|
17
|
-
class Middleware < ActionDispatch::MiddlewareStack::Middleware
|
14
|
+
class MiddlewareStack < ActionDispatch::MiddlewareStack # :nodoc:
|
15
|
+
class Middleware < ActionDispatch::MiddlewareStack::Middleware # :nodoc:
|
18
16
|
def initialize(klass, args, actions, strategy, block)
|
19
17
|
@actions = actions
|
20
18
|
@strategy = strategy
|
@@ -26,16 +24,15 @@ module ActionController
|
|
26
24
|
end
|
27
25
|
end
|
28
26
|
|
29
|
-
def build(action, app =
|
27
|
+
def build(action, app = nil, &block)
|
30
28
|
action = action.to_s
|
31
29
|
|
32
|
-
middlewares.reverse.inject(app) do |a, middleware|
|
30
|
+
middlewares.reverse.inject(app || block) do |a, middleware|
|
33
31
|
middleware.valid?(action) ? middleware.build(a) : a
|
34
32
|
end
|
35
33
|
end
|
36
34
|
|
37
35
|
private
|
38
|
-
|
39
36
|
INCLUDE = ->(list, action) { list.include? action }
|
40
37
|
EXCLUDE = ->(list, action) { !list.include? action }
|
41
38
|
NULL = ->(list, action) { true }
|
@@ -127,7 +124,7 @@ module ActionController
|
|
127
124
|
# ==== Returns
|
128
125
|
# * <tt>string</tt>
|
129
126
|
def self.controller_name
|
130
|
-
@controller_name ||= name.demodulize.
|
127
|
+
@controller_name ||= (name.demodulize.delete_suffix("Controller").underscore unless anonymous?)
|
131
128
|
end
|
132
129
|
|
133
130
|
def self.make_response!(request)
|
@@ -136,7 +133,7 @@ module ActionController
|
|
136
133
|
end
|
137
134
|
end
|
138
135
|
|
139
|
-
def self.
|
136
|
+
def self.action_encoding_template(action) # :nodoc:
|
140
137
|
false
|
141
138
|
end
|
142
139
|
|
@@ -148,7 +145,7 @@ module ActionController
|
|
148
145
|
attr_internal :response, :request
|
149
146
|
delegate :session, to: "@_request"
|
150
147
|
delegate :headers, :status=, :location=, :content_type=,
|
151
|
-
:status, :location, :content_type, to: "@_response"
|
148
|
+
:status, :location, :content_type, :media_type, to: "@_response"
|
152
149
|
|
153
150
|
def initialize
|
154
151
|
@_request = nil
|
@@ -185,7 +182,7 @@ module ActionController
|
|
185
182
|
response_body || response.committed?
|
186
183
|
end
|
187
184
|
|
188
|
-
def dispatch(name, request, response)
|
185
|
+
def dispatch(name, request, response) # :nodoc:
|
189
186
|
set_request!(request)
|
190
187
|
set_response!(response)
|
191
188
|
process(name)
|
@@ -197,12 +194,12 @@ module ActionController
|
|
197
194
|
@_response = response
|
198
195
|
end
|
199
196
|
|
200
|
-
def set_request!(request)
|
197
|
+
def set_request!(request) # :nodoc:
|
201
198
|
@_request = request
|
202
199
|
@_request.controller_instance = self
|
203
200
|
end
|
204
201
|
|
205
|
-
def to_a
|
202
|
+
def to_a # :nodoc:
|
206
203
|
response.to_a
|
207
204
|
end
|
208
205
|
|
@@ -217,10 +214,12 @@ module ActionController
|
|
217
214
|
super
|
218
215
|
end
|
219
216
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
217
|
+
class << self
|
218
|
+
# Pushes the given Rack middleware and its arguments to the bottom of the
|
219
|
+
# middleware stack.
|
220
|
+
def use(...)
|
221
|
+
middleware_stack.use(...)
|
222
|
+
end
|
224
223
|
end
|
225
224
|
|
226
225
|
# Alias for +middleware_stack+.
|
@@ -8,8 +8,11 @@ require "action_controller/railties/helpers"
|
|
8
8
|
require "action_view/railtie"
|
9
9
|
|
10
10
|
module ActionController
|
11
|
-
class Railtie < Rails::Railtie
|
11
|
+
class Railtie < Rails::Railtie # :nodoc:
|
12
12
|
config.action_controller = ActiveSupport::OrderedOptions.new
|
13
|
+
config.action_controller.raise_on_open_redirects = false
|
14
|
+
config.action_controller.log_query_tags_around_actions = true
|
15
|
+
config.action_controller.wrap_parameters_by_default = false
|
13
16
|
|
14
17
|
config.eager_load_namespaces << ActionController
|
15
18
|
|
@@ -25,14 +28,19 @@ module ActionController
|
|
25
28
|
options = app.config.action_controller
|
26
29
|
|
27
30
|
ActiveSupport.on_load(:action_controller, run_once: true) do
|
28
|
-
ActionController::Parameters.permit_all_parameters = options.
|
31
|
+
ActionController::Parameters.permit_all_parameters = options.permit_all_parameters || false
|
29
32
|
if app.config.action_controller[:always_permitted_parameters]
|
30
33
|
ActionController::Parameters.always_permitted_parameters =
|
31
|
-
app.config.action_controller.
|
34
|
+
app.config.action_controller.always_permitted_parameters
|
32
35
|
end
|
33
|
-
|
34
|
-
|
36
|
+
|
37
|
+
action_on_unpermitted_parameters = options.action_on_unpermitted_parameters
|
38
|
+
|
39
|
+
if action_on_unpermitted_parameters.nil?
|
40
|
+
action_on_unpermitted_parameters = (Rails.env.test? || Rails.env.development?) ? :log : false
|
35
41
|
end
|
42
|
+
|
43
|
+
ActionController::Parameters.action_on_unpermitted_parameters = action_on_unpermitted_parameters
|
36
44
|
end
|
37
45
|
end
|
38
46
|
|
@@ -55,7 +63,18 @@ module ActionController
|
|
55
63
|
extend ::AbstractController::Railties::RoutesHelpers.with(app.routes)
|
56
64
|
extend ::ActionController::Railties::Helpers
|
57
65
|
|
58
|
-
options.
|
66
|
+
wrap_parameters format: [:json] if options.wrap_parameters_by_default && respond_to?(:wrap_parameters)
|
67
|
+
|
68
|
+
# Configs used in other initializers
|
69
|
+
filtered_options = options.except(
|
70
|
+
:log_query_tags_around_actions,
|
71
|
+
:permit_all_parameters,
|
72
|
+
:action_on_unpermitted_parameters,
|
73
|
+
:always_permitted_parameters,
|
74
|
+
:wrap_parameters_by_default
|
75
|
+
)
|
76
|
+
|
77
|
+
filtered_options.each do |k, v|
|
59
78
|
k = "#{k}="
|
60
79
|
if respond_to?(k)
|
61
80
|
send(k, v)
|
@@ -85,5 +104,29 @@ module ActionController
|
|
85
104
|
ActionController::Metal.descendants.each(&:action_methods) if config.eager_load
|
86
105
|
end
|
87
106
|
end
|
107
|
+
|
108
|
+
initializer "action_controller.query_log_tags" do |app|
|
109
|
+
query_logs_tags_enabled = app.config.respond_to?(:active_record) &&
|
110
|
+
app.config.active_record.query_log_tags_enabled &&
|
111
|
+
app.config.action_controller.log_query_tags_around_actions
|
112
|
+
|
113
|
+
if query_logs_tags_enabled
|
114
|
+
app.config.active_record.query_log_tags += [:controller, :action]
|
115
|
+
|
116
|
+
ActiveSupport.on_load(:active_record) do
|
117
|
+
ActiveRecord::QueryLogs.taggings.merge!(
|
118
|
+
controller: ->(context) { context[:controller]&.controller_name },
|
119
|
+
action: ->(context) { context[:controller]&.action_name },
|
120
|
+
namespaced_controller: ->(context) { context[:controller].class.name if context[:controller] }
|
121
|
+
)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
initializer "action_controller.test_case" do |app|
|
127
|
+
ActiveSupport.on_load(:action_controller_test_case) do
|
128
|
+
ActionController::TestCase.executor_around_each_request = app.config.active_support.executor_around_test_case
|
129
|
+
end
|
130
|
+
end
|
88
131
|
end
|
89
132
|
end
|
@@ -7,7 +7,7 @@ module ActionController
|
|
7
7
|
super
|
8
8
|
return unless klass.respond_to?(:helpers_path=)
|
9
9
|
|
10
|
-
if namespace = klass.
|
10
|
+
if namespace = klass.module_parents.detect { |m| m.respond_to?(:railtie_helpers_paths) }
|
11
11
|
paths = namespace.railtie_helpers_paths
|
12
12
|
else
|
13
13
|
paths = ActionController::Helpers.helpers_path
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/core_ext/hash/keys"
|
4
|
-
|
5
3
|
module ActionController
|
6
4
|
# ActionController::Renderer allows you to render arbitrary templates
|
7
5
|
# without requirement of being in controller actions.
|
@@ -67,10 +65,29 @@ module ActionController
|
|
67
65
|
def initialize(controller, env, defaults)
|
68
66
|
@controller = controller
|
69
67
|
@defaults = defaults
|
70
|
-
@env = normalize_keys defaults
|
68
|
+
@env = normalize_keys defaults, env
|
71
69
|
end
|
72
70
|
|
73
71
|
# Render templates with any options from ActionController::Base#render_to_string.
|
72
|
+
#
|
73
|
+
# The primary options are:
|
74
|
+
# * <tt>:partial</tt> - See <tt>ActionView::PartialRenderer</tt> for details.
|
75
|
+
# * <tt>:file</tt> - Renders an explicit template file. Add <tt>:locals</tt> to pass in, if so desired.
|
76
|
+
# It shouldn’t be used directly with unsanitized user input due to lack of validation.
|
77
|
+
# * <tt>:inline</tt> - Renders an ERB template string.
|
78
|
+
# * <tt>:plain</tt> - Renders provided text and sets the content type as <tt>text/plain</tt>.
|
79
|
+
# * <tt>:html</tt> - Renders the provided HTML safe string, otherwise
|
80
|
+
# performs HTML escape on the string first. Sets the content type as <tt>text/html</tt>.
|
81
|
+
# * <tt>:json</tt> - Renders the provided hash or object in JSON. You don't
|
82
|
+
# need to call <tt>.to_json</tt> on the object you want to render.
|
83
|
+
# * <tt>:body</tt> - Renders provided text and sets content type of <tt>text/plain</tt>.
|
84
|
+
#
|
85
|
+
# If no <tt>options</tt> hash is passed or if <tt>:update</tt> is specified, then:
|
86
|
+
#
|
87
|
+
# If an object responding to +render_in+ is passed, +render_in+ is called on the object,
|
88
|
+
# passing in the current view context.
|
89
|
+
#
|
90
|
+
# Otherwise, a partial is rendered using the second parameter as the locals hash.
|
74
91
|
def render(*args)
|
75
92
|
raise "missing controller" unless controller
|
76
93
|
|
@@ -82,11 +99,18 @@ module ActionController
|
|
82
99
|
instance.set_response! controller.make_response!(request)
|
83
100
|
instance.render_to_string(*args)
|
84
101
|
end
|
102
|
+
alias_method :render_to_string, :render # :nodoc:
|
85
103
|
|
86
104
|
private
|
87
|
-
def normalize_keys(env)
|
105
|
+
def normalize_keys(defaults, env)
|
88
106
|
new_env = {}
|
89
107
|
env.each_pair { |k, v| new_env[rack_key_for(k)] = rack_value_for(k, v) }
|
108
|
+
|
109
|
+
defaults.each_pair do |k, v|
|
110
|
+
key = rack_key_for(k)
|
111
|
+
new_env[key] = rack_value_for(k, v) unless new_env.key?(key)
|
112
|
+
end
|
113
|
+
|
90
114
|
new_env["rack.url_scheme"] = new_env["HTTPS"] == "on" ? "https" : "http"
|
91
115
|
new_env
|
92
116
|
end
|
@@ -99,19 +123,19 @@ module ActionController
|
|
99
123
|
input: "rack.input"
|
100
124
|
}
|
101
125
|
|
102
|
-
IDENTITY = ->(_) { _ }
|
103
|
-
|
104
|
-
RACK_VALUE_TRANSLATION = {
|
105
|
-
https: ->(v) { v ? "on" : "off" },
|
106
|
-
method: ->(v) { v.upcase },
|
107
|
-
}
|
108
|
-
|
109
126
|
def rack_key_for(key)
|
110
|
-
RACK_KEY_TRANSLATION
|
127
|
+
RACK_KEY_TRANSLATION[key] || key.to_s
|
111
128
|
end
|
112
129
|
|
113
130
|
def rack_value_for(key, value)
|
114
|
-
|
131
|
+
case key
|
132
|
+
when :https
|
133
|
+
value ? "on" : "off"
|
134
|
+
when :method
|
135
|
+
-value.upcase
|
136
|
+
else
|
137
|
+
value
|
138
|
+
end
|
115
139
|
end
|
116
140
|
end
|
117
141
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActionController
|
4
|
-
module TemplateAssertions
|
4
|
+
module TemplateAssertions # :nodoc:
|
5
5
|
def assert_template(options = {}, message = nil)
|
6
6
|
raise NoMethodError,
|
7
7
|
"assert_template has been extracted to a gem. To continue using it,
|
@@ -24,11 +24,14 @@ module ActionController
|
|
24
24
|
def new_controller_thread # :nodoc:
|
25
25
|
yield
|
26
26
|
end
|
27
|
+
|
28
|
+
# Avoid a deadlock from the queue filling up
|
29
|
+
Buffer.queue_size = nil
|
27
30
|
end
|
28
31
|
|
29
|
-
# ActionController::TestCase will be deprecated and moved to a gem in
|
32
|
+
# ActionController::TestCase will be deprecated and moved to a gem in the future.
|
30
33
|
# Please use ActionDispatch::IntegrationTest going forward.
|
31
|
-
class TestRequest < ActionDispatch::TestRequest
|
34
|
+
class TestRequest < ActionDispatch::TestRequest # :nodoc:
|
32
35
|
DEFAULT_ENV = ActionDispatch::TestRequest::DEFAULT_ENV.dup
|
33
36
|
DEFAULT_ENV.delete "PATH_INFO"
|
34
37
|
|
@@ -84,7 +87,7 @@ module ActionController
|
|
84
87
|
value = value.to_param
|
85
88
|
end
|
86
89
|
|
87
|
-
path_parameters[key] = value
|
90
|
+
path_parameters[key.to_sym] = value
|
88
91
|
end
|
89
92
|
end
|
90
93
|
|
@@ -158,7 +161,6 @@ module ActionController
|
|
158
161
|
end.new
|
159
162
|
|
160
163
|
private
|
161
|
-
|
162
164
|
def params_parsers
|
163
165
|
super.merge @custom_param_parsers
|
164
166
|
end
|
@@ -177,12 +179,12 @@ module ActionController
|
|
177
179
|
|
178
180
|
# Methods #destroy and #load! are overridden to avoid calling methods on the
|
179
181
|
# @store object, which does not exist for the TestSession class.
|
180
|
-
class TestSession < Rack::Session::Abstract::
|
182
|
+
class TestSession < Rack::Session::Abstract::PersistedSecure::SecureSessionHash # :nodoc:
|
181
183
|
DEFAULT_OPTIONS = Rack::Session::Abstract::Persisted::DEFAULT_OPTIONS
|
182
184
|
|
183
185
|
def initialize(session = {})
|
184
186
|
super(nil, nil)
|
185
|
-
@id = SecureRandom.hex(16)
|
187
|
+
@id = Rack::Session::SessionId.new(SecureRandom.hex(16))
|
186
188
|
@data = stringify_keys(session)
|
187
189
|
@loaded = true
|
188
190
|
end
|
@@ -203,12 +205,20 @@ module ActionController
|
|
203
205
|
clear
|
204
206
|
end
|
205
207
|
|
208
|
+
def dig(*keys)
|
209
|
+
keys = keys.map.with_index { |key, i| i.zero? ? key.to_s : key }
|
210
|
+
@data.dig(*keys)
|
211
|
+
end
|
212
|
+
|
206
213
|
def fetch(key, *args, &block)
|
207
214
|
@data.fetch(key.to_s, *args, &block)
|
208
215
|
end
|
209
216
|
|
210
|
-
|
217
|
+
def enabled?
|
218
|
+
true
|
219
|
+
end
|
211
220
|
|
221
|
+
private
|
212
222
|
def load!
|
213
223
|
@id
|
214
224
|
end
|
@@ -276,9 +286,6 @@ module ActionController
|
|
276
286
|
# after calling +post+. If the various assert methods are not sufficient, then you
|
277
287
|
# may use this object to inspect the HTTP response in detail.
|
278
288
|
#
|
279
|
-
# (Earlier versions of \Rails required each functional test to subclass
|
280
|
-
# Test::Unit::TestCase and define @controller, @request, @response in +setup+.)
|
281
|
-
#
|
282
289
|
# == Controller is automatically inferred
|
283
290
|
#
|
284
291
|
# ActionController::TestCase will automatically infer the controller under test
|
@@ -326,6 +333,8 @@ module ActionController
|
|
326
333
|
#
|
327
334
|
# assert_redirected_to page_url(title: 'foo')
|
328
335
|
class TestCase < ActiveSupport::TestCase
|
336
|
+
singleton_class.attr_accessor :executor_around_each_request
|
337
|
+
|
329
338
|
module Behavior
|
330
339
|
extend ActiveSupport::Concern
|
331
340
|
include ActionDispatch::TestProcess
|
@@ -456,10 +465,17 @@ module ActionController
|
|
456
465
|
# prefer using #get, #post, #patch, #put, #delete and #head methods
|
457
466
|
# respectively which will make tests more expressive.
|
458
467
|
#
|
468
|
+
# It's not recommended to make more than one request in the same test. Instance
|
469
|
+
# variables that are set in one request will not persist to the next request,
|
470
|
+
# but it's not guaranteed that all Rails internal state will be reset. Prefer
|
471
|
+
# ActionDispatch::IntegrationTest for making multiple requests in the same test.
|
472
|
+
#
|
459
473
|
# Note that the request method is not verified.
|
460
|
-
def process(action, method: "GET", params:
|
474
|
+
def process(action, method: "GET", params: nil, session: nil, body: nil, flash: {}, format: nil, xhr: false, as: nil)
|
461
475
|
check_required_ivars
|
476
|
+
@controller.clear_instance_variables_between_requests
|
462
477
|
|
478
|
+
action = +action.to_s
|
463
479
|
http_method = method.to_s.upcase
|
464
480
|
|
465
481
|
@html_document = nil
|
@@ -485,63 +501,14 @@ module ActionController
|
|
485
501
|
format ||= as
|
486
502
|
end
|
487
503
|
|
488
|
-
parameters = params.symbolize_keys
|
504
|
+
parameters = (params || {}).symbolize_keys
|
489
505
|
|
490
506
|
if format
|
491
507
|
parameters[:format] = format
|
492
508
|
end
|
493
509
|
|
494
|
-
|
495
|
-
|
496
|
-
query_string_keys = query_parameter_names(generated_extras)
|
497
|
-
|
498
|
-
@request.assign_parameters(@routes, controller_class_name, action.to_s, parameters, generated_path, query_string_keys)
|
499
|
-
|
500
|
-
@request.session.update(session) if session
|
501
|
-
@request.flash.update(flash || {})
|
502
|
-
|
503
|
-
if xhr
|
504
|
-
@request.set_header "HTTP_X_REQUESTED_WITH", "XMLHttpRequest"
|
505
|
-
@request.fetch_header("HTTP_ACCEPT") do |k|
|
506
|
-
@request.set_header k, [Mime[:js], Mime[:html], Mime[:xml], "text/xml", "*/*"].join(", ")
|
507
|
-
end
|
508
|
-
end
|
509
|
-
|
510
|
-
@request.fetch_header("SCRIPT_NAME") do |k|
|
511
|
-
@request.set_header k, @controller.config.relative_url_root
|
512
|
-
end
|
513
|
-
|
514
|
-
begin
|
515
|
-
@controller.recycle!
|
516
|
-
@controller.dispatch(action, @request, @response)
|
517
|
-
ensure
|
518
|
-
@request = @controller.request
|
519
|
-
@response = @controller.response
|
520
|
-
|
521
|
-
if @request.have_cookie_jar?
|
522
|
-
unless @request.cookie_jar.committed?
|
523
|
-
@request.cookie_jar.write(@response)
|
524
|
-
cookies.update(@request.cookie_jar.instance_variable_get(:@cookies))
|
525
|
-
end
|
526
|
-
end
|
527
|
-
@response.prepare!
|
528
|
-
|
529
|
-
if flash_value = @request.flash.to_session_value
|
530
|
-
@request.session["flash"] = flash_value
|
531
|
-
else
|
532
|
-
@request.session.delete("flash")
|
533
|
-
end
|
534
|
-
|
535
|
-
if xhr
|
536
|
-
@request.delete_header "HTTP_X_REQUESTED_WITH"
|
537
|
-
@request.delete_header "HTTP_ACCEPT"
|
538
|
-
end
|
539
|
-
@request.query_string = ""
|
540
|
-
|
541
|
-
@response.sent!
|
542
|
-
end
|
543
|
-
|
544
|
-
@response
|
510
|
+
setup_request(controller_class_name, action, parameters, session, flash, xhr)
|
511
|
+
process_controller_response(action, cookies, xhr)
|
545
512
|
end
|
546
513
|
|
547
514
|
def controller_class_name
|
@@ -597,12 +564,75 @@ module ActionController
|
|
597
564
|
end
|
598
565
|
|
599
566
|
private
|
567
|
+
def setup_request(controller_class_name, action, parameters, session, flash, xhr)
|
568
|
+
generated_extras = @routes.generate_extras(parameters.merge(controller: controller_class_name, action: action))
|
569
|
+
generated_path = generated_path(generated_extras)
|
570
|
+
query_string_keys = query_parameter_names(generated_extras)
|
571
|
+
|
572
|
+
@request.assign_parameters(@routes, controller_class_name, action, parameters, generated_path, query_string_keys)
|
573
|
+
|
574
|
+
@request.session.update(session) if session
|
575
|
+
@request.flash.update(flash || {})
|
576
|
+
|
577
|
+
if xhr
|
578
|
+
@request.set_header "HTTP_X_REQUESTED_WITH", "XMLHttpRequest"
|
579
|
+
@request.fetch_header("HTTP_ACCEPT") do |k|
|
580
|
+
@request.set_header k, [Mime[:js], Mime[:html], Mime[:xml], "text/xml", "*/*"].join(", ")
|
581
|
+
end
|
582
|
+
end
|
583
|
+
|
584
|
+
@request.fetch_header("SCRIPT_NAME") do |k|
|
585
|
+
@request.set_header k, @controller.config.relative_url_root
|
586
|
+
end
|
587
|
+
end
|
588
|
+
|
589
|
+
def wrap_execution(&block)
|
590
|
+
if ActionController::TestCase.executor_around_each_request && defined?(Rails.application) && Rails.application
|
591
|
+
Rails.application.executor.wrap(&block)
|
592
|
+
else
|
593
|
+
yield
|
594
|
+
end
|
595
|
+
end
|
596
|
+
|
597
|
+
def process_controller_response(action, cookies, xhr)
|
598
|
+
begin
|
599
|
+
@controller.recycle!
|
600
|
+
|
601
|
+
wrap_execution { @controller.dispatch(action, @request, @response) }
|
602
|
+
ensure
|
603
|
+
@request = @controller.request
|
604
|
+
@response = @controller.response
|
605
|
+
|
606
|
+
if @request.have_cookie_jar?
|
607
|
+
unless @request.cookie_jar.committed?
|
608
|
+
@request.cookie_jar.write(@response)
|
609
|
+
cookies.update(@request.cookie_jar.instance_variable_get(:@cookies))
|
610
|
+
end
|
611
|
+
end
|
612
|
+
@response.prepare!
|
613
|
+
|
614
|
+
if flash_value = @request.flash.to_session_value
|
615
|
+
@request.session["flash"] = flash_value
|
616
|
+
else
|
617
|
+
@request.session.delete("flash")
|
618
|
+
end
|
619
|
+
|
620
|
+
if xhr
|
621
|
+
@request.delete_header "HTTP_X_REQUESTED_WITH"
|
622
|
+
@request.delete_header "HTTP_ACCEPT"
|
623
|
+
end
|
624
|
+
@request.query_string = ""
|
625
|
+
|
626
|
+
@response.sent!
|
627
|
+
end
|
628
|
+
|
629
|
+
@response
|
630
|
+
end
|
600
631
|
|
601
632
|
def scrub_env!(env)
|
602
|
-
env.delete_if
|
603
|
-
|
604
|
-
|
605
|
-
env.delete "action_dispatch.request.request_parameters"
|
633
|
+
env.delete_if do |k, _|
|
634
|
+
k.start_with?("rack.request", "action_dispatch.request", "action_dispatch.rescue")
|
635
|
+
end
|
606
636
|
env["rack.input"] = StringIO.new
|
607
637
|
env.delete "CONTENT_LENGTH"
|
608
638
|
env.delete "RAW_POST_DATA"
|
@@ -614,7 +644,7 @@ module ActionController
|
|
614
644
|
end
|
615
645
|
|
616
646
|
def check_required_ivars
|
617
|
-
#
|
647
|
+
# Check for required instance variables so we can give an
|
618
648
|
# understandable error message.
|
619
649
|
[:@routes, :@controller, :@request, :@response].each do |iv_name|
|
620
650
|
if !instance_variable_defined?(iv_name) || instance_variable_get(iv_name).nil?
|
data/lib/action_controller.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/rails"
|
4
3
|
require "abstract_controller"
|
5
4
|
require "action_dispatch"
|
6
|
-
require "action_controller/metal/live"
|
7
5
|
require "action_controller/metal/strong_parameters"
|
8
6
|
|
9
7
|
module ActionController
|
@@ -12,7 +10,6 @@ module ActionController
|
|
12
10
|
autoload :API
|
13
11
|
autoload :Base
|
14
12
|
autoload :Metal
|
15
|
-
autoload :Middleware
|
16
13
|
autoload :Renderer
|
17
14
|
autoload :FormBuilder
|
18
15
|
|
@@ -25,16 +22,19 @@ module ActionController
|
|
25
22
|
autoload :ContentSecurityPolicy
|
26
23
|
autoload :Cookies
|
27
24
|
autoload :DataStreaming
|
25
|
+
autoload :DefaultHeaders
|
28
26
|
autoload :EtagWithTemplateDigest
|
29
27
|
autoload :EtagWithFlash
|
28
|
+
autoload :PermissionsPolicy
|
30
29
|
autoload :Flash
|
31
|
-
autoload :ForceSSL
|
32
30
|
autoload :Head
|
33
31
|
autoload :Helpers
|
34
32
|
autoload :HttpAuthentication
|
35
33
|
autoload :BasicImplicitRender
|
36
34
|
autoload :ImplicitRender
|
37
35
|
autoload :Instrumentation
|
36
|
+
autoload :Live
|
37
|
+
autoload :Logging
|
38
38
|
autoload :MimeResponds
|
39
39
|
autoload :ParamsWrapper
|
40
40
|
autoload :Redirecting
|
@@ -62,5 +62,4 @@ require "active_support/core_ext/module/attribute_accessors"
|
|
62
62
|
require "active_support/core_ext/load_error"
|
63
63
|
require "active_support/core_ext/module/attr_internal"
|
64
64
|
require "active_support/core_ext/name_error"
|
65
|
-
require "active_support/core_ext/uri"
|
66
65
|
require "active_support/inflector"
|