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.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- 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)
|