actionpack 4.2.11.1 → 6.1.3.2

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 (187) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +291 -489
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +9 -9
  5. data/lib/abstract_controller/asset_paths.rb +2 -0
  6. data/lib/abstract_controller/base.rb +81 -51
  7. data/lib/{action_controller → abstract_controller}/caching/fragments.rb +64 -17
  8. data/lib/abstract_controller/caching.rb +66 -0
  9. data/lib/abstract_controller/callbacks.rb +61 -33
  10. data/lib/abstract_controller/collector.rb +9 -13
  11. data/lib/abstract_controller/error.rb +6 -0
  12. data/lib/abstract_controller/helpers.rb +115 -99
  13. data/lib/abstract_controller/logger.rb +2 -0
  14. data/lib/abstract_controller/railties/routes_helpers.rb +21 -3
  15. data/lib/abstract_controller/rendering.rb +48 -47
  16. data/lib/abstract_controller/translation.rb +17 -8
  17. data/lib/abstract_controller/url_for.rb +2 -0
  18. data/lib/abstract_controller.rb +13 -5
  19. data/lib/action_controller/api/api_rendering.rb +16 -0
  20. data/lib/action_controller/api.rb +150 -0
  21. data/lib/action_controller/base.rb +29 -24
  22. data/lib/action_controller/caching.rb +12 -57
  23. data/lib/action_controller/form_builder.rb +50 -0
  24. data/lib/action_controller/log_subscriber.rb +17 -19
  25. data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
  26. data/lib/action_controller/metal/conditional_get.rb +134 -46
  27. data/lib/action_controller/metal/content_security_policy.rb +51 -0
  28. data/lib/action_controller/metal/cookies.rb +6 -4
  29. data/lib/action_controller/metal/data_streaming.rb +30 -50
  30. data/lib/action_controller/metal/default_headers.rb +17 -0
  31. data/lib/action_controller/metal/etag_with_flash.rb +18 -0
  32. data/lib/action_controller/metal/etag_with_template_digest.rb +21 -16
  33. data/lib/action_controller/metal/exceptions.rb +63 -15
  34. data/lib/action_controller/metal/flash.rb +9 -8
  35. data/lib/action_controller/metal/head.rb +26 -21
  36. data/lib/action_controller/metal/helpers.rb +37 -18
  37. data/lib/action_controller/metal/http_authentication.rb +81 -73
  38. data/lib/action_controller/metal/implicit_render.rb +53 -9
  39. data/lib/action_controller/metal/instrumentation.rb +32 -35
  40. data/lib/action_controller/metal/live.rb +102 -120
  41. data/lib/action_controller/metal/logging.rb +20 -0
  42. data/lib/action_controller/metal/mime_responds.rb +49 -47
  43. data/lib/action_controller/metal/parameter_encoding.rb +82 -0
  44. data/lib/action_controller/metal/params_wrapper.rb +83 -66
  45. data/lib/action_controller/metal/permissions_policy.rb +46 -0
  46. data/lib/action_controller/metal/redirecting.rb +53 -32
  47. data/lib/action_controller/metal/renderers.rb +87 -44
  48. data/lib/action_controller/metal/rendering.rb +77 -50
  49. data/lib/action_controller/metal/request_forgery_protection.rb +267 -103
  50. data/lib/action_controller/metal/rescue.rb +10 -17
  51. data/lib/action_controller/metal/streaming.rb +12 -11
  52. data/lib/action_controller/metal/strong_parameters.rb +714 -186
  53. data/lib/action_controller/metal/testing.rb +2 -17
  54. data/lib/action_controller/metal/url_for.rb +19 -10
  55. data/lib/action_controller/metal.rb +104 -87
  56. data/lib/action_controller/railtie.rb +28 -10
  57. data/lib/action_controller/railties/helpers.rb +3 -1
  58. data/lib/action_controller/renderer.rb +141 -0
  59. data/lib/action_controller/template_assertions.rb +11 -0
  60. data/lib/action_controller/test_case.rb +296 -422
  61. data/lib/action_controller.rb +34 -23
  62. data/lib/action_dispatch/http/cache.rb +107 -56
  63. data/lib/action_dispatch/http/content_disposition.rb +45 -0
  64. data/lib/action_dispatch/http/content_security_policy.rb +286 -0
  65. data/lib/action_dispatch/http/filter_parameters.rb +32 -25
  66. data/lib/action_dispatch/http/filter_redirect.rb +10 -12
  67. data/lib/action_dispatch/http/headers.rb +55 -22
  68. data/lib/action_dispatch/http/mime_negotiation.rb +79 -51
  69. data/lib/action_dispatch/http/mime_type.rb +153 -121
  70. data/lib/action_dispatch/http/mime_types.rb +20 -6
  71. data/lib/action_dispatch/http/parameters.rb +90 -40
  72. data/lib/action_dispatch/http/permissions_policy.rb +173 -0
  73. data/lib/action_dispatch/http/rack_cache.rb +2 -0
  74. data/lib/action_dispatch/http/request.rb +226 -121
  75. data/lib/action_dispatch/http/response.rb +248 -113
  76. data/lib/action_dispatch/http/upload.rb +21 -7
  77. data/lib/action_dispatch/http/url.rb +182 -100
  78. data/lib/action_dispatch/journey/formatter.rb +90 -43
  79. data/lib/action_dispatch/journey/gtg/builder.rb +28 -41
  80. data/lib/action_dispatch/journey/gtg/simulator.rb +11 -16
  81. data/lib/action_dispatch/journey/gtg/transition_table.rb +23 -21
  82. data/lib/action_dispatch/journey/nfa/dot.rb +3 -14
  83. data/lib/action_dispatch/journey/nodes/node.rb +29 -15
  84. data/lib/action_dispatch/journey/parser.rb +17 -16
  85. data/lib/action_dispatch/journey/parser.y +4 -3
  86. data/lib/action_dispatch/journey/parser_extras.rb +12 -4
  87. data/lib/action_dispatch/journey/path/pattern.rb +58 -54
  88. data/lib/action_dispatch/journey/route.rb +100 -32
  89. data/lib/action_dispatch/journey/router/utils.rb +29 -18
  90. data/lib/action_dispatch/journey/router.rb +55 -51
  91. data/lib/action_dispatch/journey/routes.rb +17 -17
  92. data/lib/action_dispatch/journey/scanner.rb +26 -17
  93. data/lib/action_dispatch/journey/visitors.rb +98 -54
  94. data/lib/action_dispatch/journey.rb +5 -5
  95. data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
  96. data/lib/action_dispatch/middleware/callbacks.rb +3 -6
  97. data/lib/action_dispatch/middleware/cookies.rb +347 -217
  98. data/lib/action_dispatch/middleware/debug_exceptions.rb +135 -63
  99. data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
  100. data/lib/action_dispatch/middleware/debug_view.rb +66 -0
  101. data/lib/action_dispatch/middleware/exception_wrapper.rb +115 -71
  102. data/lib/action_dispatch/middleware/executor.rb +21 -0
  103. data/lib/action_dispatch/middleware/flash.rb +78 -54
  104. data/lib/action_dispatch/middleware/host_authorization.rb +130 -0
  105. data/lib/action_dispatch/middleware/public_exceptions.rb +32 -27
  106. data/lib/action_dispatch/middleware/reloader.rb +5 -91
  107. data/lib/action_dispatch/middleware/remote_ip.rb +53 -45
  108. data/lib/action_dispatch/middleware/request_id.rb +17 -10
  109. data/lib/action_dispatch/middleware/session/abstract_store.rb +41 -26
  110. data/lib/action_dispatch/middleware/session/cache_store.rb +24 -14
  111. data/lib/action_dispatch/middleware/session/cookie_store.rb +74 -75
  112. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -2
  113. data/lib/action_dispatch/middleware/show_exceptions.rb +28 -23
  114. data/lib/action_dispatch/middleware/ssl.rb +118 -35
  115. data/lib/action_dispatch/middleware/stack.rb +82 -41
  116. data/lib/action_dispatch/middleware/static.rb +156 -89
  117. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
  118. data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
  119. data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
  120. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +4 -14
  121. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
  122. data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +4 -2
  123. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  124. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +45 -35
  125. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -0
  126. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -0
  127. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +23 -4
  128. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +1 -1
  129. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +24 -0
  130. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +15 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +105 -8
  132. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +2 -2
  135. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -1
  136. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +3 -3
  137. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
  138. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
  139. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +4 -4
  140. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +87 -64
  141. data/lib/action_dispatch/railtie.rb +27 -13
  142. data/lib/action_dispatch/request/session.rb +109 -61
  143. data/lib/action_dispatch/request/utils.rb +90 -23
  144. data/lib/action_dispatch/routing/endpoint.rb +9 -2
  145. data/lib/action_dispatch/routing/inspector.rb +141 -102
  146. data/lib/action_dispatch/routing/mapper.rb +811 -473
  147. data/lib/action_dispatch/routing/polymorphic_routes.rb +167 -143
  148. data/lib/action_dispatch/routing/redirection.rb +37 -27
  149. data/lib/action_dispatch/routing/route_set.rb +363 -331
  150. data/lib/action_dispatch/routing/routes_proxy.rb +32 -5
  151. data/lib/action_dispatch/routing/url_for.rb +66 -26
  152. data/lib/action_dispatch/routing.rb +36 -36
  153. data/lib/action_dispatch/system_test_case.rb +190 -0
  154. data/lib/action_dispatch/system_testing/browser.rb +86 -0
  155. data/lib/action_dispatch/system_testing/driver.rb +67 -0
  156. data/lib/action_dispatch/system_testing/server.rb +31 -0
  157. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +138 -0
  158. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +29 -0
  159. data/lib/action_dispatch/testing/assertion_response.rb +46 -0
  160. data/lib/action_dispatch/testing/assertions/response.rb +44 -22
  161. data/lib/action_dispatch/testing/assertions/routing.rb +47 -31
  162. data/lib/action_dispatch/testing/assertions.rb +6 -4
  163. data/lib/action_dispatch/testing/integration.rb +391 -220
  164. data/lib/action_dispatch/testing/request_encoder.rb +55 -0
  165. data/lib/action_dispatch/testing/test_process.rb +53 -22
  166. data/lib/action_dispatch/testing/test_request.rb +27 -34
  167. data/lib/action_dispatch/testing/test_response.rb +11 -11
  168. data/lib/action_dispatch.rb +35 -21
  169. data/lib/action_pack/gem_version.rb +6 -4
  170. data/lib/action_pack/version.rb +3 -1
  171. data/lib/action_pack.rb +4 -2
  172. metadata +78 -48
  173. data/lib/action_controller/metal/force_ssl.rb +0 -97
  174. data/lib/action_controller/metal/hide_actions.rb +0 -40
  175. data/lib/action_controller/metal/rack_delegation.rb +0 -32
  176. data/lib/action_controller/middleware.rb +0 -39
  177. data/lib/action_controller/model_naming.rb +0 -12
  178. data/lib/action_dispatch/http/parameter_filter.rb +0 -72
  179. data/lib/action_dispatch/journey/backwards.rb +0 -5
  180. data/lib/action_dispatch/journey/nfa/builder.rb +0 -76
  181. data/lib/action_dispatch/journey/nfa/simulator.rb +0 -47
  182. data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -163
  183. data/lib/action_dispatch/journey/router/strexp.rb +0 -27
  184. data/lib/action_dispatch/middleware/params_parser.rb +0 -60
  185. data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
  186. data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
  187. 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? ? "" : 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,49 @@ 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
+ INCLUDE = ->(list, action) { list.include? action }
39
+ EXCLUDE = ->(list, action) { !list.include? action }
40
+ NULL = ->(list, action) { true }
41
+
42
+ def build_middleware(klass, args, block)
43
+ options = args.extract_options!
44
+ only = Array(options.delete(:only)).map(&:to_s)
45
+ except = Array(options.delete(:except)).map(&:to_s)
46
+ args << options unless options.empty?
47
+
48
+ strategy = NULL
49
+ list = nil
50
+
51
+ if only.any?
52
+ strategy = INCLUDE
53
+ list = only
54
+ elsif except.any?
55
+ strategy = EXCLUDE
56
+ list = except
57
+ end
58
+
59
+ Middleware.new(klass, args, list, strategy, block)
60
+ end
40
61
  end
41
62
 
42
63
  # <tt>ActionController::Metal</tt> is the simplest possible controller, providing a
@@ -98,12 +119,6 @@ module ActionController
98
119
  class Metal < AbstractController::Base
99
120
  abstract!
100
121
 
101
- attr_internal_writer :env
102
-
103
- def env
104
- @_env ||= {}
105
- end
106
-
107
122
  # Returns the last part of the controller's name, underscored, without the ending
108
123
  # <tt>Controller</tt>. For instance, PostsController returns <tt>posts</tt>.
109
124
  # Namespaces are left out, so Admin::PostsController returns <tt>posts</tt> as well.
@@ -111,26 +126,30 @@ module ActionController
111
126
  # ==== Returns
112
127
  # * <tt>string</tt>
113
128
  def self.controller_name
114
- @controller_name ||= name.demodulize.sub(/Controller$/, '').underscore
129
+ @controller_name ||= (name.demodulize.delete_suffix("Controller").underscore unless anonymous?)
115
130
  end
116
131
 
117
- # Delegates to the class' <tt>controller_name</tt>
132
+ def self.make_response!(request)
133
+ ActionDispatch::Response.new.tap do |res|
134
+ res.request = request
135
+ end
136
+ end
137
+
138
+ def self.action_encoding_template(action) # :nodoc:
139
+ false
140
+ end
141
+
142
+ # Delegates to the class' <tt>controller_name</tt>.
118
143
  def controller_name
119
144
  self.class.controller_name
120
145
  end
121
146
 
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"
147
+ attr_internal :response, :request
148
+ delegate :session, to: "@_request"
149
+ delegate :headers, :status=, :location=, :content_type=,
150
+ :status, :location, :content_type, :media_type, to: "@_response"
130
151
 
131
152
  def initialize
132
- @_headers = {"Content-Type" => "text/html"}
133
- @_status = 200
134
153
  @_request = nil
135
154
  @_response = nil
136
155
  @_routes = nil
@@ -145,74 +164,65 @@ module ActionController
145
164
  @_params = val
146
165
  end
147
166
 
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
167
+ alias :response_code :status # :nodoc:
167
168
 
168
- # Basic url_for that can be overridden for more robust functionality
169
+ # Basic url_for that can be overridden for more robust functionality.
169
170
  def url_for(string)
170
171
  string
171
172
  end
172
173
 
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
174
  def response_body=(body)
183
175
  body = [body] unless body.nil? || body.respond_to?(:each)
176
+ response.reset_body!
177
+ return unless body
178
+ response.body = body
184
179
  super
185
180
  end
186
181
 
187
182
  # Tests if render or redirect has already happened.
188
183
  def performed?
189
- response_body || (response && response.committed?)
184
+ response_body || response.committed?
190
185
  end
191
186
 
192
- def dispatch(name, request) #:nodoc:
193
- @_request = request
194
- @_env = request.env
195
- @_env['action_controller.instance'] = self
187
+ def dispatch(name, request, response) #:nodoc:
188
+ set_request!(request)
189
+ set_response!(response)
196
190
  process(name)
191
+ request.commit_flash
197
192
  to_a
198
193
  end
199
194
 
195
+ def set_response!(response) # :nodoc:
196
+ @_response = response
197
+ end
198
+
199
+ def set_request!(request) #:nodoc:
200
+ @_request = request
201
+ @_request.controller_instance = self
202
+ end
203
+
200
204
  def to_a #:nodoc:
201
- response ? response.to_a : [status, headers, response_body]
205
+ response.to_a
202
206
  end
203
207
 
204
- class_attribute :middleware_stack
205
- self.middleware_stack = ActionController::MiddlewareStack.new
208
+ def reset_session
209
+ @_request.reset_session
210
+ end
211
+
212
+ class_attribute :middleware_stack, default: ActionController::MiddlewareStack.new
206
213
 
207
214
  def self.inherited(base) # :nodoc:
208
215
  base.middleware_stack = middleware_stack.dup
209
216
  super
210
217
  end
211
218
 
212
- # Pushes the given Rack middleware and its arguments to the bottom of the
213
- # middleware stack.
214
- def self.use(*args, &block)
215
- middleware_stack.use(*args, &block)
219
+ class << self
220
+ # Pushes the given Rack middleware and its arguments to the bottom of the
221
+ # middleware stack.
222
+ def use(*args, &block)
223
+ middleware_stack.use(*args, &block)
224
+ end
225
+ ruby2_keywords(:use) if respond_to?(:ruby2_keywords, true)
216
226
  end
217
227
 
218
228
  # Alias for +middleware_stack+.
@@ -220,21 +230,28 @@ module ActionController
220
230
  middleware_stack
221
231
  end
222
232
 
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)
233
+ # Returns a Rack endpoint for the given action name.
234
+ def self.action(name)
235
+ app = lambda { |env|
236
+ req = ActionDispatch::Request.new(env)
237
+ res = make_response! req
238
+ new.dispatch(name, req, res)
239
+ }
240
+
241
+ if middleware_stack.any?
242
+ middleware_stack.build(name, app)
243
+ else
244
+ app
245
+ end
228
246
  end
229
247
 
230
- # Returns a Rack endpoint for the given action name.
231
- def self.action(name, klass = ActionDispatch::Request)
248
+ # Direct dispatch to the controller. Instantiates the controller, then
249
+ # executes the action named +name+.
250
+ def self.dispatch(name, req, res)
232
251
  if middleware_stack.any?
233
- middleware_stack.build(name) do |env|
234
- new.dispatch(name, klass.new(env))
235
- end
252
+ middleware_stack.build(name) { |env| new.dispatch(name, req, res) }.call req.env
236
253
  else
237
- lambda { |env| new.dispatch(name, klass.new(env)) }
254
+ new.dispatch(name, req, res)
238
255
  end
239
256
  end
240
257
  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
@@ -5,7 +7,7 @@ module ActionController
5
7
  super
6
8
  return unless klass.respond_to?(:helpers_path=)
7
9
 
8
- if namespace = klass.parents.detect { |m| m.respond_to?(:railtie_helpers_paths) }
10
+ if namespace = klass.module_parents.detect { |m| m.respond_to?(:railtie_helpers_paths) }
9
11
  paths = namespace.railtie_helpers_paths
10
12
  else
11
13
  paths = ActionController::Helpers.helpers_path
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionController
4
+ # ActionController::Renderer allows you to render arbitrary templates
5
+ # without requirement of being in controller actions.
6
+ #
7
+ # You get a concrete renderer class by invoking ActionController::Base#renderer.
8
+ # For example:
9
+ #
10
+ # ApplicationController.renderer
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:
22
+ #
23
+ # FooController.render :action, locals: { ... }, assigns: { ... }
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:
27
+ #
28
+ # * by changing renderer defaults, like
29
+ #
30
+ # ApplicationController.renderer.defaults # => hash with default Rack environment
31
+ #
32
+ # * by initializing an instance of renderer by passing it a custom environment.
33
+ #
34
+ # ApplicationController.renderer.new(method: 'post', https: true)
35
+ #
36
+ class Renderer
37
+ attr_reader :defaults, :controller
38
+
39
+ DEFAULTS = {
40
+ http_host: "example.org",
41
+ https: false,
42
+ method: "get",
43
+ script_name: "",
44
+ input: ""
45
+ }.freeze
46
+
47
+ # Create a new renderer instance for a specific controller class.
48
+ def self.for(controller, env = {}, defaults = DEFAULTS.dup)
49
+ new(controller, env, defaults)
50
+ end
51
+
52
+ # Create a new renderer for the same controller but with a new env.
53
+ def new(env = {})
54
+ self.class.new controller, env, defaults
55
+ end
56
+
57
+ # Create a new renderer for the same controller but with new defaults.
58
+ def with_defaults(defaults)
59
+ self.class.new controller, @env, self.defaults.merge(defaults)
60
+ end
61
+
62
+ # Accepts a custom Rack environment to render templates in.
63
+ # It will be merged with the default Rack environment defined by
64
+ # +ActionController::Renderer::DEFAULTS+.
65
+ def initialize(controller, env, defaults)
66
+ @controller = controller
67
+ @defaults = defaults
68
+ @env = normalize_keys defaults, env
69
+ end
70
+
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.
91
+ def render(*args)
92
+ raise "missing controller" unless controller
93
+
94
+ request = ActionDispatch::Request.new @env
95
+ request.routes = controller._routes
96
+
97
+ instance = controller.new
98
+ instance.set_request! request
99
+ instance.set_response! controller.make_response!(request)
100
+ instance.render_to_string(*args)
101
+ end
102
+ alias_method :render_to_string, :render # :nodoc:
103
+
104
+ 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
+ RACK_KEY_TRANSLATION = {
119
+ http_host: "HTTP_HOST",
120
+ https: "HTTPS",
121
+ method: "REQUEST_METHOD",
122
+ script_name: "SCRIPT_NAME",
123
+ input: "rack.input"
124
+ }
125
+
126
+ def rack_key_for(key)
127
+ RACK_KEY_TRANSLATION[key] || key.to_s
128
+ end
129
+
130
+ def rack_value_for(key, value)
131
+ case key
132
+ when :https
133
+ value ? "on" : "off"
134
+ when :method
135
+ -value.upcase
136
+ else
137
+ value
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionController
4
+ module TemplateAssertions # :nodoc:
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