actionpack 5.2.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 (170) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +429 -0
  3. data/MIT-LICENSE +21 -0
  4. data/README.rdoc +57 -0
  5. data/lib/abstract_controller.rb +27 -0
  6. data/lib/abstract_controller/asset_paths.rb +12 -0
  7. data/lib/abstract_controller/base.rb +265 -0
  8. data/lib/abstract_controller/caching.rb +66 -0
  9. data/lib/abstract_controller/caching/fragments.rb +166 -0
  10. data/lib/abstract_controller/callbacks.rb +212 -0
  11. data/lib/abstract_controller/collector.rb +43 -0
  12. data/lib/abstract_controller/error.rb +6 -0
  13. data/lib/abstract_controller/helpers.rb +194 -0
  14. data/lib/abstract_controller/logger.rb +14 -0
  15. data/lib/abstract_controller/railties/routes_helpers.rb +20 -0
  16. data/lib/abstract_controller/rendering.rb +127 -0
  17. data/lib/abstract_controller/translation.rb +31 -0
  18. data/lib/abstract_controller/url_for.rb +35 -0
  19. data/lib/action_controller.rb +66 -0
  20. data/lib/action_controller/api.rb +149 -0
  21. data/lib/action_controller/api/api_rendering.rb +16 -0
  22. data/lib/action_controller/base.rb +276 -0
  23. data/lib/action_controller/caching.rb +46 -0
  24. data/lib/action_controller/form_builder.rb +50 -0
  25. data/lib/action_controller/log_subscriber.rb +78 -0
  26. data/lib/action_controller/metal.rb +256 -0
  27. data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
  28. data/lib/action_controller/metal/conditional_get.rb +274 -0
  29. data/lib/action_controller/metal/content_security_policy.rb +52 -0
  30. data/lib/action_controller/metal/cookies.rb +16 -0
  31. data/lib/action_controller/metal/data_streaming.rb +152 -0
  32. data/lib/action_controller/metal/etag_with_flash.rb +18 -0
  33. data/lib/action_controller/metal/etag_with_template_digest.rb +57 -0
  34. data/lib/action_controller/metal/exceptions.rb +53 -0
  35. data/lib/action_controller/metal/flash.rb +61 -0
  36. data/lib/action_controller/metal/force_ssl.rb +99 -0
  37. data/lib/action_controller/metal/head.rb +60 -0
  38. data/lib/action_controller/metal/helpers.rb +123 -0
  39. data/lib/action_controller/metal/http_authentication.rb +519 -0
  40. data/lib/action_controller/metal/implicit_render.rb +73 -0
  41. data/lib/action_controller/metal/instrumentation.rb +107 -0
  42. data/lib/action_controller/metal/live.rb +312 -0
  43. data/lib/action_controller/metal/mime_responds.rb +313 -0
  44. data/lib/action_controller/metal/parameter_encoding.rb +51 -0
  45. data/lib/action_controller/metal/params_wrapper.rb +293 -0
  46. data/lib/action_controller/metal/redirecting.rb +133 -0
  47. data/lib/action_controller/metal/renderers.rb +181 -0
  48. data/lib/action_controller/metal/rendering.rb +122 -0
  49. data/lib/action_controller/metal/request_forgery_protection.rb +445 -0
  50. data/lib/action_controller/metal/rescue.rb +28 -0
  51. data/lib/action_controller/metal/streaming.rb +223 -0
  52. data/lib/action_controller/metal/strong_parameters.rb +1086 -0
  53. data/lib/action_controller/metal/testing.rb +16 -0
  54. data/lib/action_controller/metal/url_for.rb +58 -0
  55. data/lib/action_controller/railtie.rb +89 -0
  56. data/lib/action_controller/railties/helpers.rb +24 -0
  57. data/lib/action_controller/renderer.rb +117 -0
  58. data/lib/action_controller/template_assertions.rb +11 -0
  59. data/lib/action_controller/test_case.rb +629 -0
  60. data/lib/action_dispatch.rb +112 -0
  61. data/lib/action_dispatch/http/cache.rb +222 -0
  62. data/lib/action_dispatch/http/content_security_policy.rb +272 -0
  63. data/lib/action_dispatch/http/filter_parameters.rb +84 -0
  64. data/lib/action_dispatch/http/filter_redirect.rb +37 -0
  65. data/lib/action_dispatch/http/headers.rb +132 -0
  66. data/lib/action_dispatch/http/mime_negotiation.rb +175 -0
  67. data/lib/action_dispatch/http/mime_type.rb +342 -0
  68. data/lib/action_dispatch/http/mime_types.rb +50 -0
  69. data/lib/action_dispatch/http/parameter_filter.rb +86 -0
  70. data/lib/action_dispatch/http/parameters.rb +126 -0
  71. data/lib/action_dispatch/http/rack_cache.rb +63 -0
  72. data/lib/action_dispatch/http/request.rb +430 -0
  73. data/lib/action_dispatch/http/response.rb +519 -0
  74. data/lib/action_dispatch/http/upload.rb +84 -0
  75. data/lib/action_dispatch/http/url.rb +350 -0
  76. data/lib/action_dispatch/journey.rb +7 -0
  77. data/lib/action_dispatch/journey/formatter.rb +189 -0
  78. data/lib/action_dispatch/journey/gtg/builder.rb +164 -0
  79. data/lib/action_dispatch/journey/gtg/simulator.rb +41 -0
  80. data/lib/action_dispatch/journey/gtg/transition_table.rb +158 -0
  81. data/lib/action_dispatch/journey/nfa/builder.rb +78 -0
  82. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  83. data/lib/action_dispatch/journey/nfa/simulator.rb +49 -0
  84. data/lib/action_dispatch/journey/nfa/transition_table.rb +120 -0
  85. data/lib/action_dispatch/journey/nodes/node.rb +140 -0
  86. data/lib/action_dispatch/journey/parser.rb +199 -0
  87. data/lib/action_dispatch/journey/parser.y +50 -0
  88. data/lib/action_dispatch/journey/parser_extras.rb +31 -0
  89. data/lib/action_dispatch/journey/path/pattern.rb +198 -0
  90. data/lib/action_dispatch/journey/route.rb +203 -0
  91. data/lib/action_dispatch/journey/router.rb +156 -0
  92. data/lib/action_dispatch/journey/router/utils.rb +102 -0
  93. data/lib/action_dispatch/journey/routes.rb +82 -0
  94. data/lib/action_dispatch/journey/scanner.rb +64 -0
  95. data/lib/action_dispatch/journey/visitors.rb +268 -0
  96. data/lib/action_dispatch/journey/visualizer/fsm.css +30 -0
  97. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  98. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  99. data/lib/action_dispatch/middleware/callbacks.rb +36 -0
  100. data/lib/action_dispatch/middleware/cookies.rb +685 -0
  101. data/lib/action_dispatch/middleware/debug_exceptions.rb +205 -0
  102. data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
  103. data/lib/action_dispatch/middleware/exception_wrapper.rb +147 -0
  104. data/lib/action_dispatch/middleware/executor.rb +21 -0
  105. data/lib/action_dispatch/middleware/flash.rb +300 -0
  106. data/lib/action_dispatch/middleware/public_exceptions.rb +57 -0
  107. data/lib/action_dispatch/middleware/reloader.rb +12 -0
  108. data/lib/action_dispatch/middleware/remote_ip.rb +183 -0
  109. data/lib/action_dispatch/middleware/request_id.rb +43 -0
  110. data/lib/action_dispatch/middleware/session/abstract_store.rb +92 -0
  111. data/lib/action_dispatch/middleware/session/cache_store.rb +54 -0
  112. data/lib/action_dispatch/middleware/session/cookie_store.rb +118 -0
  113. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +28 -0
  114. data/lib/action_dispatch/middleware/show_exceptions.rb +62 -0
  115. data/lib/action_dispatch/middleware/ssl.rb +150 -0
  116. data/lib/action_dispatch/middleware/stack.rb +116 -0
  117. data/lib/action_dispatch/middleware/static.rb +130 -0
  118. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +22 -0
  119. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
  120. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +27 -0
  121. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  122. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +52 -0
  123. data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
  124. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +16 -0
  125. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
  126. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +21 -0
  127. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +13 -0
  128. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +161 -0
  129. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
  130. data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +32 -0
  132. data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
  135. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +6 -0
  136. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
  137. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  138. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +200 -0
  139. data/lib/action_dispatch/railtie.rb +55 -0
  140. data/lib/action_dispatch/request/session.rb +234 -0
  141. data/lib/action_dispatch/request/utils.rb +78 -0
  142. data/lib/action_dispatch/routing.rb +260 -0
  143. data/lib/action_dispatch/routing/endpoint.rb +17 -0
  144. data/lib/action_dispatch/routing/inspector.rb +225 -0
  145. data/lib/action_dispatch/routing/mapper.rb +2267 -0
  146. data/lib/action_dispatch/routing/polymorphic_routes.rb +352 -0
  147. data/lib/action_dispatch/routing/redirection.rb +201 -0
  148. data/lib/action_dispatch/routing/route_set.rb +890 -0
  149. data/lib/action_dispatch/routing/routes_proxy.rb +69 -0
  150. data/lib/action_dispatch/routing/url_for.rb +236 -0
  151. data/lib/action_dispatch/system_test_case.rb +147 -0
  152. data/lib/action_dispatch/system_testing/browser.rb +49 -0
  153. data/lib/action_dispatch/system_testing/driver.rb +59 -0
  154. data/lib/action_dispatch/system_testing/server.rb +31 -0
  155. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +96 -0
  156. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +31 -0
  157. data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +26 -0
  158. data/lib/action_dispatch/testing/assertion_response.rb +47 -0
  159. data/lib/action_dispatch/testing/assertions.rb +24 -0
  160. data/lib/action_dispatch/testing/assertions/response.rb +107 -0
  161. data/lib/action_dispatch/testing/assertions/routing.rb +222 -0
  162. data/lib/action_dispatch/testing/integration.rb +652 -0
  163. data/lib/action_dispatch/testing/request_encoder.rb +55 -0
  164. data/lib/action_dispatch/testing/test_process.rb +50 -0
  165. data/lib/action_dispatch/testing/test_request.rb +71 -0
  166. data/lib/action_dispatch/testing/test_response.rb +53 -0
  167. data/lib/action_pack.rb +26 -0
  168. data/lib/action_pack/gem_version.rb +17 -0
  169. data/lib/action_pack/version.rb +10 -0
  170. metadata +318 -0
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionController
4
+ module ApiRendering
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ include Rendering
9
+ end
10
+
11
+ def render_to_body(options = {})
12
+ _process_options(options)
13
+ super
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,276 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action_view"
4
+ require "action_controller/log_subscriber"
5
+ require "action_controller/metal/params_wrapper"
6
+
7
+ module ActionController
8
+ # Action Controllers are the core of a web request in \Rails. They are made up of one or more actions that are executed
9
+ # on request and then either it renders a template or redirects to another action. An action is defined as a public method
10
+ # on the controller, which will automatically be made accessible to the web-server through \Rails Routes.
11
+ #
12
+ # By default, only the ApplicationController in a \Rails application inherits from <tt>ActionController::Base</tt>. All other
13
+ # controllers inherit from ApplicationController. This gives you one class to configure things such as
14
+ # request forgery protection and filtering of sensitive request parameters.
15
+ #
16
+ # A sample controller could look like this:
17
+ #
18
+ # class PostsController < ApplicationController
19
+ # def index
20
+ # @posts = Post.all
21
+ # end
22
+ #
23
+ # def create
24
+ # @post = Post.create params[:post]
25
+ # redirect_to posts_path
26
+ # end
27
+ # end
28
+ #
29
+ # Actions, by default, render a template in the <tt>app/views</tt> directory corresponding to the name of the controller and action
30
+ # after executing code in the action. For example, the +index+ action of the PostsController would render the
31
+ # template <tt>app/views/posts/index.html.erb</tt> by default after populating the <tt>@posts</tt> instance variable.
32
+ #
33
+ # Unlike index, the create action will not render a template. After performing its main purpose (creating a
34
+ # new post), it initiates a redirect instead. This redirect works by returning an external
35
+ # <tt>302 Moved</tt> HTTP response that takes the user to the index action.
36
+ #
37
+ # These two methods represent the two basic action archetypes used in Action Controllers: Get-and-show and do-and-redirect.
38
+ # Most actions are variations on these themes.
39
+ #
40
+ # == Requests
41
+ #
42
+ # For every request, the router determines the value of the +controller+ and +action+ keys. These determine which controller
43
+ # and action are called. The remaining request parameters, the session (if one is available), and the full request with
44
+ # all the HTTP headers are made available to the action through accessor methods. Then the action is performed.
45
+ #
46
+ # The full request object is available via the request accessor and is primarily used to query for HTTP headers:
47
+ #
48
+ # def server_ip
49
+ # location = request.env["REMOTE_ADDR"]
50
+ # render plain: "This server hosted at #{location}"
51
+ # end
52
+ #
53
+ # == Parameters
54
+ #
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>.
58
+ #
59
+ # It's also possible to construct multi-dimensional parameter hashes by specifying keys using brackets, such as:
60
+ #
61
+ # <input type="text" name="post[name]" value="david">
62
+ # <input type="text" name="post[address]" value="hyacintvej">
63
+ #
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
66
+ # <tt>{ "post" => { "address" => { "street" => "hyacintvej" } } }</tt>. There's no limit to the depth of the nesting.
67
+ #
68
+ # == Sessions
69
+ #
70
+ # Sessions allow you to store objects in between requests. This is useful for objects that are not yet ready to be persisted,
71
+ # such as a Signup object constructed in a multi-paged process, or objects that don't change much and are needed all the time, such
72
+ # as a User object for a system that requires login. The session should not be used, however, as a cache for objects where it's likely
73
+ # they could be changed unknowingly. It's usually too much work to keep it all synchronized -- something databases already excel at.
74
+ #
75
+ # You can place objects in the session by using the <tt>session</tt> method, which accesses a hash:
76
+ #
77
+ # session[:person] = Person.authenticate(user_name, password)
78
+ #
79
+ # You can retrieve it again through the same hash:
80
+ #
81
+ # Hello #{session[:person]}
82
+ #
83
+ # For removing objects from the session, you can either assign a single key to +nil+:
84
+ #
85
+ # # removes :person from session
86
+ # session[:person] = nil
87
+ #
88
+ # or you can remove the entire session with +reset_session+.
89
+ #
90
+ # Sessions are stored by default in a browser cookie that's cryptographically signed, but unencrypted.
91
+ # This prevents the user from tampering with the session but also allows them to see its contents.
92
+ #
93
+ # Do not put secret information in cookie-based sessions!
94
+ #
95
+ # == Responses
96
+ #
97
+ # Each action results in a response, which holds the headers and document to be sent to the user's browser. The actual response
98
+ # object is generated automatically through the use of renders and redirects and requires no user intervention.
99
+ #
100
+ # == Renders
101
+ #
102
+ # Action Controller sends content to the user by using one of five rendering methods. The most versatile and common is the rendering
103
+ # of a template. Included in the Action Pack is the Action View, which enables rendering of ERB templates. It's automatically configured.
104
+ # The controller passes objects to the view by assigning instance variables:
105
+ #
106
+ # def show
107
+ # @post = Post.find(params[:id])
108
+ # end
109
+ #
110
+ # Which are then automatically available to the view:
111
+ #
112
+ # Title: <%= @post.title %>
113
+ #
114
+ # You don't have to rely on the automated rendering. For example, actions that could result in the rendering of different templates
115
+ # will use the manual rendering methods:
116
+ #
117
+ # def search
118
+ # @results = Search.find(params[:query])
119
+ # case @results.count
120
+ # when 0 then render action: "no_results"
121
+ # when 1 then render action: "show"
122
+ # when 2..10 then render action: "show_many"
123
+ # end
124
+ # end
125
+ #
126
+ # Read more about writing ERB and Builder templates in ActionView::Base.
127
+ #
128
+ # == Redirects
129
+ #
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
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
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:
133
+ #
134
+ # def create
135
+ # @entry = Entry.new(params[:entry])
136
+ # if @entry.save
137
+ # # The entry was saved correctly, redirect to show
138
+ # redirect_to action: 'show', id: @entry.id
139
+ # else
140
+ # # things didn't go so well, do something else
141
+ # end
142
+ # end
143
+ #
144
+ # In this case, after saving our new entry to the database, the user is redirected to the <tt>show</tt> method, which is then executed.
145
+ # Note that this is an external HTTP-level redirection which will cause the browser to make a second request (a GET to the show action),
146
+ # and not some internal re-routing which calls both "create" and then "show" within one request.
147
+ #
148
+ # Learn more about <tt>redirect_to</tt> and what options you have in ActionController::Redirecting.
149
+ #
150
+ # == Calling multiple redirects or renders
151
+ #
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:
153
+ #
154
+ # def do_something
155
+ # redirect_to action: "elsewhere"
156
+ # render action: "overthere" # raises DoubleRenderError
157
+ # end
158
+ #
159
+ # If you need to redirect on the condition of something, then be sure to add "and return" to halt execution.
160
+ #
161
+ # def do_something
162
+ # redirect_to(action: "elsewhere") and return if monkeys.nil?
163
+ # render action: "overthere" # won't be called if monkeys is nil
164
+ # end
165
+ #
166
+ class Base < Metal
167
+ abstract!
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.
197
+ def self.without_modules(*modules)
198
+ modules = modules.map do |m|
199
+ m.is_a?(Symbol) ? ActionController.const_get(m) : m
200
+ end
201
+
202
+ MODULES - modules
203
+ end
204
+
205
+ MODULES = [
206
+ AbstractController::Rendering,
207
+ AbstractController::Translation,
208
+ AbstractController::AssetPaths,
209
+
210
+ Helpers,
211
+ UrlFor,
212
+ Redirecting,
213
+ ActionView::Layouts,
214
+ Rendering,
215
+ Renderers::All,
216
+ ConditionalGet,
217
+ EtagWithTemplateDigest,
218
+ EtagWithFlash,
219
+ Caching,
220
+ MimeResponds,
221
+ ImplicitRender,
222
+ StrongParameters,
223
+ ParameterEncoding,
224
+ Cookies,
225
+ Flash,
226
+ FormBuilder,
227
+ RequestForgeryProtection,
228
+ ContentSecurityPolicy,
229
+ ForceSSL,
230
+ Streaming,
231
+ DataStreaming,
232
+ HttpAuthentication::Basic::ControllerMethods,
233
+ HttpAuthentication::Digest::ControllerMethods,
234
+ HttpAuthentication::Token::ControllerMethods,
235
+
236
+ # Before callbacks should also be executed as early as possible, so
237
+ # also include them at the bottom.
238
+ AbstractController::Callbacks,
239
+
240
+ # Append rescue at the bottom to wrap as much as possible.
241
+ Rescue,
242
+
243
+ # Add instrumentations hooks at the bottom, to ensure they instrument
244
+ # all the methods properly.
245
+ Instrumentation,
246
+
247
+ # Params wrapper should come before instrumentation so they are
248
+ # properly showed in logs
249
+ ParamsWrapper
250
+ ]
251
+
252
+ MODULES.each do |mod|
253
+ include mod
254
+ end
255
+ setup_renderer!
256
+
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
272
+
273
+ ActiveSupport.run_load_hooks(:action_controller_base, self)
274
+ ActiveSupport.run_load_hooks(:action_controller, self)
275
+ end
276
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionController
4
+ # \Caching is a cheap way of speeding up slow applications by keeping the result of
5
+ # calculations, renderings, and database calls around for subsequent requests.
6
+ #
7
+ # You can read more about each approach by clicking the modules below.
8
+ #
9
+ # Note: To turn off all caching provided by Action Controller, set
10
+ # config.action_controller.perform_caching = false
11
+ #
12
+ # == \Caching stores
13
+ #
14
+ # All the caching stores from ActiveSupport::Cache are available to be used as backends
15
+ # for Action Controller caching.
16
+ #
17
+ # Configuration examples (FileStore is the default):
18
+ #
19
+ # config.action_controller.cache_store = :memory_store
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')
24
+ module Caching
25
+ extend ActiveSupport::Autoload
26
+ extend ActiveSupport::Concern
27
+
28
+ included do
29
+ include AbstractController::Caching
30
+ end
31
+
32
+ private
33
+
34
+ def instrument_payload(key)
35
+ {
36
+ controller: controller_name,
37
+ action: action_name,
38
+ key: key
39
+ }
40
+ end
41
+
42
+ def instrument_name
43
+ "action_controller".freeze
44
+ end
45
+ end
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
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionController
4
+ class LogSubscriber < ActiveSupport::LogSubscriber
5
+ INTERNAL_PARAMS = %w(controller action format _method only_path)
6
+
7
+ def start_processing(event)
8
+ return unless logger.info?
9
+
10
+ payload = event.payload
11
+ params = payload[:params].except(*INTERNAL_PARAMS)
12
+ format = payload[:format]
13
+ format = format.to_s.upcase if format.is_a?(Symbol)
14
+
15
+ info "Processing by #{payload[:controller]}##{payload[:action]} as #{format}"
16
+ info " Parameters: #{params.inspect}" unless params.empty?
17
+ end
18
+
19
+ def process_action(event)
20
+ info do
21
+ payload = event.payload
22
+ additions = ActionController::Base.log_process_action(payload)
23
+
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?
32
+
33
+ message
34
+ end
35
+ end
36
+
37
+ def halted_callback(event)
38
+ info { "Filter chain halted as #{event.payload[:filter].inspect} rendered or redirected" }
39
+ end
40
+
41
+ def send_file(event)
42
+ info { "Sent file #{event.payload[:path]} (#{event.duration.round(1)}ms)" }
43
+ end
44
+
45
+ def redirect_to(event)
46
+ info { "Redirected to #{event.payload[:location]}" }
47
+ end
48
+
49
+ def send_data(event)
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
58
+ end
59
+
60
+ %w(write_fragment read_fragment exist_fragment?
61
+ expire_fragment expire_page write_page).each do |method|
62
+ class_eval <<-METHOD, __FILE__, __LINE__ + 1
63
+ def #{method}(event)
64
+ return unless logger.info? && ActionController::Base.enable_fragment_cache_logging
65
+ key = ActiveSupport::Cache.expand_cache_key(event.payload[:key] || event.payload[:path])
66
+ human_name = #{method.to_s.humanize.inspect}
67
+ info("\#{human_name} \#{key} (\#{event.duration.round(1)}ms)")
68
+ end
69
+ METHOD
70
+ end
71
+
72
+ def logger
73
+ ActionController::Base.logger
74
+ end
75
+ end
76
+ end
77
+
78
+ ActionController::LogSubscriber.attach_to :action_controller