actionpack 7.1.5.1 → 8.1.2

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 (177) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +308 -523
  3. data/README.rdoc +1 -1
  4. data/lib/abstract_controller/asset_paths.rb +6 -2
  5. data/lib/abstract_controller/base.rb +104 -105
  6. data/lib/abstract_controller/caching/fragments.rb +50 -53
  7. data/lib/abstract_controller/caching.rb +8 -3
  8. data/lib/abstract_controller/callbacks.rb +70 -62
  9. data/lib/abstract_controller/collector.rb +7 -7
  10. data/lib/abstract_controller/deprecator.rb +2 -0
  11. data/lib/abstract_controller/error.rb +2 -0
  12. data/lib/abstract_controller/helpers.rb +71 -84
  13. data/lib/abstract_controller/logger.rb +4 -1
  14. data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
  15. data/lib/abstract_controller/rendering.rb +13 -13
  16. data/lib/abstract_controller/translation.rb +12 -13
  17. data/lib/abstract_controller/url_for.rb +8 -6
  18. data/lib/abstract_controller.rb +2 -0
  19. data/lib/action_controller/api/api_rendering.rb +2 -0
  20. data/lib/action_controller/api.rb +76 -72
  21. data/lib/action_controller/base.rb +199 -126
  22. data/lib/action_controller/caching.rb +16 -14
  23. data/lib/action_controller/deprecator.rb +2 -0
  24. data/lib/action_controller/form_builder.rb +21 -18
  25. data/lib/action_controller/log_subscriber.rb +23 -2
  26. data/lib/action_controller/metal/allow_browser.rb +133 -0
  27. data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
  28. data/lib/action_controller/metal/conditional_get.rb +217 -175
  29. data/lib/action_controller/metal/content_security_policy.rb +25 -24
  30. data/lib/action_controller/metal/cookies.rb +4 -2
  31. data/lib/action_controller/metal/data_streaming.rb +72 -63
  32. data/lib/action_controller/metal/default_headers.rb +5 -3
  33. data/lib/action_controller/metal/etag_with_flash.rb +3 -1
  34. data/lib/action_controller/metal/etag_with_template_digest.rb +17 -15
  35. data/lib/action_controller/metal/exceptions.rb +16 -9
  36. data/lib/action_controller/metal/flash.rb +13 -14
  37. data/lib/action_controller/metal/head.rb +15 -11
  38. data/lib/action_controller/metal/helpers.rb +63 -55
  39. data/lib/action_controller/metal/http_authentication.rb +209 -201
  40. data/lib/action_controller/metal/implicit_render.rb +17 -15
  41. data/lib/action_controller/metal/instrumentation.rb +16 -14
  42. data/lib/action_controller/metal/live.rb +177 -128
  43. data/lib/action_controller/metal/logging.rb +6 -4
  44. data/lib/action_controller/metal/mime_responds.rb +151 -142
  45. data/lib/action_controller/metal/parameter_encoding.rb +34 -32
  46. data/lib/action_controller/metal/params_wrapper.rb +57 -59
  47. data/lib/action_controller/metal/permissions_policy.rb +22 -12
  48. data/lib/action_controller/metal/rate_limiting.rb +92 -0
  49. data/lib/action_controller/metal/redirecting.rb +213 -94
  50. data/lib/action_controller/metal/renderers.rb +78 -57
  51. data/lib/action_controller/metal/rendering.rb +111 -77
  52. data/lib/action_controller/metal/request_forgery_protection.rb +182 -143
  53. data/lib/action_controller/metal/rescue.rb +20 -9
  54. data/lib/action_controller/metal/streaming.rb +118 -195
  55. data/lib/action_controller/metal/strong_parameters.rb +720 -530
  56. data/lib/action_controller/metal/testing.rb +2 -0
  57. data/lib/action_controller/metal/url_for.rb +17 -15
  58. data/lib/action_controller/metal.rb +86 -60
  59. data/lib/action_controller/railtie.rb +36 -15
  60. data/lib/action_controller/railties/helpers.rb +2 -0
  61. data/lib/action_controller/renderer.rb +41 -36
  62. data/lib/action_controller/structured_event_subscriber.rb +116 -0
  63. data/lib/action_controller/template_assertions.rb +4 -2
  64. data/lib/action_controller/test_case.rb +160 -131
  65. data/lib/action_controller.rb +5 -1
  66. data/lib/action_dispatch/constants.rb +8 -0
  67. data/lib/action_dispatch/deprecator.rb +2 -0
  68. data/lib/action_dispatch/http/cache.rb +163 -35
  69. data/lib/action_dispatch/http/content_disposition.rb +2 -0
  70. data/lib/action_dispatch/http/content_security_policy.rb +54 -39
  71. data/lib/action_dispatch/http/filter_parameters.rb +14 -8
  72. data/lib/action_dispatch/http/filter_redirect.rb +22 -1
  73. data/lib/action_dispatch/http/headers.rb +22 -22
  74. data/lib/action_dispatch/http/mime_negotiation.rb +89 -41
  75. data/lib/action_dispatch/http/mime_type.rb +25 -21
  76. data/lib/action_dispatch/http/mime_types.rb +3 -0
  77. data/lib/action_dispatch/http/param_builder.rb +187 -0
  78. data/lib/action_dispatch/http/param_error.rb +26 -0
  79. data/lib/action_dispatch/http/parameters.rb +14 -12
  80. data/lib/action_dispatch/http/permissions_policy.rb +25 -36
  81. data/lib/action_dispatch/http/query_parser.rb +55 -0
  82. data/lib/action_dispatch/http/rack_cache.rb +2 -0
  83. data/lib/action_dispatch/http/request.rb +141 -92
  84. data/lib/action_dispatch/http/response.rb +137 -77
  85. data/lib/action_dispatch/http/upload.rb +18 -16
  86. data/lib/action_dispatch/http/url.rb +187 -89
  87. data/lib/action_dispatch/journey/formatter.rb +21 -9
  88. data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
  89. data/lib/action_dispatch/journey/gtg/simulator.rb +34 -11
  90. data/lib/action_dispatch/journey/gtg/transition_table.rb +47 -53
  91. data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
  92. data/lib/action_dispatch/journey/nodes/node.rb +8 -6
  93. data/lib/action_dispatch/journey/parser.rb +99 -195
  94. data/lib/action_dispatch/journey/path/pattern.rb +4 -1
  95. data/lib/action_dispatch/journey/route.rb +54 -38
  96. data/lib/action_dispatch/journey/router/utils.rb +22 -27
  97. data/lib/action_dispatch/journey/router.rb +63 -83
  98. data/lib/action_dispatch/journey/routes.rb +11 -2
  99. data/lib/action_dispatch/journey/scanner.rb +46 -42
  100. data/lib/action_dispatch/journey/visitors.rb +57 -23
  101. data/lib/action_dispatch/journey/visualizer/fsm.js +4 -6
  102. data/lib/action_dispatch/journey.rb +2 -0
  103. data/lib/action_dispatch/log_subscriber.rb +7 -1
  104. data/lib/action_dispatch/middleware/actionable_exceptions.rb +2 -0
  105. data/lib/action_dispatch/middleware/assume_ssl.rb +8 -5
  106. data/lib/action_dispatch/middleware/callbacks.rb +3 -1
  107. data/lib/action_dispatch/middleware/cookies.rb +125 -106
  108. data/lib/action_dispatch/middleware/debug_exceptions.rb +37 -8
  109. data/lib/action_dispatch/middleware/debug_locks.rb +15 -13
  110. data/lib/action_dispatch/middleware/debug_view.rb +13 -5
  111. data/lib/action_dispatch/middleware/exception_wrapper.rb +18 -23
  112. data/lib/action_dispatch/middleware/executor.rb +19 -4
  113. data/lib/action_dispatch/middleware/flash.rb +63 -51
  114. data/lib/action_dispatch/middleware/host_authorization.rb +17 -15
  115. data/lib/action_dispatch/middleware/public_exceptions.rb +14 -12
  116. data/lib/action_dispatch/middleware/reloader.rb +5 -3
  117. data/lib/action_dispatch/middleware/remote_ip.rb +87 -77
  118. data/lib/action_dispatch/middleware/request_id.rb +16 -10
  119. data/lib/action_dispatch/middleware/server_timing.rb +4 -2
  120. data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -0
  121. data/lib/action_dispatch/middleware/session/cache_store.rb +30 -8
  122. data/lib/action_dispatch/middleware/session/cookie_store.rb +27 -26
  123. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +7 -3
  124. data/lib/action_dispatch/middleware/show_exceptions.rb +16 -16
  125. data/lib/action_dispatch/middleware/ssl.rb +53 -40
  126. data/lib/action_dispatch/middleware/stack.rb +11 -10
  127. data/lib/action_dispatch/middleware/static.rb +33 -31
  128. data/lib/action_dispatch/middleware/templates/rescues/_copy_button.html.erb +1 -0
  129. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +3 -5
  130. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +9 -5
  131. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +1 -0
  132. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +1 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +4 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +3 -0
  135. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +50 -0
  136. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +1 -0
  137. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -0
  138. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -0
  139. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -0
  140. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -0
  141. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +1 -1
  142. data/lib/action_dispatch/railtie.rb +23 -3
  143. data/lib/action_dispatch/request/session.rb +24 -21
  144. data/lib/action_dispatch/request/utils.rb +11 -3
  145. data/lib/action_dispatch/routing/endpoint.rb +2 -0
  146. data/lib/action_dispatch/routing/inspector.rb +85 -60
  147. data/lib/action_dispatch/routing/mapper.rb +1031 -851
  148. data/lib/action_dispatch/routing/polymorphic_routes.rb +69 -62
  149. data/lib/action_dispatch/routing/redirection.rb +47 -39
  150. data/lib/action_dispatch/routing/route_set.rb +79 -56
  151. data/lib/action_dispatch/routing/routes_proxy.rb +7 -4
  152. data/lib/action_dispatch/routing/url_for.rb +130 -125
  153. data/lib/action_dispatch/routing.rb +150 -148
  154. data/lib/action_dispatch/structured_event_subscriber.rb +20 -0
  155. data/lib/action_dispatch/system_test_case.rb +91 -81
  156. data/lib/action_dispatch/system_testing/browser.rb +16 -23
  157. data/lib/action_dispatch/system_testing/driver.rb +2 -0
  158. data/lib/action_dispatch/system_testing/server.rb +2 -0
  159. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +34 -23
  160. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
  161. data/lib/action_dispatch/testing/assertion_response.rb +9 -7
  162. data/lib/action_dispatch/testing/assertions/response.rb +52 -25
  163. data/lib/action_dispatch/testing/assertions/routing.rb +168 -87
  164. data/lib/action_dispatch/testing/assertions.rb +2 -0
  165. data/lib/action_dispatch/testing/integration.rb +233 -223
  166. data/lib/action_dispatch/testing/request_encoder.rb +11 -9
  167. data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
  168. data/lib/action_dispatch/testing/test_process.rb +11 -8
  169. data/lib/action_dispatch/testing/test_request.rb +3 -1
  170. data/lib/action_dispatch/testing/test_response.rb +27 -26
  171. data/lib/action_dispatch.rb +36 -32
  172. data/lib/action_pack/gem_version.rb +6 -4
  173. data/lib/action_pack/version.rb +3 -1
  174. data/lib/action_pack.rb +17 -16
  175. metadata +36 -32
  176. data/lib/action_dispatch/journey/parser.y +0 -50
  177. data/lib/action_dispatch/journey/parser_extras.rb +0 -31
@@ -1,38 +1,40 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "active_support/core_ext/module/attribute_accessors"
4
6
  require "action_dispatch/http/filter_redirect"
5
7
  require "action_dispatch/http/cache"
6
8
  require "monitor"
7
9
 
8
10
  module ActionDispatch # :nodoc:
9
- # = Action Dispatch \Response
11
+ # # Action Dispatch Response
10
12
  #
11
13
  # Represents an HTTP response generated by a controller action. Use it to
12
14
  # retrieve the current state of the response, or customize the response. It can
13
- # either represent a real HTTP response (i.e. one that is meant to be sent
14
- # back to the web browser) or a TestResponse (i.e. one that is generated
15
- # from integration tests).
15
+ # either represent a real HTTP response (i.e. one that is meant to be sent back
16
+ # to the web browser) or a TestResponse (i.e. one that is generated from
17
+ # integration tests).
16
18
  #
17
- # The \Response object for the current request is exposed on controllers as
18
- # ActionController::Metal#response. ActionController::Metal also provides a
19
- # few additional methods that delegate to attributes of the \Response such as
19
+ # The Response object for the current request is exposed on controllers as
20
+ # ActionController::Metal#response. ActionController::Metal also provides a few
21
+ # additional methods that delegate to attributes of the Response such as
20
22
  # ActionController::Metal#headers.
21
23
  #
22
- # Integration tests will likely also want to inspect responses in
23
- # more detail. Methods such as Integration::RequestHelpers#get
24
- # and Integration::RequestHelpers#post return instances of
25
- # TestResponse (which inherits from \Response) for this purpose.
24
+ # Integration tests will likely also want to inspect responses in more detail.
25
+ # Methods such as Integration::RequestHelpers#get and
26
+ # Integration::RequestHelpers#post return instances of TestResponse (which
27
+ # inherits from Response) for this purpose.
26
28
  #
27
29
  # For example, the following demo integration test prints the body of the
28
30
  # controller response to the console:
29
31
  #
30
- # class DemoControllerTest < ActionDispatch::IntegrationTest
31
- # def test_print_root_path_to_console
32
- # get('/')
33
- # puts response.body
34
- # end
35
- # end
32
+ # class DemoControllerTest < ActionDispatch::IntegrationTest
33
+ # def test_print_root_path_to_console
34
+ # get('/')
35
+ # puts response.body
36
+ # end
37
+ # end
36
38
  class Response
37
39
  begin
38
40
  # For `Rack::Headers` (Rack 3+):
@@ -44,6 +46,20 @@ module ActionDispatch # :nodoc:
44
46
  Headers = ::Rack::Utils::HeaderHash
45
47
  end
46
48
 
49
+ class << self
50
+ if ActionDispatch::Constants::UNPROCESSABLE_CONTENT == :unprocessable_content
51
+ def rack_status_code(status) # :nodoc:
52
+ status = :unprocessable_content if status == :unprocessable_entity
53
+ Rack::Utils.status_code(status)
54
+ end
55
+ else
56
+ def rack_status_code(status) # :nodoc:
57
+ status = :unprocessable_entity if status == :unprocessable_content
58
+ Rack::Utils.status_code(status)
59
+ end
60
+ end
61
+ end
62
+
47
63
  # To be deprecated:
48
64
  Header = Headers
49
65
 
@@ -55,17 +71,17 @@ module ActionDispatch # :nodoc:
55
71
 
56
72
  # The headers for the response.
57
73
  #
58
- # header["Content-Type"] # => "text/plain"
59
- # header["Content-Type"] = "application/json"
60
- # header["Content-Type"] # => "application/json"
74
+ # header["Content-Type"] # => "text/plain"
75
+ # header["Content-Type"] = "application/json"
76
+ # header["Content-Type"] # => "application/json"
61
77
  #
62
- # Also aliased as +headers+.
78
+ # Also aliased as `headers`.
63
79
  #
64
- # headers["Content-Type"] # => "text/plain"
65
- # headers["Content-Type"] = "application/json"
66
- # headers["Content-Type"] # => "application/json"
80
+ # headers["Content-Type"] # => "text/plain"
81
+ # headers["Content-Type"] = "application/json"
82
+ # headers["Content-Type"] # => "application/json"
67
83
  #
68
- # Also aliased as +header+ for compatibility.
84
+ # Also aliased as `header` for compatibility.
69
85
  attr_reader :headers
70
86
 
71
87
  alias_method :header, :headers
@@ -103,10 +119,22 @@ module ActionDispatch # :nodoc:
103
119
  @str_body = nil
104
120
  end
105
121
 
122
+ BODY_METHODS = { to_ary: true }
123
+
124
+ def respond_to?(method, include_private = false)
125
+ if BODY_METHODS.key?(method)
126
+ @buf.respond_to?(method)
127
+ else
128
+ super
129
+ end
130
+ end
131
+
106
132
  def to_ary
107
- @buf.respond_to?(:to_ary) ?
108
- @buf.to_ary :
109
- @buf.each
133
+ if @str_body
134
+ [body]
135
+ else
136
+ @buf = @buf.to_ary
137
+ end
110
138
  end
111
139
 
112
140
  def body
@@ -229,22 +257,47 @@ module ActionDispatch # :nodoc:
229
257
  def committed?; synchronize { @committed }; end
230
258
  def sent?; synchronize { @sent }; end
231
259
 
260
+ ##
261
+ # :method: location
262
+ #
263
+ # Location of the response.
264
+
265
+ ##
266
+ # :method: location=
267
+ #
268
+ # :call-seq: location=(location)
269
+ #
270
+ # Sets the location of the response
271
+
232
272
  # Sets the HTTP status code.
233
273
  def status=(status)
234
- @status = Rack::Utils.status_code(status)
274
+ @status = Response.rack_status_code(status)
235
275
  end
236
276
 
237
- # Sets the HTTP response's content MIME type. For example, in the controller
238
- # you could write this:
277
+ # Sets the HTTP response's content MIME type. For example, in the controller you
278
+ # could write this:
239
279
  #
240
- # response.content_type = "text/plain"
280
+ # response.content_type = "text/html"
241
281
  #
242
- # If a character set has been defined for this response (see charset=) then
243
- # the character set information will also be included in the content type
282
+ # This method also accepts a symbol with the extension of the MIME type:
283
+ #
284
+ # response.content_type = :html
285
+ #
286
+ # If a character set has been defined for this response (see #charset=) then the
287
+ # character set information will also be included in the content type
244
288
  # information.
245
289
  def content_type=(content_type)
246
- return unless content_type
247
- new_header_info = parse_content_type(content_type.to_s)
290
+ case content_type
291
+ when NilClass
292
+ return
293
+ when Symbol
294
+ mime_type = Mime[content_type]
295
+ raise ArgumentError, "Unknown MIME type #{content_type}" unless mime_type
296
+ new_header_info = ContentTypeHeader.new(mime_type.to_s)
297
+ else
298
+ new_header_info = parse_content_type(content_type.to_s)
299
+ end
300
+
248
301
  prev_header_info = parsed_content_type_header
249
302
  charset = new_header_info.charset || prev_header_info.charset
250
303
  charset ||= self.class.default_charset unless prev_header_info.mime_type
@@ -267,11 +320,11 @@ module ActionDispatch # :nodoc:
267
320
  end
268
321
  end
269
322
 
270
- # Sets the HTTP character set. In case of +nil+ parameter
271
- # it sets the charset to +default_charset+.
323
+ # Sets the HTTP character set. In case of `nil` parameter it sets the charset to
324
+ # `default_charset`.
272
325
  #
273
- # response.charset = 'utf-16' # => 'utf-16'
274
- # response.charset = nil # => 'utf-8'
326
+ # response.charset = 'utf-16' # => 'utf-16'
327
+ # response.charset = nil # => 'utf-8'
275
328
  def charset=(charset)
276
329
  content_type = parsed_content_type_header.mime_type
277
330
  if false == charset
@@ -281,8 +334,8 @@ module ActionDispatch # :nodoc:
281
334
  end
282
335
  end
283
336
 
284
- # The charset of the response. HTML wants to know the encoding of the
285
- # content you're giving them, so we need to send that along.
337
+ # The charset of the response. HTML wants to know the encoding of the content
338
+ # you're giving them, so we need to send that along.
286
339
  def charset
287
340
  header_info = parsed_content_type_header
288
341
  header_info.charset || self.class.default_charset
@@ -293,28 +346,34 @@ module ActionDispatch # :nodoc:
293
346
  @status
294
347
  end
295
348
 
296
- # Returns a string to ensure compatibility with +Net::HTTPResponse+.
349
+ # Returns a string to ensure compatibility with `Net::HTTPResponse`.
297
350
  def code
298
351
  @status.to_s
299
352
  end
300
353
 
301
354
  # Returns the corresponding message for the current HTTP status code:
302
355
  #
303
- # response.status = 200
304
- # response.message # => "OK"
356
+ # response.status = 200
357
+ # response.message # => "OK"
305
358
  #
306
- # response.status = 404
307
- # response.message # => "Not Found"
359
+ # response.status = 404
360
+ # response.message # => "Not Found"
308
361
  #
309
362
  def message
310
363
  Rack::Utils::HTTP_STATUS_CODES[@status]
311
364
  end
312
365
  alias_method :status_message, :message
313
366
 
314
- # Returns the content of the response as a string. This contains the contents
315
- # of any calls to <tt>render</tt>.
367
+ # Returns the content of the response as a string. This contains the contents of
368
+ # any calls to `render`.
316
369
  def body
317
- @stream.body
370
+ if @stream.respond_to?(:to_ary)
371
+ @stream.to_ary.join
372
+ elsif @stream.respond_to?(:body)
373
+ @stream.body
374
+ else
375
+ @stream
376
+ end
318
377
  end
319
378
 
320
379
  def write(string)
@@ -323,18 +382,23 @@ module ActionDispatch # :nodoc:
323
382
 
324
383
  # Allows you to manually set or override the response body.
325
384
  def body=(body)
326
- if body.respond_to?(:to_path)
327
- @stream = body
328
- else
329
- synchronize do
330
- @stream = build_buffer self, munge_body_object(body)
385
+ # Prevent ActionController::Metal::Live::Response from committing the response prematurely.
386
+ synchronize do
387
+ if body.respond_to?(:to_str)
388
+ @stream = build_buffer(self, [body])
389
+ elsif body.respond_to?(:to_path)
390
+ @stream = body
391
+ elsif body.respond_to?(:to_ary)
392
+ @stream = build_buffer(self, body)
393
+ else
394
+ @stream = body
331
395
  end
332
396
  end
333
397
  end
334
398
 
335
- # Avoid having to pass an open file handle as the response body.
336
- # Rack::Sendfile will usually intercept the response and uses
337
- # the path directly, so there is no reason to open the file.
399
+ # Avoid having to pass an open file handle as the response body. Rack::Sendfile
400
+ # will usually intercept the response and uses the path directly, so there is no
401
+ # reason to open the file.
338
402
  class FileBody # :nodoc:
339
403
  attr_reader :to_path
340
404
 
@@ -356,7 +420,7 @@ module ActionDispatch # :nodoc:
356
420
  end
357
421
  end
358
422
 
359
- # Send the file stored at +path+ as the response body.
423
+ # Send the file stored at `path` as the response body.
360
424
  def send_file(path)
361
425
  commit!
362
426
  @stream = FileBody.new(path)
@@ -383,17 +447,16 @@ module ActionDispatch # :nodoc:
383
447
  if stream.respond_to?(:abort)
384
448
  stream.abort
385
449
  elsif stream.respond_to?(:close)
386
- # `stream.close` should really be reserved for a close from the
387
- # other direction, but we must fall back to it for
388
- # compatibility.
450
+ # `stream.close` should really be reserved for a close from the other direction,
451
+ # but we must fall back to it for compatibility.
389
452
  stream.close
390
453
  end
391
454
  end
392
455
 
393
- # Turns the Response into a Rack-compatible array of the status, headers,
394
- # and body. Allows explicit splatting:
456
+ # Turns the Response into a Rack-compatible array of the status, headers, and
457
+ # body. Allows explicit splatting:
395
458
  #
396
- # status, headers, body = *response
459
+ # status, headers, body = *response
397
460
  def to_a
398
461
  commit!
399
462
  rack_response @status, @headers.to_hash
@@ -402,7 +465,7 @@ module ActionDispatch # :nodoc:
402
465
 
403
466
  # Returns the response cookies, converted to a Hash of (name => value) pairs
404
467
  #
405
- # assert_equal 'AuthorOfNewPage', r.cookies['author']
468
+ # assert_equal 'AuthorOfNewPage', r.cookies['author']
406
469
  def cookies
407
470
  cookies = {}
408
471
  if header = get_header(SET_COOKIE)
@@ -456,11 +519,10 @@ module ActionDispatch # :nodoc:
456
519
  end
457
520
 
458
521
  def before_sending
459
- # Normally we've already committed by now, but it's possible
460
- # (e.g., if the controller action tries to read back its own
461
- # response) to get here before that. In that case, we must force
462
- # an "early" commit: we're about to freeze the headers, so this is
463
- # our last chance.
522
+ # Normally we've already committed by now, but it's possible (e.g., if the
523
+ # controller action tries to read back its own response) to get here before
524
+ # that. In that case, we must force an "early" commit: we're about to freeze the
525
+ # headers, so this is our last chance.
464
526
  commit! unless committed?
465
527
 
466
528
  @request.commit_cookie_jar! unless committed?
@@ -470,10 +532,6 @@ module ActionDispatch # :nodoc:
470
532
  Buffer.new response, body
471
533
  end
472
534
 
473
- def munge_body_object(body)
474
- body.respond_to?(:each) ? body : [body]
475
- end
476
-
477
535
  def assign_default_content_type_and_charset!
478
536
  return if media_type
479
537
 
@@ -487,9 +545,11 @@ module ActionDispatch # :nodoc:
487
545
  @response = response
488
546
  end
489
547
 
548
+ attr :response
549
+
490
550
  def close
491
- # Rack "close" maps to Response#abort, and *not* Response#close
492
- # (which is used when the controller's finished writing)
551
+ # Rack "close" maps to Response#abort, and **not** Response#close (which is used
552
+ # when the controller's finished writing)
493
553
  @response.abort
494
554
  end
495
555
 
@@ -1,17 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionDispatch
4
6
  module Http
5
- # = Action Dispatch HTTP \UploadedFile
7
+ # # Action Dispatch HTTP UploadedFile
6
8
  #
7
9
  # Models uploaded files.
8
10
  #
9
- # The actual file is accessible via the +tempfile+ accessor, though some
10
- # of its interface is available directly for convenience.
11
+ # The actual file is accessible via the `tempfile` accessor, though some of its
12
+ # interface is available directly for convenience.
11
13
  #
12
- # Uploaded files are temporary files whose lifespan is one request. When
13
- # the object is finalized Ruby unlinks the file, so there is no need to
14
- # clean them with a separate maintenance task.
14
+ # Uploaded files are temporary files whose lifespan is one request. When the
15
+ # object is finalized Ruby unlinks the file, so there is no need to clean them
16
+ # with a separate maintenance task.
15
17
  class UploadedFile
16
18
  # The basename of the file in the client.
17
19
  attr_accessor :original_filename
@@ -19,8 +21,8 @@ module ActionDispatch
19
21
  # A string with the MIME type of the file.
20
22
  attr_accessor :content_type
21
23
 
22
- # A +Tempfile+ object with the actual uploaded file. Note that some of
23
- # its interface is available directly.
24
+ # A `Tempfile` object with the actual uploaded file. Note that some of its
25
+ # interface is available directly.
24
26
  attr_accessor :tempfile
25
27
 
26
28
  # A string with the headers of the multipart request.
@@ -57,42 +59,42 @@ module ActionDispatch
57
59
  end
58
60
  end
59
61
 
60
- # Shortcut for +tempfile.read+.
62
+ # Shortcut for `tempfile.read`.
61
63
  def read(length = nil, buffer = nil)
62
64
  @tempfile.read(length, buffer)
63
65
  end
64
66
 
65
- # Shortcut for +tempfile.open+.
67
+ # Shortcut for `tempfile.open`.
66
68
  def open
67
69
  @tempfile.open
68
70
  end
69
71
 
70
- # Shortcut for +tempfile.close+.
72
+ # Shortcut for `tempfile.close`.
71
73
  def close(unlink_now = false)
72
74
  @tempfile.close(unlink_now)
73
75
  end
74
76
 
75
- # Shortcut for +tempfile.path+.
77
+ # Shortcut for `tempfile.path`.
76
78
  def path
77
79
  @tempfile.path
78
80
  end
79
81
 
80
- # Shortcut for +tempfile.to_path+.
82
+ # Shortcut for `tempfile.to_path`.
81
83
  def to_path
82
84
  @tempfile.to_path
83
85
  end
84
86
 
85
- # Shortcut for +tempfile.rewind+.
87
+ # Shortcut for `tempfile.rewind`.
86
88
  def rewind
87
89
  @tempfile.rewind
88
90
  end
89
91
 
90
- # Shortcut for +tempfile.size+.
92
+ # Shortcut for `tempfile.size`.
91
93
  def size
92
94
  @tempfile.size
93
95
  end
94
96
 
95
- # Shortcut for +tempfile.eof?+.
97
+ # Shortcut for `tempfile.eof?`.
96
98
  def eof?
97
99
  @tempfile.eof?
98
100
  end