actionpack 7.0.4 → 7.1.3.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 +397 -269
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -4
- data/lib/abstract_controller/base.rb +20 -11
- data/lib/abstract_controller/caching/fragments.rb +2 -0
- data/lib/abstract_controller/callbacks.rb +31 -6
- data/lib/abstract_controller/deprecator.rb +7 -0
- data/lib/abstract_controller/helpers.rb +75 -28
- data/lib/abstract_controller/railties/routes_helpers.rb +1 -16
- data/lib/abstract_controller/rendering.rb +12 -14
- data/lib/abstract_controller/translation.rb +9 -6
- data/lib/abstract_controller/url_for.rb +2 -0
- data/lib/abstract_controller.rb +6 -0
- data/lib/action_controller/api.rb +6 -4
- data/lib/action_controller/base.rb +3 -17
- data/lib/action_controller/caching.rb +2 -0
- data/lib/action_controller/deprecator.rb +7 -0
- data/lib/action_controller/form_builder.rb +2 -0
- data/lib/action_controller/log_subscriber.rb +16 -4
- data/lib/action_controller/metal/basic_implicit_render.rb +3 -1
- data/lib/action_controller/metal/conditional_get.rb +121 -123
- data/lib/action_controller/metal/content_security_policy.rb +5 -5
- data/lib/action_controller/metal/data_streaming.rb +20 -18
- data/lib/action_controller/metal/default_headers.rb +2 -0
- data/lib/action_controller/metal/etag_with_flash.rb +3 -1
- data/lib/action_controller/metal/etag_with_template_digest.rb +2 -0
- data/lib/action_controller/metal/exceptions.rb +8 -0
- data/lib/action_controller/metal/head.rb +9 -7
- data/lib/action_controller/metal/helpers.rb +3 -14
- data/lib/action_controller/metal/http_authentication.rb +17 -8
- data/lib/action_controller/metal/implicit_render.rb +5 -3
- data/lib/action_controller/metal/instrumentation.rb +8 -1
- data/lib/action_controller/metal/live.rb +25 -1
- data/lib/action_controller/metal/mime_responds.rb +2 -2
- data/lib/action_controller/metal/params_wrapper.rb +4 -2
- data/lib/action_controller/metal/permissions_policy.rb +2 -2
- data/lib/action_controller/metal/redirecting.rb +29 -8
- data/lib/action_controller/metal/renderers.rb +4 -4
- data/lib/action_controller/metal/rendering.rb +114 -9
- data/lib/action_controller/metal/request_forgery_protection.rb +144 -53
- data/lib/action_controller/metal/rescue.rb +6 -3
- data/lib/action_controller/metal/streaming.rb +71 -31
- data/lib/action_controller/metal/strong_parameters.rb +158 -101
- data/lib/action_controller/metal/url_for.rb +9 -4
- data/lib/action_controller/metal.rb +79 -21
- data/lib/action_controller/railtie.rb +24 -10
- data/lib/action_controller/renderer.rb +99 -85
- data/lib/action_controller/test_case.rb +15 -5
- data/lib/action_controller.rb +8 -1
- data/lib/action_dispatch/constants.rb +32 -0
- data/lib/action_dispatch/deprecator.rb +7 -0
- data/lib/action_dispatch/http/cache.rb +9 -11
- data/lib/action_dispatch/http/content_security_policy.rb +14 -9
- data/lib/action_dispatch/http/filter_parameters.rb +14 -28
- data/lib/action_dispatch/http/headers.rb +3 -1
- data/lib/action_dispatch/http/mime_negotiation.rb +22 -22
- data/lib/action_dispatch/http/mime_type.rb +35 -12
- data/lib/action_dispatch/http/mime_types.rb +3 -1
- data/lib/action_dispatch/http/parameters.rb +1 -1
- data/lib/action_dispatch/http/permissions_policy.rb +38 -23
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +63 -30
- data/lib/action_dispatch/http/response.rb +80 -63
- data/lib/action_dispatch/http/upload.rb +15 -2
- data/lib/action_dispatch/journey/formatter.rb +8 -2
- data/lib/action_dispatch/journey/path/pattern.rb +14 -14
- data/lib/action_dispatch/journey/route.rb +3 -2
- data/lib/action_dispatch/journey/router.rb +9 -8
- data/lib/action_dispatch/journey/routes.rb +2 -2
- data/lib/action_dispatch/log_subscriber.rb +23 -0
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +5 -6
- data/lib/action_dispatch/middleware/assume_ssl.rb +24 -0
- data/lib/action_dispatch/middleware/callbacks.rb +2 -0
- data/lib/action_dispatch/middleware/cookies.rb +108 -117
- data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -25
- data/lib/action_dispatch/middleware/debug_locks.rb +4 -1
- data/lib/action_dispatch/middleware/debug_view.rb +7 -2
- data/lib/action_dispatch/middleware/exception_wrapper.rb +186 -27
- data/lib/action_dispatch/middleware/executor.rb +1 -1
- data/lib/action_dispatch/middleware/flash.rb +7 -0
- data/lib/action_dispatch/middleware/host_authorization.rb +18 -8
- data/lib/action_dispatch/middleware/public_exceptions.rb +5 -3
- data/lib/action_dispatch/middleware/reloader.rb +7 -5
- data/lib/action_dispatch/middleware/remote_ip.rb +21 -20
- data/lib/action_dispatch/middleware/request_id.rb +4 -2
- data/lib/action_dispatch/middleware/server_timing.rb +4 -4
- data/lib/action_dispatch/middleware/session/abstract_store.rb +5 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +2 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +11 -5
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +3 -1
- data/lib/action_dispatch/middleware/show_exceptions.rb +25 -18
- data/lib/action_dispatch/middleware/ssl.rb +18 -6
- data/lib/action_dispatch/middleware/stack.rb +7 -2
- data/lib/action_dispatch/middleware/static.rb +14 -10
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +8 -1
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -3
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -3
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +7 -7
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +17 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +16 -12
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +3 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +59 -41
- data/lib/action_dispatch/railtie.rb +14 -4
- data/lib/action_dispatch/request/session.rb +16 -6
- data/lib/action_dispatch/request/utils.rb +8 -3
- data/lib/action_dispatch/routing/inspector.rb +54 -6
- data/lib/action_dispatch/routing/mapper.rb +58 -24
- data/lib/action_dispatch/routing/polymorphic_routes.rb +2 -0
- data/lib/action_dispatch/routing/redirection.rb +15 -6
- data/lib/action_dispatch/routing/route_set.rb +52 -22
- data/lib/action_dispatch/routing/routes_proxy.rb +10 -15
- data/lib/action_dispatch/routing/url_for.rb +26 -22
- data/lib/action_dispatch/routing.rb +7 -7
- data/lib/action_dispatch/system_test_case.rb +3 -3
- data/lib/action_dispatch/system_testing/browser.rb +20 -19
- data/lib/action_dispatch/system_testing/driver.rb +14 -22
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +27 -16
- data/lib/action_dispatch/testing/assertion_response.rb +1 -1
- data/lib/action_dispatch/testing/assertions/response.rb +14 -7
- data/lib/action_dispatch/testing/assertions/routing.rb +67 -28
- data/lib/action_dispatch/testing/assertions.rb +3 -1
- data/lib/action_dispatch/testing/integration.rb +27 -17
- data/lib/action_dispatch/testing/request_encoder.rb +4 -1
- data/lib/action_dispatch/testing/test_process.rb +4 -3
- data/lib/action_dispatch/testing/test_request.rb +1 -1
- data/lib/action_dispatch/testing/test_response.rb +23 -9
- data/lib/action_dispatch.rb +37 -4
- data/lib/action_pack/gem_version.rb +4 -4
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_pack.rb +1 -1
- metadata +65 -29
@@ -4,6 +4,8 @@ require "active_support/core_ext/array/extract_options"
|
|
4
4
|
require "action_dispatch/middleware/stack"
|
5
5
|
|
6
6
|
module ActionController
|
7
|
+
# = Action Controller \MiddlewareStack
|
8
|
+
#
|
7
9
|
# Extend ActionDispatch middleware stack to make it aware of options
|
8
10
|
# allowing the following syntax in controllers:
|
9
11
|
#
|
@@ -58,7 +60,9 @@ module ActionController
|
|
58
60
|
end
|
59
61
|
end
|
60
62
|
|
61
|
-
#
|
63
|
+
# = Action Controller \Metal
|
64
|
+
#
|
65
|
+
# +ActionController::Metal+ is the simplest possible controller, providing a
|
62
66
|
# valid Rack interface without the additional niceties provided by
|
63
67
|
# ActionController::Base.
|
64
68
|
#
|
@@ -78,9 +82,9 @@ module ActionController
|
|
78
82
|
# The +action+ method returns a valid Rack application for the \Rails
|
79
83
|
# router to dispatch to.
|
80
84
|
#
|
81
|
-
# == Rendering Helpers
|
85
|
+
# == \Rendering \Helpers
|
82
86
|
#
|
83
|
-
#
|
87
|
+
# +ActionController::Metal+ by default provides no utilities for rendering
|
84
88
|
# views, partials, or other responses aside from explicitly calling of
|
85
89
|
# <tt>response_body=</tt>, <tt>content_type=</tt>, and <tt>status=</tt>. To
|
86
90
|
# add the render helpers you're used to having in a normal controller, you
|
@@ -96,7 +100,7 @@ module ActionController
|
|
96
100
|
# end
|
97
101
|
# end
|
98
102
|
#
|
99
|
-
# == Redirection Helpers
|
103
|
+
# == Redirection \Helpers
|
100
104
|
#
|
101
105
|
# To add redirection helpers to your metal controller, do the following:
|
102
106
|
#
|
@@ -109,7 +113,7 @@ module ActionController
|
|
109
113
|
# end
|
110
114
|
# end
|
111
115
|
#
|
112
|
-
# == Other Helpers
|
116
|
+
# == Other \Helpers
|
113
117
|
#
|
114
118
|
# You can refer to the modules included in ActionController::Base to see
|
115
119
|
# other features you can bring into your metal controller.
|
@@ -118,8 +122,8 @@ module ActionController
|
|
118
122
|
abstract!
|
119
123
|
|
120
124
|
# Returns the last part of the controller's name, underscored, without the ending
|
121
|
-
# <tt>Controller</tt>. For instance, PostsController returns <tt>posts</tt>.
|
122
|
-
# Namespaces are left out, so Admin::PostsController returns <tt>posts</tt> as well.
|
125
|
+
# <tt>Controller</tt>. For instance, +PostsController+ returns <tt>posts</tt>.
|
126
|
+
# Namespaces are left out, so +Admin::PostsController+ returns <tt>posts</tt> as well.
|
123
127
|
#
|
124
128
|
# ==== Returns
|
125
129
|
# * <tt>string</tt>
|
@@ -137,20 +141,53 @@ module ActionController
|
|
137
141
|
false
|
138
142
|
end
|
139
143
|
|
144
|
+
class << self
|
145
|
+
private
|
146
|
+
def inherited(subclass)
|
147
|
+
super
|
148
|
+
subclass.middleware_stack = middleware_stack.dup
|
149
|
+
subclass.class_eval do
|
150
|
+
@controller_name = nil
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
140
155
|
# Delegates to the class's ::controller_name.
|
141
156
|
def controller_name
|
142
157
|
self.class.controller_name
|
143
158
|
end
|
144
159
|
|
145
|
-
|
160
|
+
##
|
161
|
+
# :attr_reader: request
|
162
|
+
#
|
163
|
+
# The ActionDispatch::Request instance for the current request.
|
164
|
+
attr_internal :request
|
165
|
+
|
166
|
+
##
|
167
|
+
# :attr_reader: response
|
168
|
+
#
|
169
|
+
# The ActionDispatch::Response instance for the current response.
|
170
|
+
attr_internal_reader :response
|
171
|
+
|
172
|
+
##
|
173
|
+
# The ActionDispatch::Request::Session instance for the current request.
|
174
|
+
# See further details in the
|
175
|
+
# {Active Controller Session guide}[https://guides.rubyonrails.org/action_controller_overview.html#session].
|
146
176
|
delegate :session, to: "@_request"
|
147
|
-
|
177
|
+
|
178
|
+
##
|
179
|
+
# Delegates to ActionDispatch::Response#headers.
|
180
|
+
delegate :headers, to: "@_response"
|
181
|
+
|
182
|
+
delegate :status=, :location=, :content_type=,
|
148
183
|
:status, :location, :content_type, :media_type, to: "@_response"
|
149
184
|
|
150
185
|
def initialize
|
151
186
|
@_request = nil
|
152
187
|
@_response = nil
|
188
|
+
@_response_body = nil
|
153
189
|
@_routes = nil
|
190
|
+
@_params = nil
|
154
191
|
super
|
155
192
|
end
|
156
193
|
|
@@ -164,17 +201,19 @@ module ActionController
|
|
164
201
|
|
165
202
|
alias :response_code :status # :nodoc:
|
166
203
|
|
167
|
-
# Basic url_for that can be overridden for more robust functionality.
|
204
|
+
# Basic \url_for that can be overridden for more robust functionality.
|
168
205
|
def url_for(string)
|
169
206
|
string
|
170
207
|
end
|
171
208
|
|
172
209
|
def response_body=(body)
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
210
|
+
if body
|
211
|
+
body = [body] if body.is_a?(String)
|
212
|
+
response.body = body
|
213
|
+
super
|
214
|
+
else
|
215
|
+
response.reset_body!
|
216
|
+
end
|
178
217
|
end
|
179
218
|
|
180
219
|
# Tests if render or redirect has already happened.
|
@@ -191,9 +230,22 @@ module ActionController
|
|
191
230
|
end
|
192
231
|
|
193
232
|
def set_response!(response) # :nodoc:
|
233
|
+
if @_response
|
234
|
+
_, _, body = @_response
|
235
|
+
body.close if body.respond_to?(:close)
|
236
|
+
end
|
237
|
+
|
194
238
|
@_response = response
|
195
239
|
end
|
196
240
|
|
241
|
+
# Assign the response and mark it as committed. No further processing will occur.
|
242
|
+
def response=(response)
|
243
|
+
set_response!(response)
|
244
|
+
|
245
|
+
# Force `performed?` to return true:
|
246
|
+
@_response_body = true
|
247
|
+
end
|
248
|
+
|
197
249
|
def set_request!(request) # :nodoc:
|
198
250
|
@_request = request
|
199
251
|
@_request.controller_instance = self
|
@@ -209,11 +261,6 @@ module ActionController
|
|
209
261
|
|
210
262
|
class_attribute :middleware_stack, default: ActionController::MiddlewareStack.new
|
211
263
|
|
212
|
-
def self.inherited(base) # :nodoc:
|
213
|
-
base.middleware_stack = middleware_stack.dup
|
214
|
-
super
|
215
|
-
end
|
216
|
-
|
217
264
|
class << self
|
218
265
|
# Pushes the given Rack middleware and its arguments to the bottom of the
|
219
266
|
# middleware stack.
|
@@ -222,7 +269,18 @@ module ActionController
|
|
222
269
|
end
|
223
270
|
end
|
224
271
|
|
225
|
-
#
|
272
|
+
# The middleware stack used by this controller.
|
273
|
+
#
|
274
|
+
# By default uses a variation of ActionDispatch::MiddlewareStack which
|
275
|
+
# allows for the following syntax:
|
276
|
+
#
|
277
|
+
# class PostsController < ApplicationController
|
278
|
+
# use AuthenticationMiddleware, except: [:index, :show]
|
279
|
+
# end
|
280
|
+
#
|
281
|
+
# Read more about {Rails middleware
|
282
|
+
# stack}[https://guides.rubyonrails.org/rails_on_rack.html#action-dispatcher-middleware-stack]
|
283
|
+
# in the guides.
|
226
284
|
def self.middleware
|
227
285
|
middleware_stack
|
228
286
|
end
|
@@ -14,8 +14,13 @@ module ActionController
|
|
14
14
|
config.action_controller.log_query_tags_around_actions = true
|
15
15
|
config.action_controller.wrap_parameters_by_default = false
|
16
16
|
|
17
|
+
config.eager_load_namespaces << AbstractController
|
17
18
|
config.eager_load_namespaces << ActionController
|
18
19
|
|
20
|
+
initializer "action_controller.deprecator", before: :load_environment_config do |app|
|
21
|
+
app.deprecators[:action_controller] = ActionController.deprecator
|
22
|
+
end
|
23
|
+
|
19
24
|
initializer "action_controller.assets_config", group: :all do |app|
|
20
25
|
app.config.action_controller.assets_dir ||= app.config.paths["public"].first
|
21
26
|
end
|
@@ -37,10 +42,15 @@ module ActionController
|
|
37
42
|
action_on_unpermitted_parameters = options.action_on_unpermitted_parameters
|
38
43
|
|
39
44
|
if action_on_unpermitted_parameters.nil?
|
40
|
-
action_on_unpermitted_parameters =
|
45
|
+
action_on_unpermitted_parameters = Rails.env.local? ? :log : false
|
41
46
|
end
|
42
47
|
|
43
48
|
ActionController::Parameters.action_on_unpermitted_parameters = action_on_unpermitted_parameters
|
49
|
+
|
50
|
+
unless options.allow_deprecated_parameters_hash_equality.nil?
|
51
|
+
ActionController::Parameters.allow_deprecated_parameters_hash_equality =
|
52
|
+
options.allow_deprecated_parameters_hash_equality
|
53
|
+
end
|
44
54
|
end
|
45
55
|
end
|
46
56
|
|
@@ -71,7 +81,8 @@ module ActionController
|
|
71
81
|
:permit_all_parameters,
|
72
82
|
:action_on_unpermitted_parameters,
|
73
83
|
:always_permitted_parameters,
|
74
|
-
:wrap_parameters_by_default
|
84
|
+
:wrap_parameters_by_default,
|
85
|
+
:allow_deprecated_parameters_hash_equality
|
75
86
|
)
|
76
87
|
|
77
88
|
filtered_options.each do |k, v|
|
@@ -99,25 +110,28 @@ module ActionController
|
|
99
110
|
end
|
100
111
|
end
|
101
112
|
|
102
|
-
initializer "action_controller.eager_load_actions" do
|
103
|
-
ActiveSupport.on_load(:after_initialize) do
|
104
|
-
ActionController::Metal.descendants.each(&:action_methods) if config.eager_load
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
113
|
initializer "action_controller.query_log_tags" do |app|
|
109
114
|
query_logs_tags_enabled = app.config.respond_to?(:active_record) &&
|
110
115
|
app.config.active_record.query_log_tags_enabled &&
|
111
116
|
app.config.action_controller.log_query_tags_around_actions
|
112
117
|
|
113
118
|
if query_logs_tags_enabled
|
114
|
-
app.config.active_record.query_log_tags
|
119
|
+
app.config.active_record.query_log_tags |= [:controller] unless app.config.active_record.query_log_tags.include?(:namespaced_controller)
|
120
|
+
app.config.active_record.query_log_tags |= [:action]
|
115
121
|
|
116
122
|
ActiveSupport.on_load(:active_record) do
|
117
123
|
ActiveRecord::QueryLogs.taggings.merge!(
|
118
124
|
controller: ->(context) { context[:controller]&.controller_name },
|
119
125
|
action: ->(context) { context[:controller]&.action_name },
|
120
|
-
namespaced_controller: ->(context) {
|
126
|
+
namespaced_controller: ->(context) {
|
127
|
+
if context[:controller]
|
128
|
+
controller_class = context[:controller].class
|
129
|
+
# based on ActionController::Metal#controller_name, but does not demodulize
|
130
|
+
unless controller_class.anonymous?
|
131
|
+
controller_class.name.delete_suffix("Controller").underscore
|
132
|
+
end
|
133
|
+
end
|
134
|
+
}
|
121
135
|
)
|
122
136
|
end
|
123
137
|
end
|
@@ -1,97 +1,127 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActionController
|
4
|
-
#
|
5
|
-
# without requirement of being in controller actions.
|
4
|
+
# = Action Controller \Renderer
|
6
5
|
#
|
7
|
-
#
|
8
|
-
#
|
6
|
+
# ActionController::Renderer allows you to render arbitrary templates without
|
7
|
+
# being inside a controller action.
|
9
8
|
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
# It allows you to call method #render directly.
|
13
|
-
#
|
14
|
-
# ApplicationController.renderer.render template: '...'
|
15
|
-
#
|
16
|
-
# You can use this shortcut in a controller, instead of the previous example:
|
17
|
-
#
|
18
|
-
# ApplicationController.render template: '...'
|
19
|
-
#
|
20
|
-
# #render allows you to use the same options that you can use when rendering in a controller.
|
21
|
-
# For example:
|
9
|
+
# You can get a renderer instance by calling +renderer+ on a controller class:
|
22
10
|
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
# The template will be rendered in a Rack environment which is accessible through
|
26
|
-
# ActionController::Renderer#env. You can set it up in two ways:
|
11
|
+
# ApplicationController.renderer
|
12
|
+
# PostsController.renderer
|
27
13
|
#
|
28
|
-
#
|
14
|
+
# and render a template by calling the #render method:
|
29
15
|
#
|
30
|
-
#
|
16
|
+
# ApplicationController.renderer.render template: "posts/show", assigns: { post: Post.first }
|
17
|
+
# PostsController.renderer.render :show, assigns: { post: Post.first }
|
31
18
|
#
|
32
|
-
#
|
19
|
+
# As a shortcut, you can also call +render+ directly on the controller class itself:
|
33
20
|
#
|
34
|
-
#
|
21
|
+
# ApplicationController.render template: "posts/show", assigns: { post: Post.first }
|
22
|
+
# PostsController.render :show, assigns: { post: Post.first }
|
35
23
|
#
|
36
24
|
class Renderer
|
37
|
-
attr_reader :
|
25
|
+
attr_reader :controller
|
38
26
|
|
39
27
|
DEFAULTS = {
|
40
|
-
http_host: "example.org",
|
41
|
-
https: false,
|
42
28
|
method: "get",
|
43
|
-
script_name: "",
|
44
29
|
input: ""
|
45
30
|
}.freeze
|
46
31
|
|
47
|
-
|
48
|
-
|
32
|
+
def self.normalize_env(env) # :nodoc:
|
33
|
+
new_env = {}
|
34
|
+
|
35
|
+
env.each_pair do |key, value|
|
36
|
+
case key
|
37
|
+
when :https
|
38
|
+
value = value ? "on" : "off"
|
39
|
+
when :method
|
40
|
+
value = -value.upcase
|
41
|
+
end
|
42
|
+
|
43
|
+
key = RACK_KEY_TRANSLATION[key] || key.to_s
|
44
|
+
|
45
|
+
new_env[key] = value
|
46
|
+
end
|
47
|
+
|
48
|
+
if new_env["HTTP_HOST"]
|
49
|
+
new_env["HTTPS"] ||= "off"
|
50
|
+
new_env["SCRIPT_NAME"] ||= ""
|
51
|
+
end
|
52
|
+
|
53
|
+
if new_env["HTTPS"]
|
54
|
+
new_env["rack.url_scheme"] = new_env["HTTPS"] == "on" ? "https" : "http"
|
55
|
+
end
|
56
|
+
|
57
|
+
new_env
|
58
|
+
end
|
59
|
+
|
60
|
+
# Creates a new renderer using the given controller class. See ::new.
|
61
|
+
def self.for(controller, env = nil, defaults = DEFAULTS)
|
49
62
|
new(controller, env, defaults)
|
50
63
|
end
|
51
64
|
|
52
|
-
#
|
53
|
-
|
54
|
-
|
65
|
+
# Creates a new renderer using the same controller, but with a new Rack env.
|
66
|
+
#
|
67
|
+
# ApplicationController.renderer.new(method: "post")
|
68
|
+
#
|
69
|
+
def new(env = nil)
|
70
|
+
self.class.new controller, env, @defaults
|
55
71
|
end
|
56
72
|
|
57
|
-
#
|
73
|
+
# Creates a new renderer using the same controller, but with the given
|
74
|
+
# defaults merged on top of the previous defaults.
|
58
75
|
def with_defaults(defaults)
|
59
|
-
self.class.new controller, @env,
|
76
|
+
self.class.new controller, @env, @defaults.merge(defaults)
|
60
77
|
end
|
61
78
|
|
62
|
-
#
|
63
|
-
#
|
64
|
-
#
|
79
|
+
# Initializes a new Renderer.
|
80
|
+
#
|
81
|
+
# ==== Parameters
|
82
|
+
#
|
83
|
+
# * +controller+ - The controller class to instantiate for rendering.
|
84
|
+
# * +env+ - The Rack env to use for mocking a request when rendering.
|
85
|
+
# Entries can be typical Rack env keys and values, or they can be any of
|
86
|
+
# the following, which will be converted appropriately:
|
87
|
+
# * +:http_host+ - The HTTP host for the incoming request. Converts to
|
88
|
+
# Rack's +HTTP_HOST+.
|
89
|
+
# * +:https+ - Boolean indicating whether the incoming request uses HTTPS.
|
90
|
+
# Converts to Rack's +HTTPS+.
|
91
|
+
# * +:method+ - The HTTP method for the incoming request, case-insensitive.
|
92
|
+
# Converts to Rack's +REQUEST_METHOD+.
|
93
|
+
# * +:script_name+ - The portion of the incoming request's URL path that
|
94
|
+
# corresponds to the application. Converts to Rack's +SCRIPT_NAME+.
|
95
|
+
# * +:input+ - The input stream. Converts to Rack's +rack.input+.
|
96
|
+
# * +defaults+ - Default values for the Rack env. Entries are specified in
|
97
|
+
# the same format as +env+. +env+ will be merged on top of these values.
|
98
|
+
# +defaults+ will be retained when calling #new on a renderer instance.
|
99
|
+
#
|
100
|
+
# If no +http_host+ is specified, the env HTTP host will be derived from the
|
101
|
+
# routes' +default_url_options+. In this case, the +https+ boolean and the
|
102
|
+
# +script_name+ will also be derived from +default_url_options+ if they were
|
103
|
+
# not specified. Additionally, the +https+ boolean will fall back to
|
104
|
+
# +Rails.application.config.force_ssl+ if +default_url_options+ does not
|
105
|
+
# specify a +protocol+.
|
65
106
|
def initialize(controller, env, defaults)
|
66
107
|
@controller = controller
|
67
108
|
@defaults = defaults
|
68
|
-
|
109
|
+
if env.blank? && @defaults == DEFAULTS
|
110
|
+
@env = DEFAULT_ENV
|
111
|
+
else
|
112
|
+
@env = normalize_env(@defaults)
|
113
|
+
@env.merge!(normalize_env(env)) unless env.blank?
|
114
|
+
end
|
69
115
|
end
|
70
116
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
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.
|
91
|
-
def render(*args)
|
92
|
-
raise "missing controller" unless controller
|
117
|
+
def defaults
|
118
|
+
@defaults = @defaults.dup if @defaults.frozen?
|
119
|
+
@defaults
|
120
|
+
end
|
93
121
|
|
94
|
-
|
122
|
+
# Renders a template to a string, just like ActionController::Rendering#render_to_string.
|
123
|
+
def render(*args)
|
124
|
+
request = ActionDispatch::Request.new(env_for_request)
|
95
125
|
request.routes = controller._routes
|
96
126
|
|
97
127
|
instance = controller.new
|
@@ -102,19 +132,6 @@ module ActionController
|
|
102
132
|
alias_method :render_to_string, :render # :nodoc:
|
103
133
|
|
104
134
|
private
|
105
|
-
def normalize_keys(defaults, env)
|
106
|
-
new_env = {}
|
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
|
-
|
114
|
-
new_env["rack.url_scheme"] = new_env["HTTPS"] == "on" ? "https" : "http"
|
115
|
-
new_env
|
116
|
-
end
|
117
|
-
|
118
135
|
RACK_KEY_TRANSLATION = {
|
119
136
|
http_host: "HTTP_HOST",
|
120
137
|
https: "HTTPS",
|
@@ -123,18 +140,15 @@ module ActionController
|
|
123
140
|
input: "rack.input"
|
124
141
|
}
|
125
142
|
|
126
|
-
|
127
|
-
RACK_KEY_TRANSLATION[key] || key.to_s
|
128
|
-
end
|
143
|
+
DEFAULT_ENV = normalize_env(DEFAULTS).freeze # :nodoc:
|
129
144
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
-value.upcase
|
145
|
+
delegate :normalize_env, to: :class
|
146
|
+
|
147
|
+
def env_for_request
|
148
|
+
if @env.key?("HTTP_HOST") || controller._routes.nil?
|
149
|
+
@env.dup
|
136
150
|
else
|
137
|
-
|
151
|
+
controller._routes.default_env.merge(@env)
|
138
152
|
end
|
139
153
|
end
|
140
154
|
end
|
@@ -127,6 +127,9 @@ module ActionController
|
|
127
127
|
fetch_header("PATH_INFO") do |k|
|
128
128
|
set_header k, generated_path
|
129
129
|
end
|
130
|
+
fetch_header("ORIGINAL_FULLPATH") do |k|
|
131
|
+
set_header k, fullpath
|
132
|
+
end
|
130
133
|
path_parameters[:controller] = controller_path
|
131
134
|
path_parameters[:action] = action
|
132
135
|
|
@@ -182,11 +185,12 @@ module ActionController
|
|
182
185
|
class TestSession < Rack::Session::Abstract::PersistedSecure::SecureSessionHash # :nodoc:
|
183
186
|
DEFAULT_OPTIONS = Rack::Session::Abstract::Persisted::DEFAULT_OPTIONS
|
184
187
|
|
185
|
-
def initialize(session = {})
|
188
|
+
def initialize(session = {}, id = Rack::Session::SessionId.new(SecureRandom.hex(16)))
|
186
189
|
super(nil, nil)
|
187
|
-
@id =
|
190
|
+
@id = id
|
188
191
|
@data = stringify_keys(session)
|
189
192
|
@loaded = true
|
193
|
+
@initially_empty = @data.empty?
|
190
194
|
end
|
191
195
|
|
192
196
|
def exists?
|
@@ -218,21 +222,27 @@ module ActionController
|
|
218
222
|
true
|
219
223
|
end
|
220
224
|
|
225
|
+
def id_was
|
226
|
+
@id
|
227
|
+
end
|
228
|
+
|
221
229
|
private
|
222
230
|
def load!
|
223
231
|
@id
|
224
232
|
end
|
225
233
|
end
|
226
234
|
|
235
|
+
# = Action Controller Test Case
|
236
|
+
#
|
227
237
|
# Superclass for ActionController functional tests. Functional tests allow you to
|
228
238
|
# test a single controller action per test method.
|
229
239
|
#
|
230
240
|
# == Use integration style controller tests over functional style controller tests.
|
231
241
|
#
|
232
|
-
# Rails discourages the use of functional tests in favor of integration tests
|
242
|
+
# \Rails discourages the use of functional tests in favor of integration tests
|
233
243
|
# (use ActionDispatch::IntegrationTest).
|
234
244
|
#
|
235
|
-
# New Rails applications no longer generate functional style controller tests and they should
|
245
|
+
# New \Rails applications no longer generate functional style controller tests and they should
|
236
246
|
# only be used for backward compatibility. Integration style controller tests perform actual
|
237
247
|
# requests, whereas functional style controller tests merely simulate a request. Besides,
|
238
248
|
# integration tests are as fast as functional tests and provide lot of helpers such as +as+,
|
@@ -467,7 +477,7 @@ module ActionController
|
|
467
477
|
#
|
468
478
|
# It's not recommended to make more than one request in the same test. Instance
|
469
479
|
# 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
|
480
|
+
# but it's not guaranteed that all \Rails internal state will be reset. Prefer
|
471
481
|
# ActionDispatch::IntegrationTest for making multiple requests in the same test.
|
472
482
|
#
|
473
483
|
# Note that the request method is not verified.
|
data/lib/action_controller.rb
CHANGED
@@ -2,9 +2,17 @@
|
|
2
2
|
|
3
3
|
require "abstract_controller"
|
4
4
|
require "action_dispatch"
|
5
|
+
require "action_controller/deprecator"
|
5
6
|
require "action_controller/metal/strong_parameters"
|
6
7
|
require "action_controller/metal/exceptions"
|
7
8
|
|
9
|
+
# = Action Controller
|
10
|
+
#
|
11
|
+
# Action Controller is a module of Action Pack.
|
12
|
+
#
|
13
|
+
# Action Controller provides a base controller class that can be subclassed to
|
14
|
+
# implement filters and actions to handle requests. The result of an action is
|
15
|
+
# typically content generated from views.
|
8
16
|
module ActionController
|
9
17
|
extend ActiveSupport::Autoload
|
10
18
|
|
@@ -60,7 +68,6 @@ end
|
|
60
68
|
|
61
69
|
# Common Active Support usage in Action Controller
|
62
70
|
require "active_support/core_ext/module/attribute_accessors"
|
63
|
-
require "active_support/core_ext/load_error"
|
64
71
|
require "active_support/core_ext/module/attr_internal"
|
65
72
|
require "active_support/core_ext/name_error"
|
66
73
|
require "active_support/inflector"
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rack/version"
|
4
|
+
|
5
|
+
module ActionDispatch
|
6
|
+
module Constants
|
7
|
+
# Response Header keys for Rack 2.x and 3.x
|
8
|
+
if Gem::Version.new(Rack::RELEASE) < Gem::Version.new("3")
|
9
|
+
VARY = "Vary"
|
10
|
+
CONTENT_ENCODING = "Content-Encoding"
|
11
|
+
CONTENT_SECURITY_POLICY = "Content-Security-Policy"
|
12
|
+
CONTENT_SECURITY_POLICY_REPORT_ONLY = "Content-Security-Policy-Report-Only"
|
13
|
+
LOCATION = "Location"
|
14
|
+
FEATURE_POLICY = "Feature-Policy"
|
15
|
+
X_REQUEST_ID = "X-Request-Id"
|
16
|
+
X_CASCADE = "X-Cascade"
|
17
|
+
SERVER_TIMING = "Server-Timing"
|
18
|
+
STRICT_TRANSPORT_SECURITY = "Strict-Transport-Security"
|
19
|
+
else
|
20
|
+
VARY = "vary"
|
21
|
+
CONTENT_ENCODING = "content-encoding"
|
22
|
+
CONTENT_SECURITY_POLICY = "content-security-policy"
|
23
|
+
CONTENT_SECURITY_POLICY_REPORT_ONLY = "content-security-policy-report-only"
|
24
|
+
LOCATION = "location"
|
25
|
+
FEATURE_POLICY = "feature-policy"
|
26
|
+
X_REQUEST_ID = "x-request-id"
|
27
|
+
X_CASCADE = "x-cascade"
|
28
|
+
SERVER_TIMING = "server-timing"
|
29
|
+
STRICT_TRANSPORT_SECURITY = "strict-transport-security"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|