actionpack 7.0.8.7 → 7.2.2.1

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 (171) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +90 -537
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -2
  5. data/lib/abstract_controller/asset_paths.rb +2 -0
  6. data/lib/abstract_controller/base.rb +119 -106
  7. data/lib/abstract_controller/caching/fragments.rb +51 -52
  8. data/lib/abstract_controller/caching.rb +2 -0
  9. data/lib/abstract_controller/callbacks.rb +94 -67
  10. data/lib/abstract_controller/collector.rb +6 -6
  11. data/lib/abstract_controller/deprecator.rb +9 -0
  12. data/lib/abstract_controller/error.rb +2 -0
  13. data/lib/abstract_controller/helpers.rb +121 -91
  14. data/lib/abstract_controller/logger.rb +2 -0
  15. data/lib/abstract_controller/railties/routes_helpers.rb +3 -16
  16. data/lib/abstract_controller/rendering.rb +14 -13
  17. data/lib/abstract_controller/translation.rb +12 -30
  18. data/lib/abstract_controller/url_for.rb +9 -5
  19. data/lib/abstract_controller.rb +8 -0
  20. data/lib/action_controller/api/api_rendering.rb +2 -0
  21. data/lib/action_controller/api.rb +78 -73
  22. data/lib/action_controller/base.rb +199 -141
  23. data/lib/action_controller/caching.rb +16 -11
  24. data/lib/action_controller/deprecator.rb +9 -0
  25. data/lib/action_controller/form_builder.rb +21 -16
  26. data/lib/action_controller/log_subscriber.rb +19 -5
  27. data/lib/action_controller/metal/allow_browser.rb +123 -0
  28. data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
  29. data/lib/action_controller/metal/conditional_get.rb +187 -174
  30. data/lib/action_controller/metal/content_security_policy.rb +26 -25
  31. data/lib/action_controller/metal/cookies.rb +4 -2
  32. data/lib/action_controller/metal/data_streaming.rb +65 -54
  33. data/lib/action_controller/metal/default_headers.rb +6 -2
  34. data/lib/action_controller/metal/etag_with_flash.rb +4 -0
  35. data/lib/action_controller/metal/etag_with_template_digest.rb +18 -14
  36. data/lib/action_controller/metal/exceptions.rb +19 -9
  37. data/lib/action_controller/metal/flash.rb +12 -10
  38. data/lib/action_controller/metal/head.rb +20 -16
  39. data/lib/action_controller/metal/helpers.rb +64 -67
  40. data/lib/action_controller/metal/http_authentication.rb +212 -199
  41. data/lib/action_controller/metal/implicit_render.rb +21 -17
  42. data/lib/action_controller/metal/instrumentation.rb +22 -12
  43. data/lib/action_controller/metal/live.rb +125 -92
  44. data/lib/action_controller/metal/logging.rb +6 -4
  45. data/lib/action_controller/metal/mime_responds.rb +151 -142
  46. data/lib/action_controller/metal/parameter_encoding.rb +34 -32
  47. data/lib/action_controller/metal/params_wrapper.rb +58 -58
  48. data/lib/action_controller/metal/permissions_policy.rb +14 -13
  49. data/lib/action_controller/metal/rate_limiting.rb +62 -0
  50. data/lib/action_controller/metal/redirecting.rb +110 -84
  51. data/lib/action_controller/metal/renderers.rb +50 -49
  52. data/lib/action_controller/metal/rendering.rb +103 -82
  53. data/lib/action_controller/metal/request_forgery_protection.rb +279 -161
  54. data/lib/action_controller/metal/rescue.rb +12 -8
  55. data/lib/action_controller/metal/streaming.rb +174 -132
  56. data/lib/action_controller/metal/strong_parameters.rb +598 -473
  57. data/lib/action_controller/metal/testing.rb +2 -0
  58. data/lib/action_controller/metal/url_for.rb +23 -14
  59. data/lib/action_controller/metal.rb +145 -61
  60. data/lib/action_controller/railtie.rb +25 -9
  61. data/lib/action_controller/railties/helpers.rb +2 -0
  62. data/lib/action_controller/renderer.rb +105 -66
  63. data/lib/action_controller/template_assertions.rb +4 -2
  64. data/lib/action_controller/test_case.rb +157 -128
  65. data/lib/action_controller.rb +17 -3
  66. data/lib/action_dispatch/constants.rb +34 -0
  67. data/lib/action_dispatch/deprecator.rb +9 -0
  68. data/lib/action_dispatch/http/cache.rb +28 -29
  69. data/lib/action_dispatch/http/content_disposition.rb +2 -0
  70. data/lib/action_dispatch/http/content_security_policy.rb +48 -45
  71. data/lib/action_dispatch/http/filter_parameters.rb +18 -8
  72. data/lib/action_dispatch/http/filter_redirect.rb +22 -1
  73. data/lib/action_dispatch/http/headers.rb +23 -21
  74. data/lib/action_dispatch/http/mime_negotiation.rb +37 -48
  75. data/lib/action_dispatch/http/mime_type.rb +60 -30
  76. data/lib/action_dispatch/http/mime_types.rb +5 -1
  77. data/lib/action_dispatch/http/parameters.rb +12 -10
  78. data/lib/action_dispatch/http/permissions_policy.rb +32 -27
  79. data/lib/action_dispatch/http/rack_cache.rb +4 -0
  80. data/lib/action_dispatch/http/request.rb +132 -79
  81. data/lib/action_dispatch/http/response.rb +136 -103
  82. data/lib/action_dispatch/http/upload.rb +19 -15
  83. data/lib/action_dispatch/http/url.rb +75 -73
  84. data/lib/action_dispatch/journey/formatter.rb +19 -6
  85. data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
  86. data/lib/action_dispatch/journey/gtg/simulator.rb +2 -0
  87. data/lib/action_dispatch/journey/gtg/transition_table.rb +10 -8
  88. data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
  89. data/lib/action_dispatch/journey/nodes/node.rb +6 -5
  90. data/lib/action_dispatch/journey/parser.rb +4 -3
  91. data/lib/action_dispatch/journey/parser_extras.rb +2 -0
  92. data/lib/action_dispatch/journey/path/pattern.rb +18 -15
  93. data/lib/action_dispatch/journey/route.rb +12 -9
  94. data/lib/action_dispatch/journey/router/utils.rb +16 -15
  95. data/lib/action_dispatch/journey/router.rb +13 -10
  96. data/lib/action_dispatch/journey/routes.rb +6 -4
  97. data/lib/action_dispatch/journey/scanner.rb +4 -2
  98. data/lib/action_dispatch/journey/visitors.rb +2 -0
  99. data/lib/action_dispatch/journey.rb +2 -0
  100. data/lib/action_dispatch/log_subscriber.rb +25 -0
  101. data/lib/action_dispatch/middleware/actionable_exceptions.rb +7 -6
  102. data/lib/action_dispatch/middleware/assume_ssl.rb +27 -0
  103. data/lib/action_dispatch/middleware/callbacks.rb +4 -0
  104. data/lib/action_dispatch/middleware/cookies.rb +192 -194
  105. data/lib/action_dispatch/middleware/debug_exceptions.rb +36 -27
  106. data/lib/action_dispatch/middleware/debug_locks.rb +18 -13
  107. data/lib/action_dispatch/middleware/debug_view.rb +9 -2
  108. data/lib/action_dispatch/middleware/exception_wrapper.rb +181 -27
  109. data/lib/action_dispatch/middleware/executor.rb +9 -1
  110. data/lib/action_dispatch/middleware/flash.rb +65 -46
  111. data/lib/action_dispatch/middleware/host_authorization.rb +22 -17
  112. data/lib/action_dispatch/middleware/public_exceptions.rb +12 -8
  113. data/lib/action_dispatch/middleware/reloader.rb +9 -5
  114. data/lib/action_dispatch/middleware/remote_ip.rb +88 -83
  115. data/lib/action_dispatch/middleware/request_id.rb +15 -8
  116. data/lib/action_dispatch/middleware/server_timing.rb +8 -6
  117. data/lib/action_dispatch/middleware/session/abstract_store.rb +7 -0
  118. data/lib/action_dispatch/middleware/session/cache_store.rb +14 -7
  119. data/lib/action_dispatch/middleware/session/cookie_store.rb +32 -25
  120. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +9 -3
  121. data/lib/action_dispatch/middleware/show_exceptions.rb +42 -28
  122. data/lib/action_dispatch/middleware/ssl.rb +60 -45
  123. data/lib/action_dispatch/middleware/stack.rb +15 -9
  124. data/lib/action_dispatch/middleware/static.rb +40 -34
  125. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +2 -2
  126. data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +4 -4
  127. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +8 -1
  128. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +7 -7
  129. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +2 -2
  130. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +17 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +16 -12
  132. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -1
  133. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
  134. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +4 -4
  135. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
  136. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +1 -1
  137. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +3 -0
  138. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +47 -38
  139. data/lib/action_dispatch/railtie.rb +12 -4
  140. data/lib/action_dispatch/request/session.rb +39 -27
  141. data/lib/action_dispatch/request/utils.rb +10 -3
  142. data/lib/action_dispatch/routing/endpoint.rb +2 -0
  143. data/lib/action_dispatch/routing/inspector.rb +59 -9
  144. data/lib/action_dispatch/routing/mapper.rb +686 -639
  145. data/lib/action_dispatch/routing/polymorphic_routes.rb +70 -61
  146. data/lib/action_dispatch/routing/redirection.rb +52 -38
  147. data/lib/action_dispatch/routing/route_set.rb +106 -62
  148. data/lib/action_dispatch/routing/routes_proxy.rb +16 -19
  149. data/lib/action_dispatch/routing/url_for.rb +131 -122
  150. data/lib/action_dispatch/routing.rb +152 -150
  151. data/lib/action_dispatch/system_test_case.rb +91 -81
  152. data/lib/action_dispatch/system_testing/browser.rb +27 -19
  153. data/lib/action_dispatch/system_testing/driver.rb +16 -22
  154. data/lib/action_dispatch/system_testing/server.rb +2 -0
  155. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +53 -31
  156. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
  157. data/lib/action_dispatch/testing/assertion_response.rb +9 -7
  158. data/lib/action_dispatch/testing/assertions/response.rb +36 -26
  159. data/lib/action_dispatch/testing/assertions/routing.rb +203 -95
  160. data/lib/action_dispatch/testing/assertions.rb +5 -1
  161. data/lib/action_dispatch/testing/integration.rb +240 -229
  162. data/lib/action_dispatch/testing/request_encoder.rb +6 -1
  163. data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
  164. data/lib/action_dispatch/testing/test_process.rb +14 -9
  165. data/lib/action_dispatch/testing/test_request.rb +4 -2
  166. data/lib/action_dispatch/testing/test_response.rb +34 -19
  167. data/lib/action_dispatch.rb +52 -21
  168. data/lib/action_pack/gem_version.rb +6 -4
  169. data/lib/action_pack/version.rb +3 -1
  170. data/lib/action_pack.rb +18 -17
  171. metadata +86 -27
@@ -1,200 +1,224 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "action_view"
4
6
  require "action_controller/log_subscriber"
5
7
  require "action_controller/metal/params_wrapper"
6
8
 
7
9
  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.
10
+ # # Action Controller Base
11
+ #
12
+ # Action Controllers are the core of a web request in Rails. They are made up of
13
+ # one or more actions that are executed on request and then either it renders a
14
+ # template or redirects to another action. An action is defined as a public
15
+ # method on the controller, which will automatically be made accessible to the
16
+ # web-server through Rails Routes.
11
17
  #
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
18
+ # By default, only the ApplicationController in a Rails application inherits
19
+ # from `ActionController::Base`. All other controllers inherit from
20
+ # ApplicationController. This gives you one class to configure things such as
14
21
  # request forgery protection and filtering of sensitive request parameters.
15
22
  #
16
23
  # A sample controller could look like this:
17
24
  #
18
- # class PostsController < ApplicationController
19
- # def index
20
- # @posts = Post.all
21
- # end
25
+ # class PostsController < ApplicationController
26
+ # def index
27
+ # @posts = Post.all
28
+ # end
22
29
  #
23
- # def create
24
- # @post = Post.create params[:post]
25
- # redirect_to posts_path
30
+ # def create
31
+ # @post = Post.create params[:post]
32
+ # redirect_to posts_path
33
+ # end
26
34
  # end
27
- # end
28
35
  #
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.
36
+ # Actions, by default, render a template in the `app/views` directory
37
+ # corresponding to the name of the controller and action after executing code in
38
+ # the action. For example, the `index` action of the PostsController would
39
+ # render the template `app/views/posts/index.html.erb` by default after
40
+ # populating the `@posts` instance variable.
32
41
  #
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.
42
+ # Unlike index, the create action will not render a template. After performing
43
+ # its main purpose (creating a new post), it initiates a redirect instead. This
44
+ # redirect works by returning an external `302 Moved` HTTP response that takes
45
+ # the user to the index action.
36
46
  #
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.
47
+ # These two methods represent the two basic action archetypes used in Action
48
+ # Controllers: Get-and-show and do-and-redirect. Most actions are variations on
49
+ # these themes.
39
50
  #
40
- # == Requests
51
+ # ## Requests
41
52
  #
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.
53
+ # For every request, the router determines the value of the `controller` and
54
+ # `action` keys. These determine which controller and action are called. The
55
+ # remaining request parameters, the session (if one is available), and the full
56
+ # request with all the HTTP headers are made available to the action through
57
+ # accessor methods. Then the action is performed.
45
58
  #
46
- # The full request object is available via the request accessor and is primarily used to query for HTTP headers:
59
+ # The full request object is available via the request accessor and is primarily
60
+ # used to query for HTTP headers:
47
61
  #
48
- # def server_ip
49
- # location = request.env["REMOTE_ADDR"]
50
- # render plain: "This server hosted at #{location}"
51
- # end
62
+ # def server_ip
63
+ # location = request.env["REMOTE_ADDR"]
64
+ # render plain: "This server hosted at #{location}"
65
+ # end
52
66
  #
53
- # == Parameters
67
+ # ## Parameters
54
68
  #
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>.
69
+ # All request parameters, whether they come from a query string in the URL or
70
+ # form data submitted through a POST request are available through the `params`
71
+ # method which returns a hash. For example, an action that was performed through
72
+ # `/posts?category=All&limit=5` will include `{ "category" => "All", "limit" =>
73
+ # "5" }` in `params`.
58
74
  #
59
- # It's also possible to construct multi-dimensional parameter hashes by specifying keys using brackets, such as:
75
+ # It's also possible to construct multi-dimensional parameter hashes by
76
+ # specifying keys using brackets, such as:
60
77
  #
61
- # <input type="text" name="post[name]" value="david">
62
- # <input type="text" name="post[address]" value="hyacintvej">
78
+ # <input type="text" name="post[name]" value="david">
79
+ # <input type="text" name="post[address]" value="hyacintvej">
63
80
  #
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.
81
+ # A request coming from a form holding these inputs will include `{ "post" => {
82
+ # "name" => "david", "address" => "hyacintvej" } }`. If the address input had
83
+ # been named `post[address][street]`, the `params` would have included `{ "post"
84
+ # => { "address" => { "street" => "hyacintvej" } } }`. There's no limit to the
85
+ # depth of the nesting.
67
86
  #
68
- # == Sessions
87
+ # ## Sessions
69
88
  #
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.
89
+ # Sessions allow you to store objects in between requests. This is useful for
90
+ # objects that are not yet ready to be persisted, such as a Signup object
91
+ # constructed in a multi-paged process, or objects that don't change much and
92
+ # are needed all the time, such as a User object for a system that requires
93
+ # login. The session should not be used, however, as a cache for objects where
94
+ # it's likely they could be changed unknowingly. It's usually too much work to
95
+ # keep it all synchronized -- something databases already excel at.
74
96
  #
75
- # You can place objects in the session by using the <tt>session</tt> method, which accesses a hash:
97
+ # You can place objects in the session by using the `session` method, which
98
+ # accesses a hash:
76
99
  #
77
- # session[:person] = Person.authenticate(user_name, password)
100
+ # session[:person] = Person.authenticate(user_name, password)
78
101
  #
79
102
  # You can retrieve it again through the same hash:
80
103
  #
81
- # "Hello #{session[:person]}"
104
+ # "Hello #{session[:person]}"
82
105
  #
83
- # For removing objects from the session, you can either assign a single key to +nil+:
106
+ # For removing objects from the session, you can either assign a single key to
107
+ # `nil`:
84
108
  #
85
- # # removes :person from session
86
- # session[:person] = nil
109
+ # # removes :person from session
110
+ # session[:person] = nil
87
111
  #
88
- # or you can remove the entire session with +reset_session+.
112
+ # or you can remove the entire session with `reset_session`.
89
113
  #
90
114
  # By default, sessions are stored in an encrypted browser cookie (see
91
- # ActionDispatch::Session::CookieStore). Thus the user will not be able to
92
- # read or edit the session data. However, the user can keep a copy of the
93
- # cookie even after it has expired, so you should avoid storing sensitive
94
- # information in cookie-based sessions.
115
+ # ActionDispatch::Session::CookieStore). Thus the user will not be able to read
116
+ # or edit the session data. However, the user can keep a copy of the cookie even
117
+ # after it has expired, so you should avoid storing sensitive information in
118
+ # cookie-based sessions.
95
119
  #
96
- # == Responses
120
+ # ## Responses
97
121
  #
98
- # Each action results in a response, which holds the headers and document to be sent to the user's browser. The actual response
99
- # object is generated automatically through the use of renders and redirects and requires no user intervention.
122
+ # Each action results in a response, which holds the headers and document to be
123
+ # sent to the user's browser. The actual response object is generated
124
+ # automatically through the use of renders and redirects and requires no user
125
+ # intervention.
100
126
  #
101
- # == Renders
127
+ # ## Renders
102
128
  #
103
- # Action Controller sends content to the user by using one of five rendering methods. The most versatile and common is the rendering
104
- # of a template. Included in the Action Pack is the Action View, which enables rendering of ERB templates. It's automatically configured.
105
- # The controller passes objects to the view by assigning instance variables:
129
+ # Action Controller sends content to the user by using one of five rendering
130
+ # methods. The most versatile and common is the rendering of a template.
131
+ # Included in the Action Pack is the Action View, which enables rendering of ERB
132
+ # templates. It's automatically configured. The controller passes objects to the
133
+ # view by assigning instance variables:
106
134
  #
107
- # def show
108
- # @post = Post.find(params[:id])
109
- # end
135
+ # def show
136
+ # @post = Post.find(params[:id])
137
+ # end
110
138
  #
111
139
  # Which are then automatically available to the view:
112
140
  #
113
- # Title: <%= @post.title %>
141
+ # Title: <%= @post.title %>
114
142
  #
115
- # You don't have to rely on the automated rendering. For example, actions that could result in the rendering of different templates
116
- # will use the manual rendering methods:
143
+ # You don't have to rely on the automated rendering. For example, actions that
144
+ # could result in the rendering of different templates will use the manual
145
+ # rendering methods:
117
146
  #
118
- # def search
119
- # @results = Search.find(params[:query])
120
- # case @results.count
121
- # when 0 then render action: "no_results"
122
- # when 1 then render action: "show"
123
- # when 2..10 then render action: "show_many"
147
+ # def search
148
+ # @results = Search.find(params[:query])
149
+ # case @results.count
150
+ # when 0 then render action: "no_results"
151
+ # when 1 then render action: "show"
152
+ # when 2..10 then render action: "show_many"
153
+ # end
124
154
  # end
125
- # end
126
155
  #
127
156
  # Read more about writing ERB and Builder templates in ActionView::Base.
128
157
  #
129
- # == Redirects
158
+ # ## Redirects
130
159
  #
131
- # 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
132
- # database, we might like to show the user the new entry. Because we're following good DRY principles (Don't Repeat Yourself), we're
133
- # 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:
160
+ # Redirects are used to move from one action to another. For example, after a
161
+ # `create` action, which stores a blog entry to the database, we might like to
162
+ # show the user the new entry. Because we're following good DRY principles
163
+ # (Don't Repeat Yourself), we're going to reuse (and redirect to) a `show`
164
+ # action that we'll assume has already been created. The code might look like
165
+ # this:
134
166
  #
135
- # def create
136
- # @entry = Entry.new(params[:entry])
137
- # if @entry.save
138
- # # The entry was saved correctly, redirect to show
139
- # redirect_to action: 'show', id: @entry.id
140
- # else
141
- # # things didn't go so well, do something else
167
+ # def create
168
+ # @entry = Entry.new(params[:entry])
169
+ # if @entry.save
170
+ # # The entry was saved correctly, redirect to show
171
+ # redirect_to action: 'show', id: @entry.id
172
+ # else
173
+ # # things didn't go so well, do something else
174
+ # end
142
175
  # end
143
- # end
144
176
  #
145
- # 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.
146
- # 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),
147
- # and not some internal re-routing which calls both "create" and then "show" within one request.
177
+ # In this case, after saving our new entry to the database, the user is
178
+ # redirected to the `show` method, which is then executed. Note that this is an
179
+ # external HTTP-level redirection which will cause the browser to make a second
180
+ # request (a GET to the show action), and not some internal re-routing which
181
+ # calls both "create" and then "show" within one request.
148
182
  #
149
- # Learn more about <tt>redirect_to</tt> and what options you have in ActionController::Redirecting.
183
+ # Learn more about `redirect_to` and what options you have in
184
+ # ActionController::Redirecting.
150
185
  #
151
- # == Calling multiple redirects or renders
186
+ # ## Calling multiple redirects or renders
152
187
  #
153
- # An action may contain only a single render or a single redirect. Attempting to try to do either again will result in a DoubleRenderError:
188
+ # An action may perform only a single render or a single redirect. Attempting to
189
+ # do either again will result in a DoubleRenderError:
154
190
  #
155
- # def do_something
156
- # redirect_to action: "elsewhere"
157
- # render action: "overthere" # raises DoubleRenderError
158
- # end
191
+ # def do_something
192
+ # redirect_to action: "elsewhere"
193
+ # render action: "overthere" # raises DoubleRenderError
194
+ # end
159
195
  #
160
- # If you need to redirect on the condition of something, then be sure to add "and return" to halt execution.
196
+ # If you need to redirect on the condition of something, then be sure to add
197
+ # "return" to halt execution.
161
198
  #
162
- # def do_something
163
- # redirect_to(action: "elsewhere") and return if monkeys.nil?
164
- # render action: "overthere" # won't be called if monkeys is nil
165
- # end
199
+ # def do_something
200
+ # if monkeys.nil?
201
+ # redirect_to(action: "elsewhere")
202
+ # return
203
+ # end
204
+ # render action: "overthere" # won't be called if monkeys is nil
205
+ # end
166
206
  #
167
207
  class Base < Metal
168
208
  abstract!
169
209
 
170
- # We document the request and response methods here because albeit they are
171
- # implemented in ActionController::Metal, the type of the returned objects
172
- # is unknown at that level.
173
-
174
- ##
175
- # :method: request
176
- #
177
- # Returns an ActionDispatch::Request instance that represents the
178
- # current request.
179
-
180
- ##
181
- # :method: response
182
- #
183
- # Returns an ActionDispatch::Response that represents the current
184
- # response.
185
-
186
210
  # Shortcut helper that returns all the modules included in
187
211
  # ActionController::Base except the ones passed as arguments:
188
212
  #
189
- # class MyBaseController < ActionController::Metal
190
- # ActionController::Base.without_modules(:ParamsWrapper, :Streaming).each do |left|
191
- # include left
213
+ # class MyBaseController < ActionController::Metal
214
+ # ActionController::Base.without_modules(:ParamsWrapper, :Streaming).each do |left|
215
+ # include left
216
+ # end
192
217
  # end
193
- # end
194
218
  #
195
- # This gives better control over what you want to exclude and makes it
196
- # easier to create a bare controller class, instead of listing the modules
197
- # required manually.
219
+ # This gives better control over what you want to exclude and makes it easier to
220
+ # create a bare controller class, instead of listing the modules required
221
+ # manually.
198
222
  def self.without_modules(*modules)
199
223
  modules = modules.map do |m|
200
224
  m.is_a?(Symbol) ? ActionController.const_get(m) : m
@@ -207,7 +231,6 @@ module ActionController
207
231
  AbstractController::Rendering,
208
232
  AbstractController::Translation,
209
233
  AbstractController::AssetPaths,
210
-
211
234
  Helpers,
212
235
  UrlFor,
213
236
  Redirecting,
@@ -228,6 +251,8 @@ module ActionController
228
251
  RequestForgeryProtection,
229
252
  ContentSecurityPolicy,
230
253
  PermissionsPolicy,
254
+ RateLimiting,
255
+ AllowBrowser,
231
256
  Streaming,
232
257
  DataStreaming,
233
258
  HttpAuthentication::Basic::ControllerMethods,
@@ -235,32 +260,65 @@ module ActionController
235
260
  HttpAuthentication::Token::ControllerMethods,
236
261
  DefaultHeaders,
237
262
  Logging,
238
-
239
- # Before callbacks should also be executed as early as possible, so
240
- # also include them at the bottom.
241
263
  AbstractController::Callbacks,
242
-
243
- # Append rescue at the bottom to wrap as much as possible.
244
264
  Rescue,
245
-
246
- # Add instrumentations hooks at the bottom, to ensure they instrument
247
- # all the methods properly.
248
265
  Instrumentation,
249
-
250
- # Params wrapper should come before instrumentation so they are
251
- # properly showed in logs
252
266
  ParamsWrapper
253
267
  ]
254
268
 
255
- MODULES.each do |mod|
256
- include mod
257
- end
269
+ # Note: Documenting these severely degrates the performance of rdoc
270
+ # :stopdoc:
271
+ include AbstractController::Rendering
272
+ include AbstractController::Translation
273
+ include AbstractController::AssetPaths
274
+ include Helpers
275
+ include UrlFor
276
+ include Redirecting
277
+ include ActionView::Layouts
278
+ include Rendering
279
+ include Renderers::All
280
+ include ConditionalGet
281
+ include EtagWithTemplateDigest
282
+ include EtagWithFlash
283
+ include Caching
284
+ include MimeResponds
285
+ include ImplicitRender
286
+ include StrongParameters
287
+ include ParameterEncoding
288
+ include Cookies
289
+ include Flash
290
+ include FormBuilder
291
+ include RequestForgeryProtection
292
+ include ContentSecurityPolicy
293
+ include PermissionsPolicy
294
+ include RateLimiting
295
+ include AllowBrowser
296
+ include Streaming
297
+ include DataStreaming
298
+ include HttpAuthentication::Basic::ControllerMethods
299
+ include HttpAuthentication::Digest::ControllerMethods
300
+ include HttpAuthentication::Token::ControllerMethods
301
+ include DefaultHeaders
302
+ include Logging
303
+ # Before callbacks should also be executed as early as possible, so also include
304
+ # them at the bottom.
305
+ include AbstractController::Callbacks
306
+ # Append rescue at the bottom to wrap as much as possible.
307
+ include Rescue
308
+ # Add instrumentations hooks at the bottom, to ensure they instrument all the
309
+ # methods properly.
310
+ include Instrumentation
311
+ # Params wrapper should come before instrumentation so they are properly showed
312
+ # in logs
313
+ include ParamsWrapper
314
+ # :startdoc:
258
315
  setup_renderer!
259
316
 
260
317
  # Define some internal variables that should not be propagated to the view.
261
318
  PROTECTED_IVARS = AbstractController::Rendering::DEFAULT_PROTECTED_INSTANCE_VARIABLES + %i(
262
319
  @_params @_response @_request @_config @_url_options @_action_has_layout @_view_context_class
263
320
  @_view_renderer @_lookup_context @_routes @_view_runtime @_db_runtime @_helper_proxy
321
+ @_marked_for_same_origin_verification @_rendered_format
264
322
  )
265
323
 
266
324
  def _protected_ivars
@@ -1,26 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  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
+ # # Action Controller Caching
7
+ #
8
+ # Caching is a cheap way of speeding up slow applications by keeping the result
9
+ # of calculations, renderings, and database calls around for subsequent
10
+ # requests.
6
11
  #
7
12
  # You can read more about each approach by clicking the modules below.
8
13
  #
9
14
  # Note: To turn off all caching provided by Action Controller, set
10
- # config.action_controller.perform_caching = false
15
+ # config.action_controller.perform_caching = false
11
16
  #
12
- # == \Caching stores
17
+ # ## Caching stores
13
18
  #
14
- # All the caching stores from ActiveSupport::Cache are available to be used as backends
15
- # for Action Controller caching.
19
+ # All the caching stores from ActiveSupport::Cache are available to be used as
20
+ # backends for Action Controller caching.
16
21
  #
17
22
  # Configuration examples (FileStore is the default):
18
23
  #
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
+ # config.action_controller.cache_store = :memory_store
25
+ # config.action_controller.cache_store = :file_store, '/path/to/cache/directory'
26
+ # config.action_controller.cache_store = :mem_cache_store, 'localhost'
27
+ # config.action_controller.cache_store = :mem_cache_store, Memcached::Rails.new('localhost:11211')
28
+ # config.action_controller.cache_store = MyOwnStore.new('parameter')
24
29
  module Caching
25
30
  extend ActiveSupport::Concern
26
31
 
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
4
+
5
+ module ActionController
6
+ def self.deprecator # :nodoc:
7
+ AbstractController.deprecator
8
+ end
9
+ end
@@ -1,29 +1,33 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  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
+ # # Action Controller Form Builder
7
+ #
8
+ # Override the default form builder for all views rendered by this controller
9
+ # and any of its descendants. Accepts a subclass of
6
10
  # ActionView::Helpers::FormBuilder.
7
11
  #
8
12
  # For example, given a form builder:
9
13
  #
10
- # class AdminFormBuilder < ActionView::Helpers::FormBuilder
11
- # def special_field(name)
14
+ # class AdminFormBuilder < ActionView::Helpers::FormBuilder
15
+ # def special_field(name)
16
+ # end
12
17
  # end
13
- # end
14
18
  #
15
19
  # The controller specifies a form builder as its default:
16
20
  #
17
- # class AdminAreaController < ApplicationController
18
- # default_form_builder AdminFormBuilder
19
- # end
21
+ # class AdminAreaController < ApplicationController
22
+ # default_form_builder AdminFormBuilder
23
+ # end
20
24
  #
21
- # Then in the view any form using +form_for+ will be an instance of the
25
+ # Then in the view any form using `form_for` will be an instance of the
22
26
  # specified form builder:
23
27
  #
24
- # <%= form_for(@instance) do |builder| %>
25
- # <%= builder.special_field(:name) %>
26
- # <% end %>
28
+ # <%= form_for(@instance) do |builder| %>
29
+ # <%= builder.special_field(:name) %>
30
+ # <% end %>
27
31
  module FormBuilder
28
32
  extend ActiveSupport::Concern
29
33
 
@@ -32,11 +36,12 @@ module ActionController
32
36
  end
33
37
 
34
38
  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.
39
+ # Set the form builder to be used as the default for all forms in the views
40
+ # rendered by this controller and its subclasses.
37
41
  #
38
- # ==== Parameters
39
- # * <tt>builder</tt> - Default form builder, an instance of ActionView::Helpers::FormBuilder
42
+ # #### Parameters
43
+ # * `builder` - Default form builder, an instance of
44
+ # ActionView::Helpers::FormBuilder
40
45
  def default_form_builder(builder)
41
46
  self._default_form_builder = builder
42
47
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionController
4
6
  class LogSubscriber < ActiveSupport::LogSubscriber
5
7
  INTERNAL_PARAMS = %w(controller action format _method only_path)
@@ -8,7 +10,10 @@ module ActionController
8
10
  return unless logger.info?
9
11
 
10
12
  payload = event.payload
11
- params = payload[:params].except(*INTERNAL_PARAMS)
13
+ params = {}
14
+ payload[:params].each_pair do |k, v|
15
+ params[k] = v unless INTERNAL_PARAMS.include?(k)
16
+ end
12
17
  format = payload[:format]
13
18
  format = format.to_s.upcase if format.is_a?(Symbol)
14
19
  format = "*/*" if format.nil?
@@ -16,6 +21,7 @@ module ActionController
16
21
  info "Processing by #{payload[:controller]}##{payload[:action]} as #{format}"
17
22
  info " Parameters: #{params.inspect}" unless params.empty?
18
23
  end
24
+ subscribe_log_level :start_processing, :info
19
25
 
20
26
  def process_action(event)
21
27
  info do
@@ -27,31 +33,36 @@ module ActionController
27
33
  status = ActionDispatch::ExceptionWrapper.status_code_for_exception(exception_class_name)
28
34
  end
29
35
 
30
- additions << "Allocations: #{event.allocations}"
36
+ additions << "GC: #{event.gc_time.round(1)}ms"
31
37
 
32
- message = +"Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{event.duration.round}ms"
33
- message << " (#{additions.join(" | ")})"
38
+ message = +"Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{event.duration.round}ms" \
39
+ " (#{additions.join(" | ")})"
34
40
  message << "\n\n" if defined?(Rails.env) && Rails.env.development?
35
41
 
36
42
  message
37
43
  end
38
44
  end
45
+ subscribe_log_level :process_action, :info
39
46
 
40
47
  def halted_callback(event)
41
48
  info { "Filter chain halted as #{event.payload[:filter].inspect} rendered or redirected" }
42
49
  end
50
+ subscribe_log_level :halted_callback, :info
43
51
 
44
52
  def send_file(event)
45
53
  info { "Sent file #{event.payload[:path]} (#{event.duration.round(1)}ms)" }
46
54
  end
55
+ subscribe_log_level :send_file, :info
47
56
 
48
57
  def redirect_to(event)
49
58
  info { "Redirected to #{event.payload[:location]}" }
50
59
  end
60
+ subscribe_log_level :redirect_to, :info
51
61
 
52
62
  def send_data(event)
53
63
  info { "Sent data #{event.payload[:filename]} (#{event.duration.round(1)}ms)" }
54
64
  end
65
+ subscribe_log_level :send_data, :info
55
66
 
56
67
  def unpermitted_parameters(event)
57
68
  debug do
@@ -61,15 +72,18 @@ module ActionController
61
72
  color("Unpermitted parameter#{'s' if unpermitted_keys.size > 1}: #{display_unpermitted_keys}. Context: { #{context} }", RED)
62
73
  end
63
74
  end
75
+ subscribe_log_level :unpermitted_parameters, :debug
64
76
 
65
77
  %w(write_fragment read_fragment exist_fragment? expire_fragment).each do |method|
66
78
  class_eval <<-METHOD, __FILE__, __LINE__ + 1
79
+ # frozen_string_literal: true
67
80
  def #{method}(event)
68
- return unless logger.info? && ActionController::Base.enable_fragment_cache_logging
81
+ return unless ActionController::Base.enable_fragment_cache_logging
69
82
  key = ActiveSupport::Cache.expand_cache_key(event.payload[:key] || event.payload[:path])
70
83
  human_name = #{method.to_s.humanize.inspect}
71
84
  info("\#{human_name} \#{key} (\#{event.duration.round(1)}ms)")
72
85
  end
86
+ subscribe_log_level :#{method}, :info
73
87
  METHOD
74
88
  end
75
89