actionpack 7.1.3 → 7.2.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +82 -501
- data/lib/abstract_controller/asset_paths.rb +2 -0
- data/lib/abstract_controller/base.rb +102 -98
- data/lib/abstract_controller/caching/fragments.rb +50 -53
- data/lib/abstract_controller/caching.rb +2 -0
- data/lib/abstract_controller/callbacks.rb +66 -64
- data/lib/abstract_controller/collector.rb +6 -6
- data/lib/abstract_controller/deprecator.rb +2 -0
- data/lib/abstract_controller/error.rb +2 -0
- data/lib/abstract_controller/helpers.rb +70 -85
- data/lib/abstract_controller/logger.rb +2 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
- data/lib/abstract_controller/rendering.rb +13 -12
- data/lib/abstract_controller/translation.rb +15 -7
- 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 +74 -72
- data/lib/action_controller/base.rb +198 -126
- data/lib/action_controller/caching.rb +15 -12
- data/lib/action_controller/deprecator.rb +2 -0
- data/lib/action_controller/form_builder.rb +20 -17
- data/lib/action_controller/log_subscriber.rb +3 -1
- data/lib/action_controller/metal/allow_browser.rb +123 -0
- data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
- data/lib/action_controller/metal/conditional_get.rb +188 -174
- 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 +64 -55
- 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 +11 -9
- data/lib/action_controller/metal/flash.rb +12 -10
- data/lib/action_controller/metal/head.rb +12 -10
- data/lib/action_controller/metal/helpers.rb +63 -55
- data/lib/action_controller/metal/http_authentication.rb +210 -205
- data/lib/action_controller/metal/implicit_render.rb +17 -15
- data/lib/action_controller/metal/instrumentation.rb +15 -12
- data/lib/action_controller/metal/live.rb +113 -107
- 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 +13 -12
- data/lib/action_controller/metal/rate_limiting.rb +62 -0
- data/lib/action_controller/metal/redirecting.rb +108 -82
- data/lib/action_controller/metal/renderers.rb +50 -49
- data/lib/action_controller/metal/rendering.rb +103 -75
- data/lib/action_controller/metal/request_forgery_protection.rb +162 -133
- data/lib/action_controller/metal/rescue.rb +11 -9
- data/lib/action_controller/metal/streaming.rb +138 -136
- data/lib/action_controller/metal/strong_parameters.rb +525 -480
- 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 +3 -0
- data/lib/action_controller/railties/helpers.rb +2 -0
- data/lib/action_controller/renderer.rb +42 -36
- data/lib/action_controller/template_assertions.rb +4 -2
- data/lib/action_controller/test_case.rb +146 -126
- data/lib/action_controller.rb +10 -3
- data/lib/action_dispatch/constants.rb +2 -0
- data/lib/action_dispatch/deprecator.rb +2 -0
- data/lib/action_dispatch/http/cache.rb +27 -26
- data/lib/action_dispatch/http/content_disposition.rb +2 -0
- data/lib/action_dispatch/http/content_security_policy.rb +44 -38
- data/lib/action_dispatch/http/filter_parameters.rb +18 -9
- 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 +30 -41
- data/lib/action_dispatch/http/mime_type.rb +31 -24
- data/lib/action_dispatch/http/mime_types.rb +2 -0
- data/lib/action_dispatch/http/parameters.rb +11 -9
- data/lib/action_dispatch/http/permissions_policy.rb +20 -44
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +94 -75
- data/lib/action_dispatch/http/response.rb +73 -61
- data/lib/action_dispatch/http/upload.rb +18 -16
- data/lib/action_dispatch/http/url.rb +75 -73
- data/lib/action_dispatch/journey/formatter.rb +13 -6
- data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
- data/lib/action_dispatch/journey/gtg/simulator.rb +2 -0
- data/lib/action_dispatch/journey/gtg/transition_table.rb +10 -8
- data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
- data/lib/action_dispatch/journey/nodes/node.rb +6 -5
- data/lib/action_dispatch/journey/parser.rb +4 -3
- data/lib/action_dispatch/journey/parser_extras.rb +2 -0
- data/lib/action_dispatch/journey/path/pattern.rb +4 -1
- data/lib/action_dispatch/journey/route.rb +9 -7
- data/lib/action_dispatch/journey/router/utils.rb +16 -15
- data/lib/action_dispatch/journey/router.rb +4 -2
- data/lib/action_dispatch/journey/routes.rb +4 -2
- data/lib/action_dispatch/journey/scanner.rb +4 -2
- data/lib/action_dispatch/journey/visitors.rb +2 -0
- data/lib/action_dispatch/journey.rb +2 -0
- data/lib/action_dispatch/log_subscriber.rb +2 -0
- 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 +119 -104
- data/lib/action_dispatch/middleware/debug_exceptions.rb +13 -5
- data/lib/action_dispatch/middleware/debug_locks.rb +15 -13
- data/lib/action_dispatch/middleware/debug_view.rb +2 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +6 -11
- data/lib/action_dispatch/middleware/executor.rb +8 -0
- 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 +8 -6
- data/lib/action_dispatch/middleware/reloader.rb +5 -3
- data/lib/action_dispatch/middleware/remote_ip.rb +77 -72
- data/lib/action_dispatch/middleware/request_id.rb +14 -9
- 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 +13 -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 +31 -21
- data/lib/action_dispatch/middleware/ssl.rb +43 -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/_source.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +1 -1
- data/lib/action_dispatch/railtie.rb +2 -4
- data/lib/action_dispatch/request/session.rb +23 -21
- data/lib/action_dispatch/request/utils.rb +2 -0
- data/lib/action_dispatch/routing/endpoint.rb +2 -0
- data/lib/action_dispatch/routing/inspector.rb +5 -3
- data/lib/action_dispatch/routing/mapper.rb +671 -636
- data/lib/action_dispatch/routing/polymorphic_routes.rb +69 -62
- data/lib/action_dispatch/routing/redirection.rb +37 -32
- data/lib/action_dispatch/routing/route_set.rb +59 -45
- data/lib/action_dispatch/routing/routes_proxy.rb +6 -4
- data/lib/action_dispatch/routing/url_for.rb +130 -125
- data/lib/action_dispatch/routing.rb +150 -148
- data/lib/action_dispatch/system_test_case.rb +91 -81
- data/lib/action_dispatch/system_testing/browser.rb +10 -3
- data/lib/action_dispatch/system_testing/driver.rb +3 -1
- data/lib/action_dispatch/system_testing/server.rb +2 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +32 -21
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
- data/lib/action_dispatch/testing/assertion_response.rb +8 -6
- data/lib/action_dispatch/testing/assertions/response.rb +26 -23
- data/lib/action_dispatch/testing/assertions/routing.rb +153 -84
- data/lib/action_dispatch/testing/assertions.rb +2 -0
- data/lib/action_dispatch/testing/integration.rb +223 -222
- data/lib/action_dispatch/testing/request_encoder.rb +2 -0
- data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
- data/lib/action_dispatch/testing/test_process.rb +12 -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 +22 -28
- 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 +39 -16
@@ -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+):
|
@@ -55,17 +57,17 @@ module ActionDispatch # :nodoc:
|
|
55
57
|
|
56
58
|
# The headers for the response.
|
57
59
|
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
60
|
+
# header["Content-Type"] # => "text/plain"
|
61
|
+
# header["Content-Type"] = "application/json"
|
62
|
+
# header["Content-Type"] # => "application/json"
|
61
63
|
#
|
62
|
-
# Also aliased as
|
64
|
+
# Also aliased as `headers`.
|
63
65
|
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
66
|
+
# headers["Content-Type"] # => "text/plain"
|
67
|
+
# headers["Content-Type"] = "application/json"
|
68
|
+
# headers["Content-Type"] # => "application/json"
|
67
69
|
#
|
68
|
-
# Also aliased as
|
70
|
+
# Also aliased as `header` for compatibility.
|
69
71
|
attr_reader :headers
|
70
72
|
|
71
73
|
alias_method :header, :headers
|
@@ -229,18 +231,30 @@ module ActionDispatch # :nodoc:
|
|
229
231
|
def committed?; synchronize { @committed }; end
|
230
232
|
def sent?; synchronize { @sent }; end
|
231
233
|
|
234
|
+
##
|
235
|
+
# :method: location
|
236
|
+
#
|
237
|
+
# Location of the response.
|
238
|
+
|
239
|
+
##
|
240
|
+
# :method: location=
|
241
|
+
#
|
242
|
+
# :call-seq: location=(location)
|
243
|
+
#
|
244
|
+
# Sets the location of the response
|
245
|
+
|
232
246
|
# Sets the HTTP status code.
|
233
247
|
def status=(status)
|
234
248
|
@status = Rack::Utils.status_code(status)
|
235
249
|
end
|
236
250
|
|
237
|
-
# Sets the HTTP response's content MIME type. For example, in the controller
|
238
|
-
#
|
251
|
+
# Sets the HTTP response's content MIME type. For example, in the controller you
|
252
|
+
# could write this:
|
239
253
|
#
|
240
|
-
#
|
254
|
+
# response.content_type = "text/plain"
|
241
255
|
#
|
242
|
-
# If a character set has been defined for this response (see charset=) then
|
243
|
-
#
|
256
|
+
# If a character set has been defined for this response (see #charset=) then the
|
257
|
+
# character set information will also be included in the content type
|
244
258
|
# information.
|
245
259
|
def content_type=(content_type)
|
246
260
|
return unless content_type
|
@@ -267,11 +281,11 @@ module ActionDispatch # :nodoc:
|
|
267
281
|
end
|
268
282
|
end
|
269
283
|
|
270
|
-
# Sets the HTTP character set. In case of
|
271
|
-
#
|
284
|
+
# Sets the HTTP character set. In case of `nil` parameter it sets the charset to
|
285
|
+
# `default_charset`.
|
272
286
|
#
|
273
|
-
#
|
274
|
-
#
|
287
|
+
# response.charset = 'utf-16' # => 'utf-16'
|
288
|
+
# response.charset = nil # => 'utf-8'
|
275
289
|
def charset=(charset)
|
276
290
|
content_type = parsed_content_type_header.mime_type
|
277
291
|
if false == charset
|
@@ -281,8 +295,8 @@ module ActionDispatch # :nodoc:
|
|
281
295
|
end
|
282
296
|
end
|
283
297
|
|
284
|
-
# The charset of the response. HTML wants to know the encoding of the
|
285
|
-
#
|
298
|
+
# The charset of the response. HTML wants to know the encoding of the content
|
299
|
+
# you're giving them, so we need to send that along.
|
286
300
|
def charset
|
287
301
|
header_info = parsed_content_type_header
|
288
302
|
header_info.charset || self.class.default_charset
|
@@ -293,26 +307,26 @@ module ActionDispatch # :nodoc:
|
|
293
307
|
@status
|
294
308
|
end
|
295
309
|
|
296
|
-
# Returns a string to ensure compatibility with
|
310
|
+
# Returns a string to ensure compatibility with `Net::HTTPResponse`.
|
297
311
|
def code
|
298
312
|
@status.to_s
|
299
313
|
end
|
300
314
|
|
301
315
|
# Returns the corresponding message for the current HTTP status code:
|
302
316
|
#
|
303
|
-
#
|
304
|
-
#
|
317
|
+
# response.status = 200
|
318
|
+
# response.message # => "OK"
|
305
319
|
#
|
306
|
-
#
|
307
|
-
#
|
320
|
+
# response.status = 404
|
321
|
+
# response.message # => "Not Found"
|
308
322
|
#
|
309
323
|
def message
|
310
324
|
Rack::Utils::HTTP_STATUS_CODES[@status]
|
311
325
|
end
|
312
326
|
alias_method :status_message, :message
|
313
327
|
|
314
|
-
# Returns the content of the response as a string. This contains the contents
|
315
|
-
#
|
328
|
+
# Returns the content of the response as a string. This contains the contents of
|
329
|
+
# any calls to `render`.
|
316
330
|
def body
|
317
331
|
@stream.body
|
318
332
|
end
|
@@ -332,9 +346,9 @@ module ActionDispatch # :nodoc:
|
|
332
346
|
end
|
333
347
|
end
|
334
348
|
|
335
|
-
# Avoid having to pass an open file handle as the response body.
|
336
|
-
#
|
337
|
-
#
|
349
|
+
# Avoid having to pass an open file handle as the response body. Rack::Sendfile
|
350
|
+
# will usually intercept the response and uses the path directly, so there is no
|
351
|
+
# reason to open the file.
|
338
352
|
class FileBody # :nodoc:
|
339
353
|
attr_reader :to_path
|
340
354
|
|
@@ -356,7 +370,7 @@ module ActionDispatch # :nodoc:
|
|
356
370
|
end
|
357
371
|
end
|
358
372
|
|
359
|
-
# Send the file stored at
|
373
|
+
# Send the file stored at `path` as the response body.
|
360
374
|
def send_file(path)
|
361
375
|
commit!
|
362
376
|
@stream = FileBody.new(path)
|
@@ -383,17 +397,16 @@ module ActionDispatch # :nodoc:
|
|
383
397
|
if stream.respond_to?(:abort)
|
384
398
|
stream.abort
|
385
399
|
elsif stream.respond_to?(:close)
|
386
|
-
# `stream.close` should really be reserved for a close from the
|
387
|
-
#
|
388
|
-
# compatibility.
|
400
|
+
# `stream.close` should really be reserved for a close from the other direction,
|
401
|
+
# but we must fall back to it for compatibility.
|
389
402
|
stream.close
|
390
403
|
end
|
391
404
|
end
|
392
405
|
|
393
|
-
# Turns the Response into a Rack-compatible array of the status, headers,
|
394
|
-
#
|
406
|
+
# Turns the Response into a Rack-compatible array of the status, headers, and
|
407
|
+
# body. Allows explicit splatting:
|
395
408
|
#
|
396
|
-
#
|
409
|
+
# status, headers, body = *response
|
397
410
|
def to_a
|
398
411
|
commit!
|
399
412
|
rack_response @status, @headers.to_hash
|
@@ -402,7 +415,7 @@ module ActionDispatch # :nodoc:
|
|
402
415
|
|
403
416
|
# Returns the response cookies, converted to a Hash of (name => value) pairs
|
404
417
|
#
|
405
|
-
#
|
418
|
+
# assert_equal 'AuthorOfNewPage', r.cookies['author']
|
406
419
|
def cookies
|
407
420
|
cookies = {}
|
408
421
|
if header = get_header(SET_COOKIE)
|
@@ -456,11 +469,10 @@ module ActionDispatch # :nodoc:
|
|
456
469
|
end
|
457
470
|
|
458
471
|
def before_sending
|
459
|
-
# Normally we've already committed by now, but it's possible
|
460
|
-
#
|
461
|
-
#
|
462
|
-
#
|
463
|
-
# our last chance.
|
472
|
+
# Normally we've already committed by now, but it's possible (e.g., if the
|
473
|
+
# controller action tries to read back its own response) to get here before
|
474
|
+
# that. In that case, we must force an "early" commit: we're about to freeze the
|
475
|
+
# headers, so this is our last chance.
|
464
476
|
commit! unless committed?
|
465
477
|
|
466
478
|
@request.commit_cookie_jar! unless committed?
|
@@ -488,8 +500,8 @@ module ActionDispatch # :nodoc:
|
|
488
500
|
end
|
489
501
|
|
490
502
|
def close
|
491
|
-
# Rack "close" maps to Response#abort, and
|
492
|
-
#
|
503
|
+
# Rack "close" maps to Response#abort, and **not** Response#close (which is used
|
504
|
+
# when the controller's finished writing)
|
493
505
|
@response.abort
|
494
506
|
end
|
495
507
|
|
@@ -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
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "active_support/core_ext/module/attribute_accessors"
|
4
6
|
|
5
7
|
module ActionDispatch
|
@@ -15,20 +17,20 @@ module ActionDispatch
|
|
15
17
|
class << self
|
16
18
|
# Returns the domain part of a host given the domain level.
|
17
19
|
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
20
|
+
# # Top-level domain example
|
21
|
+
# extract_domain('www.example.com', 1) # => "example.com"
|
22
|
+
# # Second-level domain example
|
23
|
+
# extract_domain('dev.www.example.co.uk', 2) # => "example.co.uk"
|
22
24
|
def extract_domain(host, tld_length)
|
23
25
|
extract_domain_from(host, tld_length) if named_host?(host)
|
24
26
|
end
|
25
27
|
|
26
28
|
# Returns the subdomains of a host as an Array given the domain level.
|
27
29
|
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
30
|
+
# # Top-level domain example
|
31
|
+
# extract_subdomains('www.example.com', 1) # => ["www"]
|
32
|
+
# # Second-level domain example
|
33
|
+
# extract_subdomains('dev.www.example.co.uk', 2) # => ["dev", "www"]
|
32
34
|
def extract_subdomains(host, tld_length)
|
33
35
|
if named_host?(host)
|
34
36
|
extract_subdomains_from(host, tld_length)
|
@@ -39,10 +41,10 @@ module ActionDispatch
|
|
39
41
|
|
40
42
|
# Returns the subdomains of a host as a String given the domain level.
|
41
43
|
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
44
|
+
# # Top-level domain example
|
45
|
+
# extract_subdomain('www.example.com', 1) # => "www"
|
46
|
+
# # Second-level domain example
|
47
|
+
# extract_subdomain('dev.www.example.co.uk', 2) # => "dev.www"
|
46
48
|
def extract_subdomain(host, tld_length)
|
47
49
|
extract_subdomains(host, tld_length).join(".")
|
48
50
|
end
|
@@ -184,33 +186,33 @@ module ActionDispatch
|
|
184
186
|
|
185
187
|
# Returns the complete URL used for this request.
|
186
188
|
#
|
187
|
-
#
|
188
|
-
#
|
189
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
|
190
|
+
# req.url # => "http://example.com"
|
189
191
|
def url
|
190
192
|
protocol + host_with_port + fullpath
|
191
193
|
end
|
192
194
|
|
193
195
|
# Returns 'https://' if this is an SSL request and 'http://' otherwise.
|
194
196
|
#
|
195
|
-
#
|
196
|
-
#
|
197
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
|
198
|
+
# req.protocol # => "http://"
|
197
199
|
#
|
198
|
-
#
|
199
|
-
#
|
200
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com', 'HTTPS' => 'on'
|
201
|
+
# req.protocol # => "https://"
|
200
202
|
def protocol
|
201
203
|
@protocol ||= ssl? ? "https://" : "http://"
|
202
204
|
end
|
203
205
|
|
204
|
-
# Returns the
|
206
|
+
# Returns the host and port for this request, such as "example.com:8080".
|
205
207
|
#
|
206
|
-
#
|
207
|
-
#
|
208
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
|
209
|
+
# req.raw_host_with_port # => "example.com"
|
208
210
|
#
|
209
|
-
#
|
210
|
-
#
|
211
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
|
212
|
+
# req.raw_host_with_port # => "example.com:80"
|
211
213
|
#
|
212
|
-
#
|
213
|
-
#
|
214
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
215
|
+
# req.raw_host_with_port # => "example.com:8080"
|
214
216
|
def raw_host_with_port
|
215
217
|
if forwarded = x_forwarded_host.presence
|
216
218
|
forwarded.split(/,\s?/).last
|
@@ -221,35 +223,35 @@ module ActionDispatch
|
|
221
223
|
|
222
224
|
# Returns the host for this request, such as "example.com".
|
223
225
|
#
|
224
|
-
#
|
225
|
-
#
|
226
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
227
|
+
# req.host # => "example.com"
|
226
228
|
def host
|
227
229
|
raw_host_with_port.sub(/:\d+$/, "")
|
228
230
|
end
|
229
231
|
|
230
|
-
# Returns a
|
231
|
-
# "example.com:8080". Port is only included if it is not a default port
|
232
|
-
#
|
232
|
+
# Returns a host:port string for this request, such as "example.com" or
|
233
|
+
# "example.com:8080". Port is only included if it is not a default port (80 or
|
234
|
+
# 443)
|
233
235
|
#
|
234
|
-
#
|
235
|
-
#
|
236
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
|
237
|
+
# req.host_with_port # => "example.com"
|
236
238
|
#
|
237
|
-
#
|
238
|
-
#
|
239
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
|
240
|
+
# req.host_with_port # => "example.com"
|
239
241
|
#
|
240
|
-
#
|
241
|
-
#
|
242
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
243
|
+
# req.host_with_port # => "example.com:8080"
|
242
244
|
def host_with_port
|
243
245
|
"#{host}#{port_string}"
|
244
246
|
end
|
245
247
|
|
246
248
|
# Returns the port number of this request as an integer.
|
247
249
|
#
|
248
|
-
#
|
249
|
-
#
|
250
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
|
251
|
+
# req.port # => 80
|
250
252
|
#
|
251
|
-
#
|
252
|
-
#
|
253
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
254
|
+
# req.port # => 8080
|
253
255
|
def port
|
254
256
|
@port ||= if raw_host_with_port =~ /:(\d+)$/
|
255
257
|
$1.to_i
|
@@ -258,10 +260,10 @@ module ActionDispatch
|
|
258
260
|
end
|
259
261
|
end
|
260
262
|
|
261
|
-
# Returns the standard
|
263
|
+
# Returns the standard port number for this request's protocol.
|
262
264
|
#
|
263
|
-
#
|
264
|
-
#
|
265
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
266
|
+
# req.standard_port # => 80
|
265
267
|
def standard_port
|
266
268
|
if "https://" == protocol
|
267
269
|
443
|
@@ -272,68 +274,68 @@ module ActionDispatch
|
|
272
274
|
|
273
275
|
# Returns whether this request is using the standard port
|
274
276
|
#
|
275
|
-
#
|
276
|
-
#
|
277
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
|
278
|
+
# req.standard_port? # => true
|
277
279
|
#
|
278
|
-
#
|
279
|
-
#
|
280
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
281
|
+
# req.standard_port? # => false
|
280
282
|
def standard_port?
|
281
283
|
port == standard_port
|
282
284
|
end
|
283
285
|
|
284
|
-
# Returns a number
|
285
|
-
#
|
286
|
+
# Returns a number port suffix like 8080 if the port number of this request is
|
287
|
+
# not the default HTTP port 80 or HTTPS port 443.
|
286
288
|
#
|
287
|
-
#
|
288
|
-
#
|
289
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
|
290
|
+
# req.optional_port # => nil
|
289
291
|
#
|
290
|
-
#
|
291
|
-
#
|
292
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
293
|
+
# req.optional_port # => 8080
|
292
294
|
def optional_port
|
293
295
|
standard_port? ? nil : port
|
294
296
|
end
|
295
297
|
|
296
|
-
# Returns a string
|
297
|
-
#
|
298
|
+
# Returns a string port suffix, including colon, like ":8080" if the port number
|
299
|
+
# of this request is not the default HTTP port 80 or HTTPS port 443.
|
298
300
|
#
|
299
|
-
#
|
300
|
-
#
|
301
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
|
302
|
+
# req.port_string # => ""
|
301
303
|
#
|
302
|
-
#
|
303
|
-
#
|
304
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
305
|
+
# req.port_string # => ":8080"
|
304
306
|
def port_string
|
305
307
|
standard_port? ? "" : ":#{port}"
|
306
308
|
end
|
307
309
|
|
308
310
|
# Returns the requested port, such as 8080, based on SERVER_PORT
|
309
311
|
#
|
310
|
-
#
|
311
|
-
#
|
312
|
+
# req = ActionDispatch::Request.new 'SERVER_PORT' => '80'
|
313
|
+
# req.server_port # => 80
|
312
314
|
#
|
313
|
-
#
|
314
|
-
#
|
315
|
+
# req = ActionDispatch::Request.new 'SERVER_PORT' => '8080'
|
316
|
+
# req.server_port # => 8080
|
315
317
|
def server_port
|
316
318
|
get_header("SERVER_PORT").to_i
|
317
319
|
end
|
318
320
|
|
319
|
-
# Returns the
|
320
|
-
# a different
|
321
|
+
# Returns the domain part of a host, such as "rubyonrails.org" in
|
322
|
+
# "www.rubyonrails.org". You can specify a different `tld_length`, such as 2 to
|
323
|
+
# catch rubyonrails.co.uk in "www.rubyonrails.co.uk".
|
321
324
|
def domain(tld_length = @@tld_length)
|
322
325
|
ActionDispatch::Http::URL.extract_domain(host, tld_length)
|
323
326
|
end
|
324
327
|
|
325
|
-
# Returns all the
|
326
|
-
#
|
327
|
-
#
|
328
|
-
#
|
328
|
+
# Returns all the subdomains as an array, so `["dev", "www"]` would be returned
|
329
|
+
# for "dev.www.rubyonrails.org". You can specify a different `tld_length`, such
|
330
|
+
# as 2 to catch `["www"]` instead of `["www", "rubyonrails"]` in
|
331
|
+
# "www.rubyonrails.co.uk".
|
329
332
|
def subdomains(tld_length = @@tld_length)
|
330
333
|
ActionDispatch::Http::URL.extract_subdomains(host, tld_length)
|
331
334
|
end
|
332
335
|
|
333
|
-
# Returns all the
|
334
|
-
#
|
335
|
-
#
|
336
|
-
# in "www.rubyonrails.co.uk".
|
336
|
+
# Returns all the subdomains as a string, so `"dev.www"` would be returned for
|
337
|
+
# "dev.www.rubyonrails.org". You can specify a different `tld_length`, such as 2
|
338
|
+
# to catch `"www"` instead of `"www.rubyonrails"` in "www.rubyonrails.co.uk".
|
337
339
|
def subdomain(tld_length = @@tld_length)
|
338
340
|
ActionDispatch::Http::URL.extract_subdomain(host, tld_length)
|
339
341
|
end
|
@@ -1,12 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "action_controller/metal/exceptions"
|
4
6
|
|
5
7
|
module ActionDispatch
|
6
8
|
# :stopdoc:
|
7
9
|
module Journey
|
8
10
|
# The Formatter class is used for formatting URLs. For example, parameters
|
9
|
-
# passed to
|
11
|
+
# passed to `url_for` in Rails will eventually call Formatter#generate.
|
10
12
|
class Formatter
|
11
13
|
attr_reader :routes
|
12
14
|
|
@@ -66,16 +68,16 @@ module ActionDispatch
|
|
66
68
|
match_route(name, constraints) do |route|
|
67
69
|
parameterized_parts = extract_parameterized_parts(route, options, path_parameters)
|
68
70
|
|
69
|
-
# Skip this route unless a name has been provided or it is a
|
70
|
-
#
|
71
|
-
#
|
71
|
+
# Skip this route unless a name has been provided or it is a standard Rails
|
72
|
+
# route since we can't determine whether an options hash passed to url_for
|
73
|
+
# matches a Rack application or a redirect.
|
72
74
|
next unless name || route.dispatcher?
|
73
75
|
|
74
76
|
missing_keys = missing_keys(route, parameterized_parts)
|
75
77
|
next if missing_keys && !missing_keys.empty?
|
76
78
|
params = options.delete_if do |key, _|
|
77
|
-
# top-level params' normal behavior of generating query_params
|
78
|
-
#
|
79
|
+
# top-level params' normal behavior of generating query_params should be
|
80
|
+
# preserved even if the same key is also a bind_param
|
79
81
|
parameterized_parts.key?(key) || route.defaults.key?(key) ||
|
80
82
|
(path_params.key?(key) && !original_options.key?(key))
|
81
83
|
end
|
@@ -104,6 +106,11 @@ module ActionDispatch
|
|
104
106
|
@cache = nil
|
105
107
|
end
|
106
108
|
|
109
|
+
def eager_load!
|
110
|
+
cache
|
111
|
+
nil
|
112
|
+
end
|
113
|
+
|
107
114
|
private
|
108
115
|
def extract_parameterized_parts(route, options, recall)
|
109
116
|
parameterized_parts = recall.merge(options)
|