actionpack 3.2.22.5 → 5.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (271) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +279 -603
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +13 -297
  5. data/lib/abstract_controller/asset_paths.rb +4 -2
  6. data/lib/abstract_controller/base.rb +82 -52
  7. data/lib/abstract_controller/caching/fragments.rb +166 -0
  8. data/lib/abstract_controller/caching.rb +66 -0
  9. data/lib/abstract_controller/callbacks.rb +117 -103
  10. data/lib/abstract_controller/collector.rb +18 -7
  11. data/lib/abstract_controller/error.rb +6 -0
  12. data/lib/abstract_controller/helpers.rb +65 -38
  13. data/lib/abstract_controller/logger.rb +3 -2
  14. data/lib/abstract_controller/railties/routes_helpers.rb +5 -3
  15. data/lib/abstract_controller/rendering.rb +77 -129
  16. data/lib/abstract_controller/translation.rb +21 -3
  17. data/lib/abstract_controller/url_for.rb +9 -7
  18. data/lib/abstract_controller.rb +12 -13
  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 +81 -40
  22. data/lib/action_controller/caching.rb +22 -62
  23. data/lib/action_controller/form_builder.rb +50 -0
  24. data/lib/action_controller/log_subscriber.rb +30 -18
  25. data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
  26. data/lib/action_controller/metal/conditional_get.rb +190 -47
  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 +40 -65
  30. data/lib/action_controller/metal/etag_with_flash.rb +18 -0
  31. data/lib/action_controller/metal/etag_with_template_digest.rb +57 -0
  32. data/lib/action_controller/metal/exceptions.rb +19 -12
  33. data/lib/action_controller/metal/flash.rb +42 -9
  34. data/lib/action_controller/metal/force_ssl.rb +79 -19
  35. data/lib/action_controller/metal/head.rb +35 -10
  36. data/lib/action_controller/metal/helpers.rb +31 -21
  37. data/lib/action_controller/metal/http_authentication.rb +182 -134
  38. data/lib/action_controller/metal/implicit_render.rb +62 -8
  39. data/lib/action_controller/metal/instrumentation.rb +28 -26
  40. data/lib/action_controller/metal/live.rb +312 -0
  41. data/lib/action_controller/metal/mime_responds.rb +159 -163
  42. data/lib/action_controller/metal/parameter_encoding.rb +51 -0
  43. data/lib/action_controller/metal/params_wrapper.rb +146 -93
  44. data/lib/action_controller/metal/redirecting.rb +80 -56
  45. data/lib/action_controller/metal/renderers.rb +119 -47
  46. data/lib/action_controller/metal/rendering.rb +89 -32
  47. data/lib/action_controller/metal/request_forgery_protection.rb +373 -41
  48. data/lib/action_controller/metal/rescue.rb +9 -16
  49. data/lib/action_controller/metal/streaming.rb +39 -45
  50. data/lib/action_controller/metal/strong_parameters.rb +1086 -0
  51. data/lib/action_controller/metal/testing.rb +8 -29
  52. data/lib/action_controller/metal/url_for.rb +43 -32
  53. data/lib/action_controller/metal.rb +112 -106
  54. data/lib/action_controller/railtie.rb +56 -18
  55. data/lib/action_controller/railties/helpers.rb +24 -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 +402 -347
  59. data/lib/action_controller.rb +31 -30
  60. data/lib/action_dispatch/http/cache.rb +133 -34
  61. data/lib/action_dispatch/http/content_security_policy.rb +272 -0
  62. data/lib/action_dispatch/http/filter_parameters.rb +40 -24
  63. data/lib/action_dispatch/http/filter_redirect.rb +37 -0
  64. data/lib/action_dispatch/http/headers.rb +117 -16
  65. data/lib/action_dispatch/http/mime_negotiation.rb +98 -33
  66. data/lib/action_dispatch/http/mime_type.rb +198 -146
  67. data/lib/action_dispatch/http/mime_types.rb +22 -7
  68. data/lib/action_dispatch/http/parameter_filter.rb +61 -49
  69. data/lib/action_dispatch/http/parameters.rb +94 -51
  70. data/lib/action_dispatch/http/rack_cache.rb +4 -3
  71. data/lib/action_dispatch/http/request.rb +262 -117
  72. data/lib/action_dispatch/http/response.rb +400 -86
  73. data/lib/action_dispatch/http/upload.rb +66 -29
  74. data/lib/action_dispatch/http/url.rb +232 -60
  75. data/lib/action_dispatch/journey/formatter.rb +189 -0
  76. data/lib/action_dispatch/journey/gtg/builder.rb +164 -0
  77. data/lib/action_dispatch/journey/gtg/simulator.rb +41 -0
  78. data/lib/action_dispatch/journey/gtg/transition_table.rb +158 -0
  79. data/lib/action_dispatch/journey/nfa/builder.rb +78 -0
  80. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  81. data/lib/action_dispatch/journey/nfa/simulator.rb +49 -0
  82. data/lib/action_dispatch/journey/nfa/transition_table.rb +120 -0
  83. data/lib/action_dispatch/journey/nodes/node.rb +140 -0
  84. data/lib/action_dispatch/journey/parser.rb +199 -0
  85. data/lib/action_dispatch/journey/parser.y +50 -0
  86. data/lib/action_dispatch/journey/parser_extras.rb +31 -0
  87. data/lib/action_dispatch/journey/path/pattern.rb +199 -0
  88. data/lib/action_dispatch/journey/route.rb +203 -0
  89. data/lib/action_dispatch/journey/router/utils.rb +102 -0
  90. data/lib/action_dispatch/journey/router.rb +156 -0
  91. data/lib/action_dispatch/journey/routes.rb +82 -0
  92. data/lib/action_dispatch/journey/scanner.rb +64 -0
  93. data/lib/action_dispatch/journey/visitors.rb +268 -0
  94. data/lib/action_dispatch/journey/visualizer/fsm.css +30 -0
  95. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  96. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  97. data/lib/action_dispatch/journey.rb +7 -0
  98. data/lib/action_dispatch/middleware/callbacks.rb +17 -13
  99. data/lib/action_dispatch/middleware/cookies.rb +494 -162
  100. data/lib/action_dispatch/middleware/debug_exceptions.rb +176 -53
  101. data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
  102. data/lib/action_dispatch/middleware/exception_wrapper.rb +103 -38
  103. data/lib/action_dispatch/middleware/executor.rb +21 -0
  104. data/lib/action_dispatch/middleware/flash.rb +128 -91
  105. data/lib/action_dispatch/middleware/public_exceptions.rb +43 -16
  106. data/lib/action_dispatch/middleware/reloader.rb +6 -83
  107. data/lib/action_dispatch/middleware/remote_ip.rb +151 -49
  108. data/lib/action_dispatch/middleware/request_id.rb +19 -15
  109. data/lib/action_dispatch/middleware/session/abstract_store.rb +38 -34
  110. data/lib/action_dispatch/middleware/session/cache_store.rb +14 -9
  111. data/lib/action_dispatch/middleware/session/cookie_store.rb +94 -44
  112. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +15 -4
  113. data/lib/action_dispatch/middleware/show_exceptions.rb +36 -61
  114. data/lib/action_dispatch/middleware/ssl.rb +150 -0
  115. data/lib/action_dispatch/middleware/stack.rb +33 -41
  116. data/lib/action_dispatch/middleware/static.rb +92 -48
  117. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +22 -0
  118. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
  119. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +27 -0
  120. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  121. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +52 -0
  122. data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
  123. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +16 -0
  124. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
  125. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +21 -0
  126. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +13 -0
  127. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +134 -5
  128. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
  129. data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
  130. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +32 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
  132. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +6 -0
  135. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
  136. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  137. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +200 -0
  138. data/lib/action_dispatch/railtie.rb +29 -8
  139. data/lib/action_dispatch/request/session.rb +234 -0
  140. data/lib/action_dispatch/request/utils.rb +78 -0
  141. data/lib/action_dispatch/routing/endpoint.rb +17 -0
  142. data/lib/action_dispatch/routing/inspector.rb +225 -0
  143. data/lib/action_dispatch/routing/mapper.rb +1329 -582
  144. data/lib/action_dispatch/routing/polymorphic_routes.rb +237 -94
  145. data/lib/action_dispatch/routing/redirection.rb +120 -50
  146. data/lib/action_dispatch/routing/route_set.rb +545 -322
  147. data/lib/action_dispatch/routing/routes_proxy.rb +37 -7
  148. data/lib/action_dispatch/routing/url_for.rb +103 -34
  149. data/lib/action_dispatch/routing.rb +66 -99
  150. data/lib/action_dispatch/system_test_case.rb +147 -0
  151. data/lib/action_dispatch/system_testing/browser.rb +49 -0
  152. data/lib/action_dispatch/system_testing/driver.rb +59 -0
  153. data/lib/action_dispatch/system_testing/server.rb +31 -0
  154. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +96 -0
  155. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +31 -0
  156. data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +26 -0
  157. data/lib/action_dispatch/testing/assertion_response.rb +47 -0
  158. data/lib/action_dispatch/testing/assertions/response.rb +53 -42
  159. data/lib/action_dispatch/testing/assertions/routing.rb +79 -74
  160. data/lib/action_dispatch/testing/assertions.rb +15 -9
  161. data/lib/action_dispatch/testing/integration.rb +361 -207
  162. data/lib/action_dispatch/testing/request_encoder.rb +55 -0
  163. data/lib/action_dispatch/testing/test_process.rb +28 -19
  164. data/lib/action_dispatch/testing/test_request.rb +30 -33
  165. data/lib/action_dispatch/testing/test_response.rb +35 -11
  166. data/lib/action_dispatch.rb +42 -32
  167. data/lib/action_pack/gem_version.rb +17 -0
  168. data/lib/action_pack/version.rb +7 -7
  169. data/lib/action_pack.rb +4 -2
  170. metadata +116 -175
  171. data/lib/abstract_controller/layouts.rb +0 -423
  172. data/lib/abstract_controller/view_paths.rb +0 -96
  173. data/lib/action_controller/caching/actions.rb +0 -185
  174. data/lib/action_controller/caching/fragments.rb +0 -127
  175. data/lib/action_controller/caching/pages.rb +0 -187
  176. data/lib/action_controller/caching/sweeping.rb +0 -97
  177. data/lib/action_controller/deprecated/integration_test.rb +0 -2
  178. data/lib/action_controller/deprecated/performance_test.rb +0 -1
  179. data/lib/action_controller/deprecated.rb +0 -3
  180. data/lib/action_controller/metal/compatibility.rb +0 -65
  181. data/lib/action_controller/metal/hide_actions.rb +0 -41
  182. data/lib/action_controller/metal/rack_delegation.rb +0 -26
  183. data/lib/action_controller/metal/responder.rb +0 -286
  184. data/lib/action_controller/metal/session_management.rb +0 -14
  185. data/lib/action_controller/middleware.rb +0 -39
  186. data/lib/action_controller/railties/paths.rb +0 -25
  187. data/lib/action_controller/record_identifier.rb +0 -85
  188. data/lib/action_controller/vendor/html-scanner/html/document.rb +0 -68
  189. data/lib/action_controller/vendor/html-scanner/html/node.rb +0 -532
  190. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +0 -177
  191. data/lib/action_controller/vendor/html-scanner/html/selector.rb +0 -830
  192. data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +0 -107
  193. data/lib/action_controller/vendor/html-scanner/html/version.rb +0 -11
  194. data/lib/action_controller/vendor/html-scanner.rb +0 -20
  195. data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
  196. data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
  197. data/lib/action_dispatch/middleware/head.rb +0 -18
  198. data/lib/action_dispatch/middleware/params_parser.rb +0 -75
  199. data/lib/action_dispatch/middleware/rescue.rb +0 -26
  200. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +0 -31
  201. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +0 -26
  202. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +0 -10
  203. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +0 -2
  204. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +0 -15
  205. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +0 -17
  206. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +0 -2
  207. data/lib/action_dispatch/testing/assertions/dom.rb +0 -37
  208. data/lib/action_dispatch/testing/assertions/selector.rb +0 -435
  209. data/lib/action_dispatch/testing/assertions/tag.rb +0 -138
  210. data/lib/action_dispatch/testing/performance_test.rb +0 -10
  211. data/lib/action_view/asset_paths.rb +0 -142
  212. data/lib/action_view/base.rb +0 -220
  213. data/lib/action_view/buffers.rb +0 -43
  214. data/lib/action_view/context.rb +0 -36
  215. data/lib/action_view/flows.rb +0 -79
  216. data/lib/action_view/helpers/active_model_helper.rb +0 -50
  217. data/lib/action_view/helpers/asset_paths.rb +0 -7
  218. data/lib/action_view/helpers/asset_tag_helper.rb +0 -457
  219. data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
  220. data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
  221. data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
  222. data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
  223. data/lib/action_view/helpers/atom_feed_helper.rb +0 -200
  224. data/lib/action_view/helpers/cache_helper.rb +0 -64
  225. data/lib/action_view/helpers/capture_helper.rb +0 -203
  226. data/lib/action_view/helpers/controller_helper.rb +0 -25
  227. data/lib/action_view/helpers/csrf_helper.rb +0 -32
  228. data/lib/action_view/helpers/date_helper.rb +0 -1062
  229. data/lib/action_view/helpers/debug_helper.rb +0 -40
  230. data/lib/action_view/helpers/form_helper.rb +0 -1486
  231. data/lib/action_view/helpers/form_options_helper.rb +0 -658
  232. data/lib/action_view/helpers/form_tag_helper.rb +0 -685
  233. data/lib/action_view/helpers/javascript_helper.rb +0 -110
  234. data/lib/action_view/helpers/number_helper.rb +0 -622
  235. data/lib/action_view/helpers/output_safety_helper.rb +0 -38
  236. data/lib/action_view/helpers/record_tag_helper.rb +0 -111
  237. data/lib/action_view/helpers/rendering_helper.rb +0 -92
  238. data/lib/action_view/helpers/sanitize_helper.rb +0 -259
  239. data/lib/action_view/helpers/tag_helper.rb +0 -167
  240. data/lib/action_view/helpers/text_helper.rb +0 -426
  241. data/lib/action_view/helpers/translation_helper.rb +0 -91
  242. data/lib/action_view/helpers/url_helper.rb +0 -693
  243. data/lib/action_view/helpers.rb +0 -60
  244. data/lib/action_view/locale/en.yml +0 -160
  245. data/lib/action_view/log_subscriber.rb +0 -28
  246. data/lib/action_view/lookup_context.rb +0 -258
  247. data/lib/action_view/path_set.rb +0 -101
  248. data/lib/action_view/railtie.rb +0 -55
  249. data/lib/action_view/renderer/abstract_renderer.rb +0 -41
  250. data/lib/action_view/renderer/partial_renderer.rb +0 -415
  251. data/lib/action_view/renderer/renderer.rb +0 -61
  252. data/lib/action_view/renderer/streaming_template_renderer.rb +0 -106
  253. data/lib/action_view/renderer/template_renderer.rb +0 -95
  254. data/lib/action_view/template/error.rb +0 -128
  255. data/lib/action_view/template/handlers/builder.rb +0 -26
  256. data/lib/action_view/template/handlers/erb.rb +0 -125
  257. data/lib/action_view/template/handlers.rb +0 -50
  258. data/lib/action_view/template/resolver.rb +0 -298
  259. data/lib/action_view/template/text.rb +0 -30
  260. data/lib/action_view/template.rb +0 -337
  261. data/lib/action_view/test_case.rb +0 -246
  262. data/lib/action_view/testing/resolvers.rb +0 -49
  263. data/lib/action_view.rb +0 -84
  264. data/lib/sprockets/assets.rake +0 -99
  265. data/lib/sprockets/bootstrap.rb +0 -37
  266. data/lib/sprockets/compressors.rb +0 -83
  267. data/lib/sprockets/helpers/isolated_helper.rb +0 -13
  268. data/lib/sprockets/helpers/rails_helper.rb +0 -182
  269. data/lib/sprockets/helpers.rb +0 -6
  270. data/lib/sprockets/railtie.rb +0 -62
  271. data/lib/sprockets/static_compiler.rb +0 -56
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action_view"
4
+ require "action_controller"
5
+ require "action_controller/log_subscriber"
6
+
7
+ module ActionController
8
+ # API Controller is a lightweight version of <tt>ActionController::Base</tt>,
9
+ # created for applications that don't require all functionalities that a complete
10
+ # \Rails controller provides, allowing you to create controllers with just the
11
+ # features that you need for API only applications.
12
+ #
13
+ # An API Controller is different from a normal controller in the sense that
14
+ # by default it doesn't include a number of features that are usually required
15
+ # by browser access only: layouts and templates rendering, cookies, sessions,
16
+ # flash, assets, and so on. This makes the entire controller stack thinner,
17
+ # suitable for API applications. It doesn't mean you won't have such
18
+ # features if you need them: they're all available for you to include in
19
+ # your application, they're just not part of the default API controller stack.
20
+ #
21
+ # Normally, +ApplicationController+ is the only controller that inherits from
22
+ # <tt>ActionController::API</tt>. All other controllers in turn inherit from
23
+ # +ApplicationController+.
24
+ #
25
+ # A sample controller could look like this:
26
+ #
27
+ # class PostsController < ApplicationController
28
+ # def index
29
+ # posts = Post.all
30
+ # render json: posts
31
+ # end
32
+ # end
33
+ #
34
+ # Request, response, and parameters objects all work the exact same way as
35
+ # <tt>ActionController::Base</tt>.
36
+ #
37
+ # == Renders
38
+ #
39
+ # The default API Controller stack includes all renderers, which means you
40
+ # can use <tt>render :json</tt> and brothers freely in your controllers. Keep
41
+ # in mind that templates are not going to be rendered, so you need to ensure
42
+ # your controller is calling either <tt>render</tt> or <tt>redirect_to</tt> in
43
+ # all actions, otherwise it will return 204 No Content.
44
+ #
45
+ # def show
46
+ # post = Post.find(params[:id])
47
+ # render json: post
48
+ # end
49
+ #
50
+ # == Redirects
51
+ #
52
+ # Redirects are used to move from one action to another. You can use the
53
+ # <tt>redirect_to</tt> method in your controllers in the same way as in
54
+ # <tt>ActionController::Base</tt>. For example:
55
+ #
56
+ # def create
57
+ # redirect_to root_url and return if not_authorized?
58
+ # # do stuff here
59
+ # end
60
+ #
61
+ # == Adding New Behavior
62
+ #
63
+ # In some scenarios you may want to add back some functionality provided by
64
+ # <tt>ActionController::Base</tt> that is not present by default in
65
+ # <tt>ActionController::API</tt>, for instance <tt>MimeResponds</tt>. This
66
+ # module gives you the <tt>respond_to</tt> method. Adding it is quite simple,
67
+ # you just need to include the module in a specific controller or in
68
+ # +ApplicationController+ in case you want it available in your entire
69
+ # application:
70
+ #
71
+ # class ApplicationController < ActionController::API
72
+ # include ActionController::MimeResponds
73
+ # end
74
+ #
75
+ # class PostsController < ApplicationController
76
+ # def index
77
+ # posts = Post.all
78
+ #
79
+ # respond_to do |format|
80
+ # format.json { render json: posts }
81
+ # format.xml { render xml: posts }
82
+ # end
83
+ # end
84
+ # end
85
+ #
86
+ # Make sure to check the modules included in <tt>ActionController::Base</tt>
87
+ # if you want to use any other functionality that is not provided
88
+ # by <tt>ActionController::API</tt> out of the box.
89
+ class API < Metal
90
+ abstract!
91
+
92
+ # Shortcut helper that returns all the ActionController::API modules except
93
+ # the ones passed as arguments:
94
+ #
95
+ # class MyAPIBaseController < ActionController::Metal
96
+ # ActionController::API.without_modules(:ForceSSL, :UrlFor).each do |left|
97
+ # include left
98
+ # end
99
+ # end
100
+ #
101
+ # This gives better control over what you want to exclude and makes it easier
102
+ # to create an API controller class, instead of listing the modules required
103
+ # manually.
104
+ def self.without_modules(*modules)
105
+ modules = modules.map do |m|
106
+ m.is_a?(Symbol) ? ActionController.const_get(m) : m
107
+ end
108
+
109
+ MODULES - modules
110
+ end
111
+
112
+ MODULES = [
113
+ AbstractController::Rendering,
114
+
115
+ UrlFor,
116
+ Redirecting,
117
+ ApiRendering,
118
+ Renderers::All,
119
+ ConditionalGet,
120
+ BasicImplicitRender,
121
+ StrongParameters,
122
+
123
+ ForceSSL,
124
+ DataStreaming,
125
+
126
+ # Before callbacks should also be executed as early as possible, so
127
+ # also include them at the bottom.
128
+ AbstractController::Callbacks,
129
+
130
+ # Append rescue at the bottom to wrap as much as possible.
131
+ Rescue,
132
+
133
+ # Add instrumentations hooks at the bottom, to ensure they instrument
134
+ # all the methods properly.
135
+ Instrumentation,
136
+
137
+ # Params wrapper should come before instrumentation so they are
138
+ # properly showed in logs
139
+ ParamsWrapper
140
+ ]
141
+
142
+ MODULES.each do |mod|
143
+ include mod
144
+ end
145
+
146
+ ActiveSupport.run_load_hooks(:action_controller_api, self)
147
+ ActiveSupport.run_load_hooks(:action_controller, self)
148
+ end
149
+ end
@@ -1,12 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action_view"
1
4
  require "action_controller/log_subscriber"
5
+ require "action_controller/metal/params_wrapper"
2
6
 
3
7
  module ActionController
4
8
  # Action Controllers are the core of a web request in \Rails. They are made up of one or more actions that are executed
5
- # on request and then either render a template or redirect to another action. An action is defined as a public method
9
+ # on request and then either it renders a template or redirects to another action. An action is defined as a public method
6
10
  # on the controller, which will automatically be made accessible to the web-server through \Rails Routes.
7
11
  #
8
12
  # By default, only the ApplicationController in a \Rails application inherits from <tt>ActionController::Base</tt>. All other
9
- # controllers in turn inherit from ApplicationController. This gives you one class to configure things such as
13
+ # controllers inherit from ApplicationController. This gives you one class to configure things such as
10
14
  # request forgery protection and filtering of sensitive request parameters.
11
15
  #
12
16
  # A sample controller could look like this:
@@ -28,9 +32,9 @@ module ActionController
28
32
  #
29
33
  # Unlike index, the create action will not render a template. After performing its main purpose (creating a
30
34
  # new post), it initiates a redirect instead. This redirect works by returning an external
31
- # "302 Moved" HTTP response that takes the user to the index action.
35
+ # <tt>302 Moved</tt> HTTP response that takes the user to the index action.
32
36
  #
33
- # These two methods represent the two basic action archetypes used in Action Controllers. Get-and-show and do-and-redirect.
37
+ # These two methods represent the two basic action archetypes used in Action Controllers: Get-and-show and do-and-redirect.
34
38
  # Most actions are variations on these themes.
35
39
  #
36
40
  # == Requests
@@ -42,23 +46,23 @@ module ActionController
42
46
  # The full request object is available via the request accessor and is primarily used to query for HTTP headers:
43
47
  #
44
48
  # def server_ip
45
- # location = request.env["SERVER_ADDR"]
46
- # render :text => "This server hosted at #{location}"
49
+ # location = request.env["REMOTE_ADDR"]
50
+ # render plain: "This server hosted at #{location}"
47
51
  # end
48
52
  #
49
53
  # == Parameters
50
54
  #
51
- # All request parameters, whether they come from a GET or POST request, or from the URL, are available through the params method
52
- # which returns a hash. For example, an action that was performed through <tt>/posts?category=All&limit=5</tt> will include
53
- # <tt>{ "category" => "All", "limit" => "5" }</tt> in params.
55
+ # All request parameters, whether they come from a query string in the URL or form data submitted through a POST request are
56
+ # available through the <tt>params</tt> method which returns a hash. For example, an action that was performed through
57
+ # <tt>/posts?category=All&limit=5</tt> will include <tt>{ "category" => "All", "limit" => "5" }</tt> in <tt>params</tt>.
54
58
  #
55
59
  # It's also possible to construct multi-dimensional parameter hashes by specifying keys using brackets, such as:
56
60
  #
57
61
  # <input type="text" name="post[name]" value="david">
58
62
  # <input type="text" name="post[address]" value="hyacintvej">
59
63
  #
60
- # A request stemming from a form holding these inputs will include <tt>{ "post" => { "name" => "david", "address" => "hyacintvej" } }</tt>.
61
- # If the address input had been named "post[address][street]", the params would have included
64
+ # A request coming from a form holding these inputs will include <tt>{ "post" => { "name" => "david", "address" => "hyacintvej" } }</tt>.
65
+ # If the address input had been named <tt>post[address][street]</tt>, the <tt>params</tt> would have included
62
66
  # <tt>{ "post" => { "address" => { "street" => "hyacintvej" } } }</tt>. There's no limit to the depth of the nesting.
63
67
  #
64
68
  # == Sessions
@@ -72,7 +76,7 @@ module ActionController
72
76
  #
73
77
  # session[:person] = Person.authenticate(user_name, password)
74
78
  #
75
- # And retrieved again through the same hash:
79
+ # You can retrieve it again through the same hash:
76
80
  #
77
81
  # Hello #{session[:person]}
78
82
  #
@@ -84,19 +88,10 @@ module ActionController
84
88
  # or you can remove the entire session with +reset_session+.
85
89
  #
86
90
  # Sessions are stored by default in a browser cookie that's cryptographically signed, but unencrypted.
87
- # This prevents the user from tampering with the session but also allows him to see its contents.
91
+ # This prevents the user from tampering with the session but also allows them to see its contents.
88
92
  #
89
93
  # Do not put secret information in cookie-based sessions!
90
94
  #
91
- # Other options for session storage:
92
- #
93
- # * ActiveRecord::SessionStore - Sessions are stored in your database, which works better than PStore with multiple app servers and,
94
- # unlike CookieStore, hides your session contents from the user. To use ActiveRecord::SessionStore, set
95
- #
96
- # MyApplication::Application.config.session_store :active_record_store
97
- #
98
- # in your <tt>config/initializers/session_store.rb</tt> and run <tt>script/rails g session_migration</tt>.
99
- #
100
95
  # == Responses
101
96
  #
102
97
  # Each action results in a response, which holds the headers and document to be sent to the user's browser. The actual response
@@ -116,15 +111,15 @@ module ActionController
116
111
  #
117
112
  # Title: <%= @post.title %>
118
113
  #
119
- # You don't have to rely on the automated rendering. For example, actions that could result in the rendering of different templates
114
+ # You don't have to rely on the automated rendering. For example, actions that could result in the rendering of different templates
120
115
  # will use the manual rendering methods:
121
116
  #
122
117
  # def search
123
118
  # @results = Search.find(params[:query])
124
119
  # case @results.count
125
- # when 0 then render :action => "no_results"
126
- # when 1 then render :action => "show"
127
- # when 2..10 then render :action => "show_many"
120
+ # when 0 then render action: "no_results"
121
+ # when 1 then render action: "show"
122
+ # when 2..10 then render action: "show_many"
128
123
  # end
129
124
  # end
130
125
  #
@@ -133,14 +128,14 @@ module ActionController
133
128
  # == Redirects
134
129
  #
135
130
  # Redirects are used to move from one action to another. For example, after a <tt>create</tt> action, which stores a blog entry to the
136
- # database, we might like to show the user the new entry. Because we're following good DRY principles (Don't Repeat Yourself), we're
131
+ # database, we might like to show the user the new entry. Because we're following good DRY principles (Don't Repeat Yourself), we're
137
132
  # going to reuse (and redirect to) a <tt>show</tt> action that we'll assume has already been created. The code might look like this:
138
133
  #
139
134
  # def create
140
135
  # @entry = Entry.new(params[:entry])
141
136
  # if @entry.save
142
137
  # # The entry was saved correctly, redirect to show
143
- # redirect_to :action => 'show', :id => @entry.id
138
+ # redirect_to action: 'show', id: @entry.id
144
139
  # else
145
140
  # # things didn't go so well, do something else
146
141
  # end
@@ -157,20 +152,48 @@ module ActionController
157
152
  # An action may contain only a single render or a single redirect. Attempting to try to do either again will result in a DoubleRenderError:
158
153
  #
159
154
  # def do_something
160
- # redirect_to :action => "elsewhere"
161
- # render :action => "overthere" # raises DoubleRenderError
155
+ # redirect_to action: "elsewhere"
156
+ # render action: "overthere" # raises DoubleRenderError
162
157
  # end
163
158
  #
164
159
  # If you need to redirect on the condition of something, then be sure to add "and return" to halt execution.
165
160
  #
166
161
  # def do_something
167
- # redirect_to(:action => "elsewhere") and return if monkeys.nil?
168
- # render :action => "overthere" # won't be called if monkeys is nil
162
+ # redirect_to(action: "elsewhere") and return if monkeys.nil?
163
+ # render action: "overthere" # won't be called if monkeys is nil
169
164
  # end
170
165
  #
171
166
  class Base < Metal
172
167
  abstract!
173
168
 
169
+ # We document the request and response methods here because albeit they are
170
+ # implemented in ActionController::Metal, the type of the returned objects
171
+ # is unknown at that level.
172
+
173
+ ##
174
+ # :method: request
175
+ #
176
+ # Returns an ActionDispatch::Request instance that represents the
177
+ # current request.
178
+
179
+ ##
180
+ # :method: response
181
+ #
182
+ # Returns an ActionDispatch::Response that represents the current
183
+ # response.
184
+
185
+ # Shortcut helper that returns all the modules included in
186
+ # ActionController::Base except the ones passed as arguments:
187
+ #
188
+ # class MyBaseController < ActionController::Metal
189
+ # ActionController::Base.without_modules(:ParamsWrapper, :Streaming).each do |left|
190
+ # include left
191
+ # end
192
+ # end
193
+ #
194
+ # This gives better control over what you want to exclude and makes it
195
+ # easier to create a bare controller class, instead of listing the modules
196
+ # required manually.
174
197
  def self.without_modules(*modules)
175
198
  modules = modules.map do |m|
176
199
  m.is_a?(Symbol) ? ActionController.const_get(m) : m
@@ -180,34 +203,37 @@ module ActionController
180
203
  end
181
204
 
182
205
  MODULES = [
183
- AbstractController::Layouts,
206
+ AbstractController::Rendering,
184
207
  AbstractController::Translation,
185
208
  AbstractController::AssetPaths,
186
209
 
187
210
  Helpers,
188
- HideActions,
189
211
  UrlFor,
190
212
  Redirecting,
213
+ ActionView::Layouts,
191
214
  Rendering,
192
215
  Renderers::All,
193
216
  ConditionalGet,
194
- RackDelegation,
217
+ EtagWithTemplateDigest,
218
+ EtagWithFlash,
195
219
  Caching,
196
220
  MimeResponds,
197
221
  ImplicitRender,
198
-
222
+ StrongParameters,
223
+ ParameterEncoding,
199
224
  Cookies,
200
225
  Flash,
226
+ FormBuilder,
201
227
  RequestForgeryProtection,
228
+ ContentSecurityPolicy,
202
229
  ForceSSL,
203
230
  Streaming,
204
231
  DataStreaming,
205
- RecordIdentifier,
206
232
  HttpAuthentication::Basic::ControllerMethods,
207
233
  HttpAuthentication::Digest::ControllerMethods,
208
234
  HttpAuthentication::Token::ControllerMethods,
209
235
 
210
- # Before callbacks should also be executed the earliest as possible, so
236
+ # Before callbacks should also be executed as early as possible, so
211
237
  # also include them at the bottom.
212
238
  AbstractController::Callbacks,
213
239
 
@@ -226,10 +252,25 @@ module ActionController
226
252
  MODULES.each do |mod|
227
253
  include mod
228
254
  end
255
+ setup_renderer!
229
256
 
230
- # Rails 2.x compatibility
231
- include ActionController::Compatibility
257
+ # Define some internal variables that should not be propagated to the view.
258
+ PROTECTED_IVARS = AbstractController::Rendering::DEFAULT_PROTECTED_INSTANCE_VARIABLES + %i(
259
+ @_params @_response @_request @_config @_url_options @_action_has_layout @_view_context_class
260
+ @_view_renderer @_lookup_context @_routes @_view_runtime @_db_runtime @_helper_proxy
261
+ )
262
+
263
+ def _protected_ivars # :nodoc:
264
+ PROTECTED_IVARS
265
+ end
266
+
267
+ def self.make_response!(request)
268
+ ActionDispatch::Response.create.tap do |res|
269
+ res.request = request
270
+ end
271
+ end
232
272
 
273
+ ActiveSupport.run_load_hooks(:action_controller_base, self)
233
274
  ActiveSupport.run_load_hooks(:action_controller, self)
234
275
  end
235
276
  end
@@ -1,86 +1,46 @@
1
- require 'fileutils'
2
- require 'uri'
3
- require 'set'
1
+ # frozen_string_literal: true
4
2
 
5
- module ActionController #:nodoc:
3
+ module ActionController
6
4
  # \Caching is a cheap way of speeding up slow applications by keeping the result of
7
5
  # calculations, renderings, and database calls around for subsequent requests.
8
- # Action Controller affords you three approaches in varying levels of granularity:
9
- # Page, Action, Fragment.
10
6
  #
11
- # You can read more about each approach and the sweeping assistance by clicking the
12
- # modules below.
7
+ # You can read more about each approach by clicking the modules below.
13
8
  #
14
- # Note: To turn off all caching and sweeping, set
15
- # config.action_controller.perform_caching = false.
9
+ # Note: To turn off all caching provided by Action Controller, set
10
+ # config.action_controller.perform_caching = false
16
11
  #
17
12
  # == \Caching stores
18
13
  #
19
14
  # All the caching stores from ActiveSupport::Cache are available to be used as backends
20
- # for Action Controller caching. This setting only affects action and fragment caching
21
- # as page caching is always written to disk.
15
+ # for Action Controller caching.
22
16
  #
23
- # Configuration examples (MemoryStore is the default):
17
+ # Configuration examples (FileStore is the default):
24
18
  #
25
19
  # config.action_controller.cache_store = :memory_store
26
- # config.action_controller.cache_store = :file_store, "/path/to/cache/directory"
27
- # config.action_controller.cache_store = :mem_cache_store, "localhost"
28
- # config.action_controller.cache_store = :mem_cache_store, Memcached::Rails.new("localhost:11211")
29
- # config.action_controller.cache_store = MyOwnStore.new("parameter")
20
+ # config.action_controller.cache_store = :file_store, '/path/to/cache/directory'
21
+ # config.action_controller.cache_store = :mem_cache_store, 'localhost'
22
+ # config.action_controller.cache_store = :mem_cache_store, Memcached::Rails.new('localhost:11211')
23
+ # config.action_controller.cache_store = MyOwnStore.new('parameter')
30
24
  module Caching
31
- extend ActiveSupport::Concern
32
25
  extend ActiveSupport::Autoload
26
+ extend ActiveSupport::Concern
33
27
 
34
- eager_autoload do
35
- autoload :Actions
36
- autoload :Fragments
37
- autoload :Pages
38
- autoload :Sweeper, 'action_controller/caching/sweeping'
39
- autoload :Sweeping, 'action_controller/caching/sweeping'
28
+ included do
29
+ include AbstractController::Caching
40
30
  end
41
31
 
42
- module ConfigMethods
43
- def cache_store
44
- config.cache_store
45
- end
46
-
47
- def cache_store=(store)
48
- config.cache_store = ActiveSupport::Cache.lookup_store(store)
49
- end
50
-
51
32
  private
52
33
 
53
- def cache_configured?
54
- perform_caching && cache_store
34
+ def instrument_payload(key)
35
+ {
36
+ controller: controller_name,
37
+ action: action_name,
38
+ key: key
39
+ }
55
40
  end
56
- end
57
-
58
- include RackDelegation
59
- include AbstractController::Callbacks
60
41
 
61
- include ConfigMethods
62
- include Pages, Actions, Fragments
63
- include Sweeping if defined?(ActiveRecord)
64
-
65
- included do
66
- extend ConfigMethods
67
-
68
- config_accessor :perform_caching
69
- self.perform_caching = true if perform_caching.nil?
70
- end
71
-
72
- def caching_allowed?
73
- request.get? && response.status == 200
74
- end
75
-
76
- protected
77
- # Convenience accessor
78
- def cache(key, options = {}, &block)
79
- if cache_configured?
80
- cache_store.fetch(ActiveSupport::Cache.expand_cache_key(key, :controller), options, &block)
81
- else
82
- yield
42
+ def instrument_name
43
+ "action_controller".freeze
83
44
  end
84
- end
85
45
  end
86
46
  end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionController
4
+ # Override the default form builder for all views rendered by this
5
+ # controller and any of its descendants. Accepts a subclass of
6
+ # +ActionView::Helpers::FormBuilder+.
7
+ #
8
+ # For example, given a form builder:
9
+ #
10
+ # class AdminFormBuilder < ActionView::Helpers::FormBuilder
11
+ # def special_field(name)
12
+ # end
13
+ # end
14
+ #
15
+ # The controller specifies a form builder as its default:
16
+ #
17
+ # class AdminAreaController < ApplicationController
18
+ # default_form_builder AdminFormBuilder
19
+ # end
20
+ #
21
+ # Then in the view any form using +form_for+ will be an instance of the
22
+ # specified form builder:
23
+ #
24
+ # <%= form_for(@instance) do |builder| %>
25
+ # <%= builder.special_field(:name) %>
26
+ # <% end %>
27
+ module FormBuilder
28
+ extend ActiveSupport::Concern
29
+
30
+ included do
31
+ class_attribute :_default_form_builder, instance_accessor: false
32
+ end
33
+
34
+ module ClassMethods
35
+ # Set the form builder to be used as the default for all forms
36
+ # in the views rendered by this controller and its subclasses.
37
+ #
38
+ # ==== Parameters
39
+ # * <tt>builder</tt> - Default form builder, an instance of +ActionView::Helpers::FormBuilder+
40
+ def default_form_builder(builder)
41
+ self._default_form_builder = builder
42
+ end
43
+ end
44
+
45
+ # Default form builder for the controller
46
+ def default_form_builder
47
+ self.class._default_form_builder
48
+ end
49
+ end
50
+ end
@@ -1,10 +1,12 @@
1
- require 'active_support/core_ext/object/blank'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module ActionController
4
4
  class LogSubscriber < ActiveSupport::LogSubscriber
5
5
  INTERNAL_PARAMS = %w(controller action format _method only_path)
6
6
 
7
7
  def start_processing(event)
8
+ return unless logger.info?
9
+
8
10
  payload = event.payload
9
11
  params = payload[:params].except(*INTERNAL_PARAMS)
10
12
  format = payload[:format]
@@ -15,44 +17,54 @@ module ActionController
15
17
  end
16
18
 
17
19
  def process_action(event)
18
- payload = event.payload
19
- additions = ActionController::Base.log_process_action(payload)
20
+ info do
21
+ payload = event.payload
22
+ additions = ActionController::Base.log_process_action(payload)
20
23
 
21
- status = payload[:status]
22
- if status.nil? && payload[:exception].present?
23
- exception_class_name = payload[:exception].first
24
- status = ActionDispatch::ExceptionWrapper.status_code_for_exception(exception_class_name)
25
- end
26
- message = "Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{format_duration(event.duration)}"
27
- message << " (#{additions.join(" | ")})" unless additions.blank?
24
+ status = payload[:status]
25
+ if status.nil? && payload[:exception].present?
26
+ exception_class_name = payload[:exception].first
27
+ status = ActionDispatch::ExceptionWrapper.status_code_for_exception(exception_class_name)
28
+ end
29
+ message = "Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{event.duration.round}ms".dup
30
+ message << " (#{additions.join(" | ".freeze)})" unless additions.empty?
31
+ message << "\n\n" if defined?(Rails.env) && Rails.env.development?
28
32
 
29
- info(message)
33
+ message
34
+ end
30
35
  end
31
36
 
32
37
  def halted_callback(event)
33
- info "Filter chain halted as #{event.payload[:filter]} rendered or redirected"
38
+ info { "Filter chain halted as #{event.payload[:filter].inspect} rendered or redirected" }
34
39
  end
35
40
 
36
41
  def send_file(event)
37
- info("Sent file #{event.payload[:path]} (#{format_duration(event.duration)})")
42
+ info { "Sent file #{event.payload[:path]} (#{event.duration.round(1)}ms)" }
38
43
  end
39
44
 
40
45
  def redirect_to(event)
41
- info "Redirected to #{event.payload[:location]}"
46
+ info { "Redirected to #{event.payload[:location]}" }
42
47
  end
43
48
 
44
49
  def send_data(event)
45
- info("Sent data #{event.payload[:filename]} (#{format_duration(event.duration)})")
50
+ info { "Sent data #{event.payload[:filename]} (#{event.duration.round(1)}ms)" }
51
+ end
52
+
53
+ def unpermitted_parameters(event)
54
+ debug do
55
+ unpermitted_keys = event.payload[:keys]
56
+ "Unpermitted parameter#{'s' if unpermitted_keys.size > 1}: #{unpermitted_keys.map { |e| ":#{e}" }.join(", ")}"
57
+ end
46
58
  end
47
59
 
48
60
  %w(write_fragment read_fragment exist_fragment?
49
61
  expire_fragment expire_page write_page).each do |method|
50
62
  class_eval <<-METHOD, __FILE__, __LINE__ + 1
51
63
  def #{method}(event)
52
- key_or_path = event.payload[:key] || event.payload[:path]
64
+ return unless logger.info? && ActionController::Base.enable_fragment_cache_logging
65
+ key = ActiveSupport::Cache.expand_cache_key(event.payload[:key] || event.payload[:path])
53
66
  human_name = #{method.to_s.humanize.inspect}
54
- duration = format_duration(event.duration)
55
- info("\#{human_name} \#{key_or_path} \#{duration}")
67
+ info("\#{human_name} \#{key} (\#{event.duration.round(1)}ms)")
56
68
  end
57
69
  METHOD
58
70
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionController
4
+ module BasicImplicitRender # :nodoc:
5
+ def send_action(method, *args)
6
+ super.tap { default_render unless performed? }
7
+ end
8
+
9
+ def default_render(*args)
10
+ head :no_content
11
+ end
12
+ end
13
+ end