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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +308 -523
- data/README.rdoc +1 -1
- data/lib/abstract_controller/asset_paths.rb +6 -2
- data/lib/abstract_controller/base.rb +104 -105
- data/lib/abstract_controller/caching/fragments.rb +50 -53
- data/lib/abstract_controller/caching.rb +8 -3
- data/lib/abstract_controller/callbacks.rb +70 -62
- data/lib/abstract_controller/collector.rb +7 -7
- data/lib/abstract_controller/deprecator.rb +2 -0
- data/lib/abstract_controller/error.rb +2 -0
- data/lib/abstract_controller/helpers.rb +71 -84
- data/lib/abstract_controller/logger.rb +4 -1
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
- data/lib/abstract_controller/rendering.rb +13 -13
- data/lib/abstract_controller/translation.rb +12 -13
- data/lib/abstract_controller/url_for.rb +8 -6
- data/lib/abstract_controller.rb +2 -0
- data/lib/action_controller/api/api_rendering.rb +2 -0
- data/lib/action_controller/api.rb +76 -72
- data/lib/action_controller/base.rb +199 -126
- data/lib/action_controller/caching.rb +16 -14
- data/lib/action_controller/deprecator.rb +2 -0
- data/lib/action_controller/form_builder.rb +21 -18
- data/lib/action_controller/log_subscriber.rb +23 -2
- data/lib/action_controller/metal/allow_browser.rb +133 -0
- data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
- data/lib/action_controller/metal/conditional_get.rb +217 -175
- data/lib/action_controller/metal/content_security_policy.rb +25 -24
- data/lib/action_controller/metal/cookies.rb +4 -2
- data/lib/action_controller/metal/data_streaming.rb +72 -63
- data/lib/action_controller/metal/default_headers.rb +5 -3
- data/lib/action_controller/metal/etag_with_flash.rb +3 -1
- data/lib/action_controller/metal/etag_with_template_digest.rb +17 -15
- data/lib/action_controller/metal/exceptions.rb +16 -9
- data/lib/action_controller/metal/flash.rb +13 -14
- data/lib/action_controller/metal/head.rb +15 -11
- data/lib/action_controller/metal/helpers.rb +63 -55
- data/lib/action_controller/metal/http_authentication.rb +209 -201
- data/lib/action_controller/metal/implicit_render.rb +17 -15
- data/lib/action_controller/metal/instrumentation.rb +16 -14
- data/lib/action_controller/metal/live.rb +177 -128
- data/lib/action_controller/metal/logging.rb +6 -4
- data/lib/action_controller/metal/mime_responds.rb +151 -142
- data/lib/action_controller/metal/parameter_encoding.rb +34 -32
- data/lib/action_controller/metal/params_wrapper.rb +57 -59
- data/lib/action_controller/metal/permissions_policy.rb +22 -12
- data/lib/action_controller/metal/rate_limiting.rb +92 -0
- data/lib/action_controller/metal/redirecting.rb +213 -94
- data/lib/action_controller/metal/renderers.rb +78 -57
- data/lib/action_controller/metal/rendering.rb +111 -77
- data/lib/action_controller/metal/request_forgery_protection.rb +182 -143
- data/lib/action_controller/metal/rescue.rb +20 -9
- data/lib/action_controller/metal/streaming.rb +118 -195
- data/lib/action_controller/metal/strong_parameters.rb +720 -530
- data/lib/action_controller/metal/testing.rb +2 -0
- data/lib/action_controller/metal/url_for.rb +17 -15
- data/lib/action_controller/metal.rb +86 -60
- data/lib/action_controller/railtie.rb +36 -15
- data/lib/action_controller/railties/helpers.rb +2 -0
- data/lib/action_controller/renderer.rb +41 -36
- data/lib/action_controller/structured_event_subscriber.rb +116 -0
- data/lib/action_controller/template_assertions.rb +4 -2
- data/lib/action_controller/test_case.rb +160 -131
- data/lib/action_controller.rb +5 -1
- data/lib/action_dispatch/constants.rb +8 -0
- data/lib/action_dispatch/deprecator.rb +2 -0
- data/lib/action_dispatch/http/cache.rb +163 -35
- data/lib/action_dispatch/http/content_disposition.rb +2 -0
- data/lib/action_dispatch/http/content_security_policy.rb +54 -39
- data/lib/action_dispatch/http/filter_parameters.rb +14 -8
- data/lib/action_dispatch/http/filter_redirect.rb +22 -1
- data/lib/action_dispatch/http/headers.rb +22 -22
- data/lib/action_dispatch/http/mime_negotiation.rb +89 -41
- data/lib/action_dispatch/http/mime_type.rb +25 -21
- data/lib/action_dispatch/http/mime_types.rb +3 -0
- data/lib/action_dispatch/http/param_builder.rb +187 -0
- data/lib/action_dispatch/http/param_error.rb +26 -0
- data/lib/action_dispatch/http/parameters.rb +14 -12
- data/lib/action_dispatch/http/permissions_policy.rb +25 -36
- data/lib/action_dispatch/http/query_parser.rb +55 -0
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +141 -92
- data/lib/action_dispatch/http/response.rb +137 -77
- data/lib/action_dispatch/http/upload.rb +18 -16
- data/lib/action_dispatch/http/url.rb +187 -89
- data/lib/action_dispatch/journey/formatter.rb +21 -9
- data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
- data/lib/action_dispatch/journey/gtg/simulator.rb +34 -11
- data/lib/action_dispatch/journey/gtg/transition_table.rb +47 -53
- data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
- data/lib/action_dispatch/journey/nodes/node.rb +8 -6
- data/lib/action_dispatch/journey/parser.rb +99 -195
- data/lib/action_dispatch/journey/path/pattern.rb +4 -1
- data/lib/action_dispatch/journey/route.rb +54 -38
- data/lib/action_dispatch/journey/router/utils.rb +22 -27
- data/lib/action_dispatch/journey/router.rb +63 -83
- data/lib/action_dispatch/journey/routes.rb +11 -2
- data/lib/action_dispatch/journey/scanner.rb +46 -42
- data/lib/action_dispatch/journey/visitors.rb +57 -23
- data/lib/action_dispatch/journey/visualizer/fsm.js +4 -6
- data/lib/action_dispatch/journey.rb +2 -0
- data/lib/action_dispatch/log_subscriber.rb +7 -1
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +2 -0
- data/lib/action_dispatch/middleware/assume_ssl.rb +8 -5
- data/lib/action_dispatch/middleware/callbacks.rb +3 -1
- data/lib/action_dispatch/middleware/cookies.rb +125 -106
- data/lib/action_dispatch/middleware/debug_exceptions.rb +37 -8
- data/lib/action_dispatch/middleware/debug_locks.rb +15 -13
- data/lib/action_dispatch/middleware/debug_view.rb +13 -5
- data/lib/action_dispatch/middleware/exception_wrapper.rb +18 -23
- data/lib/action_dispatch/middleware/executor.rb +19 -4
- data/lib/action_dispatch/middleware/flash.rb +63 -51
- data/lib/action_dispatch/middleware/host_authorization.rb +17 -15
- data/lib/action_dispatch/middleware/public_exceptions.rb +14 -12
- data/lib/action_dispatch/middleware/reloader.rb +5 -3
- data/lib/action_dispatch/middleware/remote_ip.rb +87 -77
- data/lib/action_dispatch/middleware/request_id.rb +16 -10
- data/lib/action_dispatch/middleware/server_timing.rb +4 -2
- data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +30 -8
- data/lib/action_dispatch/middleware/session/cookie_store.rb +27 -26
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +7 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +16 -16
- data/lib/action_dispatch/middleware/ssl.rb +53 -40
- data/lib/action_dispatch/middleware/stack.rb +11 -10
- data/lib/action_dispatch/middleware/static.rb +33 -31
- data/lib/action_dispatch/middleware/templates/rescues/_copy_button.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +3 -5
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +9 -5
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +4 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +50 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +1 -1
- data/lib/action_dispatch/railtie.rb +23 -3
- data/lib/action_dispatch/request/session.rb +24 -21
- data/lib/action_dispatch/request/utils.rb +11 -3
- data/lib/action_dispatch/routing/endpoint.rb +2 -0
- data/lib/action_dispatch/routing/inspector.rb +85 -60
- data/lib/action_dispatch/routing/mapper.rb +1031 -851
- data/lib/action_dispatch/routing/polymorphic_routes.rb +69 -62
- data/lib/action_dispatch/routing/redirection.rb +47 -39
- data/lib/action_dispatch/routing/route_set.rb +79 -56
- data/lib/action_dispatch/routing/routes_proxy.rb +7 -4
- data/lib/action_dispatch/routing/url_for.rb +130 -125
- data/lib/action_dispatch/routing.rb +150 -148
- data/lib/action_dispatch/structured_event_subscriber.rb +20 -0
- data/lib/action_dispatch/system_test_case.rb +91 -81
- data/lib/action_dispatch/system_testing/browser.rb +16 -23
- data/lib/action_dispatch/system_testing/driver.rb +2 -0
- data/lib/action_dispatch/system_testing/server.rb +2 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +34 -23
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
- data/lib/action_dispatch/testing/assertion_response.rb +9 -7
- data/lib/action_dispatch/testing/assertions/response.rb +52 -25
- data/lib/action_dispatch/testing/assertions/routing.rb +168 -87
- data/lib/action_dispatch/testing/assertions.rb +2 -0
- data/lib/action_dispatch/testing/integration.rb +233 -223
- data/lib/action_dispatch/testing/request_encoder.rb +11 -9
- data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
- data/lib/action_dispatch/testing/test_process.rb +11 -8
- data/lib/action_dispatch/testing/test_request.rb +3 -1
- data/lib/action_dispatch/testing/test_response.rb +27 -26
- data/lib/action_dispatch.rb +36 -32
- data/lib/action_pack/gem_version.rb +6 -4
- data/lib/action_pack/version.rb +3 -1
- data/lib/action_pack.rb +17 -16
- metadata +36 -32
- data/lib/action_dispatch/journey/parser.y +0 -50
- 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
|
-
#
|
|
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
|
-
#
|
|
15
|
-
#
|
|
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
|
|
18
|
-
# ActionController::Metal#response. ActionController::Metal also provides a
|
|
19
|
-
#
|
|
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
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
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
|
-
#
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
-
#
|
|
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
|
-
#
|
|
59
|
-
#
|
|
60
|
-
#
|
|
74
|
+
# header["Content-Type"] # => "text/plain"
|
|
75
|
+
# header["Content-Type"] = "application/json"
|
|
76
|
+
# header["Content-Type"] # => "application/json"
|
|
61
77
|
#
|
|
62
|
-
# Also aliased as
|
|
78
|
+
# Also aliased as `headers`.
|
|
63
79
|
#
|
|
64
|
-
#
|
|
65
|
-
#
|
|
66
|
-
#
|
|
80
|
+
# headers["Content-Type"] # => "text/plain"
|
|
81
|
+
# headers["Content-Type"] = "application/json"
|
|
82
|
+
# headers["Content-Type"] # => "application/json"
|
|
67
83
|
#
|
|
68
|
-
# Also aliased as
|
|
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
|
-
@
|
|
108
|
-
|
|
109
|
-
|
|
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 =
|
|
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
|
-
#
|
|
277
|
+
# Sets the HTTP response's content MIME type. For example, in the controller you
|
|
278
|
+
# could write this:
|
|
239
279
|
#
|
|
240
|
-
#
|
|
280
|
+
# response.content_type = "text/html"
|
|
241
281
|
#
|
|
242
|
-
#
|
|
243
|
-
#
|
|
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
|
-
|
|
247
|
-
|
|
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
|
|
271
|
-
#
|
|
323
|
+
# Sets the HTTP character set. In case of `nil` parameter it sets the charset to
|
|
324
|
+
# `default_charset`.
|
|
272
325
|
#
|
|
273
|
-
#
|
|
274
|
-
#
|
|
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
|
-
#
|
|
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
|
|
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
|
-
#
|
|
304
|
-
#
|
|
356
|
+
# response.status = 200
|
|
357
|
+
# response.message # => "OK"
|
|
305
358
|
#
|
|
306
|
-
#
|
|
307
|
-
#
|
|
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
|
-
#
|
|
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.
|
|
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
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
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
|
-
#
|
|
337
|
-
#
|
|
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
|
|
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
|
-
#
|
|
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
|
-
#
|
|
456
|
+
# Turns the Response into a Rack-compatible array of the status, headers, and
|
|
457
|
+
# body. Allows explicit splatting:
|
|
395
458
|
#
|
|
396
|
-
#
|
|
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
|
-
#
|
|
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
|
-
#
|
|
461
|
-
#
|
|
462
|
-
#
|
|
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
|
|
492
|
-
#
|
|
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
|
-
#
|
|
7
|
+
# # Action Dispatch HTTP UploadedFile
|
|
6
8
|
#
|
|
7
9
|
# Models uploaded files.
|
|
8
10
|
#
|
|
9
|
-
# The actual file is accessible via the
|
|
10
|
-
#
|
|
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
|
-
#
|
|
14
|
-
#
|
|
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
|
|
23
|
-
#
|
|
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
|
|
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
|
|
67
|
+
# Shortcut for `tempfile.open`.
|
|
66
68
|
def open
|
|
67
69
|
@tempfile.open
|
|
68
70
|
end
|
|
69
71
|
|
|
70
|
-
# Shortcut for
|
|
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
|
|
77
|
+
# Shortcut for `tempfile.path`.
|
|
76
78
|
def path
|
|
77
79
|
@tempfile.path
|
|
78
80
|
end
|
|
79
81
|
|
|
80
|
-
# Shortcut for
|
|
82
|
+
# Shortcut for `tempfile.to_path`.
|
|
81
83
|
def to_path
|
|
82
84
|
@tempfile.to_path
|
|
83
85
|
end
|
|
84
86
|
|
|
85
|
-
# Shortcut for
|
|
87
|
+
# Shortcut for `tempfile.rewind`.
|
|
86
88
|
def rewind
|
|
87
89
|
@tempfile.rewind
|
|
88
90
|
end
|
|
89
91
|
|
|
90
|
-
# Shortcut for
|
|
92
|
+
# Shortcut for `tempfile.size`.
|
|
91
93
|
def size
|
|
92
94
|
@tempfile.size
|
|
93
95
|
end
|
|
94
96
|
|
|
95
|
-
# Shortcut for
|
|
97
|
+
# Shortcut for `tempfile.eof?`.
|
|
96
98
|
def eof?
|
|
97
99
|
@tempfile.eof?
|
|
98
100
|
end
|