actionpack 4.2.11.1 → 5.2.4.3

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.

Files changed (166) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +287 -488
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +6 -7
  5. data/lib/abstract_controller/asset_paths.rb +2 -0
  6. data/lib/abstract_controller/base.rb +45 -49
  7. data/lib/{action_controller → abstract_controller}/caching/fragments.rb +78 -15
  8. data/lib/abstract_controller/caching.rb +66 -0
  9. data/lib/abstract_controller/callbacks.rb +47 -31
  10. data/lib/abstract_controller/collector.rb +8 -11
  11. data/lib/abstract_controller/error.rb +6 -0
  12. data/lib/abstract_controller/helpers.rb +25 -25
  13. data/lib/abstract_controller/logger.rb +2 -0
  14. data/lib/abstract_controller/railties/routes_helpers.rb +4 -2
  15. data/lib/abstract_controller/rendering.rb +42 -41
  16. data/lib/abstract_controller/translation.rb +10 -7
  17. data/lib/abstract_controller/url_for.rb +2 -0
  18. data/lib/abstract_controller.rb +12 -5
  19. data/lib/action_controller/api/api_rendering.rb +16 -0
  20. data/lib/action_controller/api.rb +149 -0
  21. data/lib/action_controller/base.rb +27 -19
  22. data/lib/action_controller/caching.rb +14 -57
  23. data/lib/action_controller/form_builder.rb +50 -0
  24. data/lib/action_controller/log_subscriber.rb +10 -15
  25. data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
  26. data/lib/action_controller/metal/conditional_get.rb +118 -44
  27. data/lib/action_controller/metal/content_security_policy.rb +52 -0
  28. data/lib/action_controller/metal/cookies.rb +3 -3
  29. data/lib/action_controller/metal/data_streaming.rb +27 -46
  30. data/lib/action_controller/metal/etag_with_flash.rb +18 -0
  31. data/lib/action_controller/metal/etag_with_template_digest.rb +20 -13
  32. data/lib/action_controller/metal/exceptions.rb +8 -14
  33. data/lib/action_controller/metal/flash.rb +4 -3
  34. data/lib/action_controller/metal/force_ssl.rb +23 -21
  35. data/lib/action_controller/metal/head.rb +21 -19
  36. data/lib/action_controller/metal/helpers.rb +24 -14
  37. data/lib/action_controller/metal/http_authentication.rb +64 -57
  38. data/lib/action_controller/metal/implicit_render.rb +62 -8
  39. data/lib/action_controller/metal/instrumentation.rb +19 -21
  40. data/lib/action_controller/metal/live.rb +90 -106
  41. data/lib/action_controller/metal/mime_responds.rb +33 -46
  42. data/lib/action_controller/metal/parameter_encoding.rb +51 -0
  43. data/lib/action_controller/metal/params_wrapper.rb +61 -53
  44. data/lib/action_controller/metal/redirecting.rb +49 -28
  45. data/lib/action_controller/metal/renderers.rb +87 -44
  46. data/lib/action_controller/metal/rendering.rb +72 -50
  47. data/lib/action_controller/metal/request_forgery_protection.rb +229 -93
  48. data/lib/action_controller/metal/rescue.rb +9 -16
  49. data/lib/action_controller/metal/streaming.rb +12 -10
  50. data/lib/action_controller/metal/strong_parameters.rb +583 -164
  51. data/lib/action_controller/metal/testing.rb +2 -17
  52. data/lib/action_controller/metal/url_for.rb +19 -10
  53. data/lib/action_controller/metal.rb +98 -83
  54. data/lib/action_controller/railtie.rb +28 -10
  55. data/lib/action_controller/railties/helpers.rb +2 -0
  56. data/lib/action_controller/renderer.rb +117 -0
  57. data/lib/action_controller/template_assertions.rb +11 -0
  58. data/lib/action_controller/test_case.rb +280 -411
  59. data/lib/action_controller.rb +29 -21
  60. data/lib/action_dispatch/http/cache.rb +93 -47
  61. data/lib/action_dispatch/http/content_security_policy.rb +272 -0
  62. data/lib/action_dispatch/http/filter_parameters.rb +26 -20
  63. data/lib/action_dispatch/http/filter_redirect.rb +10 -11
  64. data/lib/action_dispatch/http/headers.rb +55 -22
  65. data/lib/action_dispatch/http/mime_negotiation.rb +56 -41
  66. data/lib/action_dispatch/http/mime_type.rb +134 -121
  67. data/lib/action_dispatch/http/mime_types.rb +20 -6
  68. data/lib/action_dispatch/http/parameter_filter.rb +25 -11
  69. data/lib/action_dispatch/http/parameters.rb +98 -39
  70. data/lib/action_dispatch/http/rack_cache.rb +2 -0
  71. data/lib/action_dispatch/http/request.rb +200 -118
  72. data/lib/action_dispatch/http/response.rb +225 -110
  73. data/lib/action_dispatch/http/upload.rb +12 -6
  74. data/lib/action_dispatch/http/url.rb +110 -28
  75. data/lib/action_dispatch/journey/formatter.rb +55 -32
  76. data/lib/action_dispatch/journey/gtg/builder.rb +7 -5
  77. data/lib/action_dispatch/journey/gtg/simulator.rb +3 -9
  78. data/lib/action_dispatch/journey/gtg/transition_table.rb +17 -16
  79. data/lib/action_dispatch/journey/nfa/builder.rb +5 -3
  80. data/lib/action_dispatch/journey/nfa/dot.rb +13 -13
  81. data/lib/action_dispatch/journey/nfa/simulator.rb +3 -1
  82. data/lib/action_dispatch/journey/nfa/transition_table.rb +5 -48
  83. data/lib/action_dispatch/journey/nodes/node.rb +18 -6
  84. data/lib/action_dispatch/journey/parser.rb +23 -22
  85. data/lib/action_dispatch/journey/parser.y +3 -2
  86. data/lib/action_dispatch/journey/parser_extras.rb +12 -4
  87. data/lib/action_dispatch/journey/path/pattern.rb +50 -44
  88. data/lib/action_dispatch/journey/route.rb +106 -28
  89. data/lib/action_dispatch/journey/router/utils.rb +20 -11
  90. data/lib/action_dispatch/journey/router.rb +35 -23
  91. data/lib/action_dispatch/journey/routes.rb +18 -16
  92. data/lib/action_dispatch/journey/scanner.rb +18 -15
  93. data/lib/action_dispatch/journey/visitors.rb +99 -52
  94. data/lib/action_dispatch/journey.rb +7 -5
  95. data/lib/action_dispatch/middleware/callbacks.rb +1 -2
  96. data/lib/action_dispatch/middleware/cookies.rb +304 -193
  97. data/lib/action_dispatch/middleware/debug_exceptions.rb +152 -57
  98. data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
  99. data/lib/action_dispatch/middleware/exception_wrapper.rb +68 -69
  100. data/lib/action_dispatch/middleware/executor.rb +21 -0
  101. data/lib/action_dispatch/middleware/flash.rb +78 -54
  102. data/lib/action_dispatch/middleware/public_exceptions.rb +27 -25
  103. data/lib/action_dispatch/middleware/reloader.rb +5 -91
  104. data/lib/action_dispatch/middleware/remote_ip.rb +41 -31
  105. data/lib/action_dispatch/middleware/request_id.rb +17 -9
  106. data/lib/action_dispatch/middleware/session/abstract_store.rb +41 -25
  107. data/lib/action_dispatch/middleware/session/cache_store.rb +24 -14
  108. data/lib/action_dispatch/middleware/session/cookie_store.rb +72 -67
  109. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -2
  110. data/lib/action_dispatch/middleware/show_exceptions.rb +26 -22
  111. data/lib/action_dispatch/middleware/ssl.rb +114 -36
  112. data/lib/action_dispatch/middleware/stack.rb +31 -44
  113. data/lib/action_dispatch/middleware/static.rb +57 -50
  114. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +2 -14
  115. data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +0 -0
  116. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  117. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +21 -0
  118. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +13 -0
  119. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +1 -0
  120. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -1
  121. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
  122. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +4 -4
  123. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +64 -64
  124. data/lib/action_dispatch/railtie.rb +19 -11
  125. data/lib/action_dispatch/request/session.rb +106 -59
  126. data/lib/action_dispatch/request/utils.rb +67 -24
  127. data/lib/action_dispatch/routing/endpoint.rb +9 -2
  128. data/lib/action_dispatch/routing/inspector.rb +58 -67
  129. data/lib/action_dispatch/routing/mapper.rb +733 -447
  130. data/lib/action_dispatch/routing/polymorphic_routes.rb +161 -139
  131. data/lib/action_dispatch/routing/redirection.rb +36 -26
  132. data/lib/action_dispatch/routing/route_set.rb +321 -291
  133. data/lib/action_dispatch/routing/routes_proxy.rb +32 -5
  134. data/lib/action_dispatch/routing/url_for.rb +65 -25
  135. data/lib/action_dispatch/routing.rb +17 -18
  136. data/lib/action_dispatch/system_test_case.rb +147 -0
  137. data/lib/action_dispatch/system_testing/browser.rb +49 -0
  138. data/lib/action_dispatch/system_testing/driver.rb +59 -0
  139. data/lib/action_dispatch/system_testing/server.rb +31 -0
  140. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +96 -0
  141. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +31 -0
  142. data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +26 -0
  143. data/lib/action_dispatch/testing/assertion_response.rb +47 -0
  144. data/lib/action_dispatch/testing/assertions/response.rb +45 -20
  145. data/lib/action_dispatch/testing/assertions/routing.rb +30 -26
  146. data/lib/action_dispatch/testing/assertions.rb +6 -4
  147. data/lib/action_dispatch/testing/integration.rb +347 -209
  148. data/lib/action_dispatch/testing/request_encoder.rb +55 -0
  149. data/lib/action_dispatch/testing/test_process.rb +28 -22
  150. data/lib/action_dispatch/testing/test_request.rb +27 -34
  151. data/lib/action_dispatch/testing/test_response.rb +35 -7
  152. data/lib/action_dispatch.rb +27 -19
  153. data/lib/action_pack/gem_version.rb +5 -3
  154. data/lib/action_pack/version.rb +3 -1
  155. data/lib/action_pack.rb +4 -2
  156. metadata +56 -38
  157. data/lib/action_controller/metal/hide_actions.rb +0 -40
  158. data/lib/action_controller/metal/rack_delegation.rb +0 -32
  159. data/lib/action_controller/middleware.rb +0 -39
  160. data/lib/action_controller/model_naming.rb +0 -12
  161. data/lib/action_dispatch/journey/backwards.rb +0 -5
  162. data/lib/action_dispatch/journey/router/strexp.rb +0 -27
  163. data/lib/action_dispatch/middleware/params_parser.rb +0 -60
  164. data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
  165. data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
  166. data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
@@ -1,31 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionController
2
4
  module Testing
3
5
  extend ActiveSupport::Concern
4
6
 
5
- include RackDelegation
6
-
7
- # TODO : Rewrite tests using controller.headers= to use Rack env
8
- def headers=(new_headers)
9
- @_response ||= ActionDispatch::Response.new
10
- @_response.headers.replace(new_headers)
11
- end
12
-
13
7
  # Behavior specific to functional tests
14
8
  module Functional # :nodoc:
15
- def set_response!(request)
16
- end
17
-
18
9
  def recycle!
19
10
  @_url_options = nil
20
11
  self.formats = nil
21
12
  self.params = nil
22
13
  end
23
14
  end
24
-
25
- module ClassMethods
26
- def before_filters
27
- _process_action_callbacks.find_all{|x| x.kind == :before}.map{|x| x.name}
28
- end
29
- end
30
15
  end
31
16
  end
@@ -1,10 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionController
2
4
  # Includes +url_for+ into the host class. The class has to provide a +RouteSet+ by implementing
3
5
  # the <tt>_routes</tt> method. Otherwise, an exception will be raised.
4
6
  #
5
7
  # In addition to <tt>AbstractController::UrlFor</tt>, this module accesses the HTTP layer to define
6
- # url options like the +host+. In order to do so, this module requires the host class
7
- # to implement +env+ and +request+, which need to be a Rack-compatible.
8
+ # URL options like the +host+. In order to do so, this module requires the host class
9
+ # to implement +env+ which needs to be Rack-compatible and +request+
10
+ # which is either an instance of +ActionDispatch::Request+ or an object
11
+ # that responds to the +host+, +optional_port+, +protocol+ and
12
+ # +symbolized_path_parameter+ methods.
8
13
  #
9
14
  # class RootUrl
10
15
  # include ActionController::UrlFor
@@ -24,21 +29,25 @@ module ActionController
24
29
 
25
30
  def url_options
26
31
  @_url_options ||= {
27
- :host => request.host,
28
- :port => request.optional_port,
29
- :protocol => request.protocol,
30
- :_recall => request.path_parameters
32
+ host: request.host,
33
+ port: request.optional_port,
34
+ protocol: request.protocol,
35
+ _recall: request.path_parameters
31
36
  }.merge!(super).freeze
32
37
 
33
- if (same_origin = _routes.equal?(env["action_dispatch.routes".freeze])) ||
34
- (script_name = env["ROUTES_#{_routes.object_id}_SCRIPT_NAME"]) ||
35
- (original_script_name = env['ORIGINAL_SCRIPT_NAME'.freeze])
38
+ if (same_origin = _routes.equal?(request.routes)) ||
39
+ (script_name = request.engine_script_name(_routes)) ||
40
+ (original_script_name = request.original_script_name)
36
41
 
37
42
  options = @_url_options.dup
38
43
  if original_script_name
39
44
  options[:original_script_name] = original_script_name
40
45
  else
41
- options[:script_name] = same_origin ? request.script_name.dup : script_name
46
+ if same_origin
47
+ options[:script_name] = request.script_name.empty? ? "".freeze : request.script_name.dup
48
+ else
49
+ options[:script_name] = script_name
50
+ end
42
51
  end
43
52
  options.freeze
44
53
  else
@@ -1,5 +1,9 @@
1
- require 'active_support/core_ext/array/extract_options'
2
- require 'action_dispatch/middleware/stack'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/array/extract_options"
4
+ require "action_dispatch/middleware/stack"
5
+ require "action_dispatch/http/request"
6
+ require "action_dispatch/http/response"
3
7
 
4
8
  module ActionController
5
9
  # Extend ActionDispatch middleware stack to make it aware of options
@@ -11,32 +15,50 @@ module ActionController
11
15
  #
12
16
  class MiddlewareStack < ActionDispatch::MiddlewareStack #:nodoc:
13
17
  class Middleware < ActionDispatch::MiddlewareStack::Middleware #:nodoc:
14
- def initialize(klass, *args, &block)
15
- options = args.extract_options!
16
- @only = Array(options.delete(:only)).map(&:to_s)
17
- @except = Array(options.delete(:except)).map(&:to_s)
18
- args << options unless options.empty?
19
- super
18
+ def initialize(klass, args, actions, strategy, block)
19
+ @actions = actions
20
+ @strategy = strategy
21
+ super(klass, args, block)
20
22
  end
21
23
 
22
24
  def valid?(action)
23
- if @only.present?
24
- @only.include?(action)
25
- elsif @except.present?
26
- !@except.include?(action)
27
- else
28
- true
29
- end
25
+ @strategy.call @actions, action
30
26
  end
31
27
  end
32
28
 
33
- def build(action, app = Proc.new)
29
+ def build(action, app = nil, &block)
34
30
  action = action.to_s
35
31
 
36
- middlewares.reverse.inject(app) do |a, middleware|
32
+ middlewares.reverse.inject(app || block) do |a, middleware|
37
33
  middleware.valid?(action) ? middleware.build(a) : a
38
34
  end
39
35
  end
36
+
37
+ private
38
+
39
+ INCLUDE = ->(list, action) { list.include? action }
40
+ EXCLUDE = ->(list, action) { !list.include? action }
41
+ NULL = ->(list, action) { true }
42
+
43
+ def build_middleware(klass, args, block)
44
+ options = args.extract_options!
45
+ only = Array(options.delete(:only)).map(&:to_s)
46
+ except = Array(options.delete(:except)).map(&:to_s)
47
+ args << options unless options.empty?
48
+
49
+ strategy = NULL
50
+ list = nil
51
+
52
+ if only.any?
53
+ strategy = INCLUDE
54
+ list = only
55
+ elsif except.any?
56
+ strategy = EXCLUDE
57
+ list = except
58
+ end
59
+
60
+ Middleware.new(klass, args, list, strategy, block)
61
+ end
40
62
  end
41
63
 
42
64
  # <tt>ActionController::Metal</tt> is the simplest possible controller, providing a
@@ -98,12 +120,6 @@ module ActionController
98
120
  class Metal < AbstractController::Base
99
121
  abstract!
100
122
 
101
- attr_internal_writer :env
102
-
103
- def env
104
- @_env ||= {}
105
- end
106
-
107
123
  # Returns the last part of the controller's name, underscored, without the ending
108
124
  # <tt>Controller</tt>. For instance, PostsController returns <tt>posts</tt>.
109
125
  # Namespaces are left out, so Admin::PostsController returns <tt>posts</tt> as well.
@@ -111,26 +127,30 @@ module ActionController
111
127
  # ==== Returns
112
128
  # * <tt>string</tt>
113
129
  def self.controller_name
114
- @controller_name ||= name.demodulize.sub(/Controller$/, '').underscore
130
+ @controller_name ||= name.demodulize.sub(/Controller$/, "").underscore
131
+ end
132
+
133
+ def self.make_response!(request)
134
+ ActionDispatch::Response.new.tap do |res|
135
+ res.request = request
136
+ end
115
137
  end
116
138
 
117
- # Delegates to the class' <tt>controller_name</tt>
139
+ def self.binary_params_for?(action) # :nodoc:
140
+ false
141
+ end
142
+
143
+ # Delegates to the class' <tt>controller_name</tt>.
118
144
  def controller_name
119
145
  self.class.controller_name
120
146
  end
121
147
 
122
- # The details below can be overridden to support a specific
123
- # Request and Response object. The default ActionController::Base
124
- # implementation includes RackDelegation, which makes a request
125
- # and response object available. You might wish to control the
126
- # environment and response manually for performance reasons.
127
-
128
- attr_internal :headers, :response, :request
129
- delegate :session, :to => "@_request"
148
+ attr_internal :response, :request
149
+ delegate :session, to: "@_request"
150
+ delegate :headers, :status=, :location=, :content_type=,
151
+ :status, :location, :content_type, to: "@_response"
130
152
 
131
153
  def initialize
132
- @_headers = {"Content-Type" => "text/html"}
133
- @_status = 200
134
154
  @_request = nil
135
155
  @_response = nil
136
156
  @_routes = nil
@@ -145,64 +165,52 @@ module ActionController
145
165
  @_params = val
146
166
  end
147
167
 
148
- # Basic implementations for content_type=, location=, and headers are
149
- # provided to reduce the dependency on the RackDelegation module
150
- # in Renderer and Redirector.
151
-
152
- def content_type=(type)
153
- headers["Content-Type"] = type.to_s
154
- end
155
-
156
- def content_type
157
- headers["Content-Type"]
158
- end
159
-
160
- def location
161
- headers["Location"]
162
- end
163
-
164
- def location=(url)
165
- headers["Location"] = url
166
- end
168
+ alias :response_code :status # :nodoc:
167
169
 
168
- # Basic url_for that can be overridden for more robust functionality
170
+ # Basic url_for that can be overridden for more robust functionality.
169
171
  def url_for(string)
170
172
  string
171
173
  end
172
174
 
173
- def status
174
- @_status
175
- end
176
- alias :response_code :status # :nodoc:
177
-
178
- def status=(status)
179
- @_status = Rack::Utils.status_code(status)
180
- end
181
-
182
175
  def response_body=(body)
183
176
  body = [body] unless body.nil? || body.respond_to?(:each)
177
+ response.reset_body!
178
+ return unless body
179
+ response.body = body
184
180
  super
185
181
  end
186
182
 
187
183
  # Tests if render or redirect has already happened.
188
184
  def performed?
189
- response_body || (response && response.committed?)
185
+ response_body || response.committed?
190
186
  end
191
187
 
192
- def dispatch(name, request) #:nodoc:
193
- @_request = request
194
- @_env = request.env
195
- @_env['action_controller.instance'] = self
188
+ def dispatch(name, request, response) #:nodoc:
189
+ set_request!(request)
190
+ set_response!(response)
196
191
  process(name)
192
+ request.commit_flash
197
193
  to_a
198
194
  end
199
195
 
196
+ def set_response!(response) # :nodoc:
197
+ @_response = response
198
+ end
199
+
200
+ def set_request!(request) #:nodoc:
201
+ @_request = request
202
+ @_request.controller_instance = self
203
+ end
204
+
200
205
  def to_a #:nodoc:
201
- response ? response.to_a : [status, headers, response_body]
206
+ response.to_a
202
207
  end
203
208
 
204
- class_attribute :middleware_stack
205
- self.middleware_stack = ActionController::MiddlewareStack.new
209
+ def reset_session
210
+ @_request.reset_session
211
+ end
212
+
213
+ class_attribute :middleware_stack, default: ActionController::MiddlewareStack.new
206
214
 
207
215
  def self.inherited(base) # :nodoc:
208
216
  base.middleware_stack = middleware_stack.dup
@@ -220,21 +228,28 @@ module ActionController
220
228
  middleware_stack
221
229
  end
222
230
 
223
- # Makes the controller a Rack endpoint that runs the action in the given
224
- # +env+'s +action_dispatch.request.path_parameters+ key.
225
- def self.call(env)
226
- req = ActionDispatch::Request.new env
227
- action(req.path_parameters[:action]).call(env)
231
+ # Returns a Rack endpoint for the given action name.
232
+ def self.action(name)
233
+ app = lambda { |env|
234
+ req = ActionDispatch::Request.new(env)
235
+ res = make_response! req
236
+ new.dispatch(name, req, res)
237
+ }
238
+
239
+ if middleware_stack.any?
240
+ middleware_stack.build(name, app)
241
+ else
242
+ app
243
+ end
228
244
  end
229
245
 
230
- # Returns a Rack endpoint for the given action name.
231
- def self.action(name, klass = ActionDispatch::Request)
246
+ # Direct dispatch to the controller. Instantiates the controller, then
247
+ # executes the action named +name+.
248
+ def self.dispatch(name, req, res)
232
249
  if middleware_stack.any?
233
- middleware_stack.build(name) do |env|
234
- new.dispatch(name, klass.new(env))
235
- end
250
+ middleware_stack.build(name) { |env| new.dispatch(name, req, res) }.call req.env
236
251
  else
237
- lambda { |env| new.dispatch(name, klass.new(env)) }
252
+ new.dispatch(name, req, res)
238
253
  end
239
254
  end
240
255
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "rails"
2
4
  require "action_controller"
3
5
  require "action_dispatch/railtie"
@@ -11,7 +13,7 @@ module ActionController
11
13
 
12
14
  config.eager_load_namespaces << ActionController
13
15
 
14
- initializer "action_controller.assets_config", :group => :all do |app|
16
+ initializer "action_controller.assets_config", group: :all do |app|
15
17
  app.config.action_controller.assets_dir ||= app.config.paths["public"].first
16
18
  end
17
19
 
@@ -22,13 +24,15 @@ module ActionController
22
24
  initializer "action_controller.parameters_config" do |app|
23
25
  options = app.config.action_controller
24
26
 
25
- ActionController::Parameters.permit_all_parameters = options.delete(:permit_all_parameters) { false }
26
- if app.config.action_controller[:always_permitted_parameters]
27
- ActionController::Parameters.always_permitted_parameters =
28
- app.config.action_controller.delete(:always_permitted_parameters)
29
- end
30
- ActionController::Parameters.action_on_unpermitted_parameters = options.delete(:action_on_unpermitted_parameters) do
31
- (Rails.env.test? || Rails.env.development?) ? :log : false
27
+ ActiveSupport.on_load(:action_controller, run_once: true) do
28
+ ActionController::Parameters.permit_all_parameters = options.delete(:permit_all_parameters) { false }
29
+ if app.config.action_controller[:always_permitted_parameters]
30
+ ActionController::Parameters.always_permitted_parameters =
31
+ app.config.action_controller.delete(:always_permitted_parameters)
32
+ end
33
+ ActionController::Parameters.action_on_unpermitted_parameters = options.delete(:action_on_unpermitted_parameters) do
34
+ (Rails.env.test? || Rails.env.development?) ? :log : false
35
+ end
32
36
  end
33
37
  end
34
38
 
@@ -42,7 +46,7 @@ module ActionController
42
46
  options.javascripts_dir ||= paths["public/javascripts"].first
43
47
  options.stylesheets_dir ||= paths["public/stylesheets"].first
44
48
 
45
- # Ensure readers methods get compiled
49
+ # Ensure readers methods get compiled.
46
50
  options.asset_host ||= app.config.asset_host
47
51
  options.relative_url_root ||= app.config.relative_url_root
48
52
 
@@ -51,7 +55,7 @@ module ActionController
51
55
  extend ::AbstractController::Railties::RoutesHelpers.with(app.routes)
52
56
  extend ::ActionController::Railties::Helpers
53
57
 
54
- options.each do |k,v|
58
+ options.each do |k, v|
55
59
  k = "#{k}="
56
60
  if respond_to?(k)
57
61
  send(k, v)
@@ -67,5 +71,19 @@ module ActionController
67
71
  config.compile_methods! if config.respond_to?(:compile_methods!)
68
72
  end
69
73
  end
74
+
75
+ initializer "action_controller.request_forgery_protection" do |app|
76
+ ActiveSupport.on_load(:action_controller_base) do
77
+ if app.config.action_controller.default_protect_from_forgery
78
+ protect_from_forgery with: :exception
79
+ end
80
+ end
81
+ end
82
+
83
+ initializer "action_controller.eager_load_actions" do
84
+ ActiveSupport.on_load(:after_initialize) do
85
+ ActionController::Metal.descendants.each(&:action_methods) if config.eager_load
86
+ end
87
+ end
70
88
  end
71
89
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionController
2
4
  module Railties
3
5
  module Helpers
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/keys"
4
+
5
+ module ActionController
6
+ # ActionController::Renderer allows you to render arbitrary templates
7
+ # without requirement of being in controller actions.
8
+ #
9
+ # You get a concrete renderer class by invoking ActionController::Base#renderer.
10
+ # For example:
11
+ #
12
+ # ApplicationController.renderer
13
+ #
14
+ # It allows you to call method #render directly.
15
+ #
16
+ # ApplicationController.renderer.render template: '...'
17
+ #
18
+ # You can use this shortcut in a controller, instead of the previous example:
19
+ #
20
+ # ApplicationController.render template: '...'
21
+ #
22
+ # #render allows you to use the same options that you can use when rendering in a controller.
23
+ # For example:
24
+ #
25
+ # FooController.render :action, locals: { ... }, assigns: { ... }
26
+ #
27
+ # The template will be rendered in a Rack environment which is accessible through
28
+ # ActionController::Renderer#env. You can set it up in two ways:
29
+ #
30
+ # * by changing renderer defaults, like
31
+ #
32
+ # ApplicationController.renderer.defaults # => hash with default Rack environment
33
+ #
34
+ # * by initializing an instance of renderer by passing it a custom environment.
35
+ #
36
+ # ApplicationController.renderer.new(method: 'post', https: true)
37
+ #
38
+ class Renderer
39
+ attr_reader :defaults, :controller
40
+
41
+ DEFAULTS = {
42
+ http_host: "example.org",
43
+ https: false,
44
+ method: "get",
45
+ script_name: "",
46
+ input: ""
47
+ }.freeze
48
+
49
+ # Create a new renderer instance for a specific controller class.
50
+ def self.for(controller, env = {}, defaults = DEFAULTS.dup)
51
+ new(controller, env, defaults)
52
+ end
53
+
54
+ # Create a new renderer for the same controller but with a new env.
55
+ def new(env = {})
56
+ self.class.new controller, env, defaults
57
+ end
58
+
59
+ # Create a new renderer for the same controller but with new defaults.
60
+ def with_defaults(defaults)
61
+ self.class.new controller, @env, self.defaults.merge(defaults)
62
+ end
63
+
64
+ # Accepts a custom Rack environment to render templates in.
65
+ # It will be merged with the default Rack environment defined by
66
+ # +ActionController::Renderer::DEFAULTS+.
67
+ def initialize(controller, env, defaults)
68
+ @controller = controller
69
+ @defaults = defaults
70
+ @env = normalize_keys defaults.merge(env)
71
+ end
72
+
73
+ # Render templates with any options from ActionController::Base#render_to_string.
74
+ def render(*args)
75
+ raise "missing controller" unless controller
76
+
77
+ request = ActionDispatch::Request.new @env
78
+ request.routes = controller._routes
79
+
80
+ instance = controller.new
81
+ instance.set_request! request
82
+ instance.set_response! controller.make_response!(request)
83
+ instance.render_to_string(*args)
84
+ end
85
+
86
+ private
87
+ def normalize_keys(env)
88
+ new_env = {}
89
+ env.each_pair { |k, v| new_env[rack_key_for(k)] = rack_value_for(k, v) }
90
+ new_env["rack.url_scheme"] = new_env["HTTPS"] == "on" ? "https" : "http"
91
+ new_env
92
+ end
93
+
94
+ RACK_KEY_TRANSLATION = {
95
+ http_host: "HTTP_HOST",
96
+ https: "HTTPS",
97
+ method: "REQUEST_METHOD",
98
+ script_name: "SCRIPT_NAME",
99
+ input: "rack.input"
100
+ }
101
+
102
+ IDENTITY = ->(_) { _ }
103
+
104
+ RACK_VALUE_TRANSLATION = {
105
+ https: ->(v) { v ? "on" : "off" },
106
+ method: ->(v) { v.upcase },
107
+ }
108
+
109
+ def rack_key_for(key)
110
+ RACK_KEY_TRANSLATION.fetch(key, key.to_s)
111
+ end
112
+
113
+ def rack_value_for(key, value)
114
+ RACK_VALUE_TRANSLATION.fetch(key, IDENTITY).call value
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionController
4
+ module TemplateAssertions
5
+ def assert_template(options = {}, message = nil)
6
+ raise NoMethodError,
7
+ "assert_template has been extracted to a gem. To continue using it,
8
+ add `gem 'rails-controller-testing'` to your Gemfile."
9
+ end
10
+ end
11
+ end