actionpack 7.1.3.2 → 7.2.0.beta1
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 +70 -530
- 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 +11 -10
- 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 +155 -117
- 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 +119 -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 +209 -201
- 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 +58 -57
- 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 +9 -5
- data/lib/action_dispatch/http/filter_redirect.rb +15 -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 +29 -22
- 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 -37
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +71 -71
- data/lib/action_dispatch/http/response.rb +61 -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 +670 -635
- 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 +30 -13
@@ -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)
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "action_dispatch/journey/gtg/transition_table"
|
4
6
|
|
5
7
|
module ActionDispatch
|
@@ -66,9 +68,8 @@ module ActionDispatch
|
|
66
68
|
when Nodes::Group
|
67
69
|
true
|
68
70
|
when Nodes::Star
|
69
|
-
# the default star regex is /(.+)/ which is NOT nullable
|
70
|
-
#
|
71
|
-
# actually check if this is the case or not.
|
71
|
+
# the default star regex is /(.+)/ which is NOT nullable but since different
|
72
|
+
# constraints can be provided we must actually check if this is the case or not.
|
72
73
|
node.regexp.match?("")
|
73
74
|
when Nodes::Or
|
74
75
|
node.children.any? { |c| nullable?(c) }
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "action_dispatch/journey/nfa/dot"
|
4
6
|
|
5
7
|
module ActionDispatch
|
@@ -55,8 +57,8 @@ module ActionDispatch
|
|
55
57
|
|
56
58
|
t.each { |s, previous_start|
|
57
59
|
if previous_start.nil?
|
58
|
-
# In the simple case of a "default" param regex do this fast-path
|
59
|
-
#
|
60
|
+
# In the simple case of a "default" param regex do this fast-path and add all
|
61
|
+
# next states.
|
60
62
|
if token_matches_default_component && states = @stdparam_states[s]
|
61
63
|
states.each { |re, v| next_states << [v, nil].freeze if !v.nil? }
|
62
64
|
end
|
@@ -67,10 +69,10 @@ module ActionDispatch
|
|
67
69
|
end
|
68
70
|
end
|
69
71
|
|
70
|
-
# For regexes that aren't the "default" style, they may potentially
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
72
|
+
# For regexes that aren't the "default" style, they may potentially not be
|
73
|
+
# terminated by the first "token" [./?], so we need to continue to attempt to
|
74
|
+
# match this regexp as well as any successful paths that continue out of it.
|
75
|
+
# both paths could be valid.
|
74
76
|
if states = @regexp_states[s]
|
75
77
|
slice_start = if previous_start.nil?
|
76
78
|
start_index
|
@@ -86,8 +88,8 @@ module ActionDispatch
|
|
86
88
|
next_states << [v, nil].freeze if !v.nil? && re.match?(curr_slice)
|
87
89
|
}
|
88
90
|
|
89
|
-
# and regardless, we must continue accepting tokens and retrying this regexp.
|
90
|
-
#
|
91
|
+
# and regardless, we must continue accepting tokens and retrying this regexp. we
|
92
|
+
# need to remember where we started as well so we can take bigger slices.
|
91
93
|
next_states << [s, slice_start].freeze
|
92
94
|
end
|
93
95
|
}
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "action_dispatch/journey/visitors"
|
4
6
|
|
5
7
|
module ActionDispatch
|
@@ -21,9 +23,8 @@ module ActionDispatch
|
|
21
23
|
end
|
22
24
|
|
23
25
|
def requirements=(requirements)
|
24
|
-
# inject any regexp requirements for `star` nodes so they can be
|
25
|
-
#
|
26
|
-
# empty string.
|
26
|
+
# inject any regexp requirements for `star` nodes so they can be determined
|
27
|
+
# nullable, which requires knowing if the regex accepts an empty string.
|
27
28
|
(symbols + stars).each do |node|
|
28
29
|
re = requirements[node.to_sym]
|
29
30
|
node.regexp = re if re
|
@@ -51,8 +52,8 @@ module ActionDispatch
|
|
51
52
|
stars << node
|
52
53
|
|
53
54
|
if formatted != false
|
54
|
-
# Add a constraint for wildcard route to make it non-greedy and
|
55
|
-
#
|
55
|
+
# Add a constraint for wildcard route to make it non-greedy and match the
|
56
|
+
# optional format part of the route by default.
|
56
57
|
wildcard_options[node.name.to_sym] ||= /.+?/m
|
57
58
|
end
|
58
59
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionDispatch
|
4
6
|
module Journey # :nodoc:
|
5
7
|
module Path # :nodoc:
|
@@ -32,7 +34,8 @@ module ActionDispatch
|
|
32
34
|
end
|
33
35
|
|
34
36
|
def requirements_anchored?
|
35
|
-
# each required param must not be surrounded by a literal, otherwise it isn't
|
37
|
+
# each required param must not be surrounded by a literal, otherwise it isn't
|
38
|
+
# simple to chunk-match the url piecemeal
|
36
39
|
terminals = ast.terminals
|
37
40
|
|
38
41
|
terminals.each_with_index { |s, index|
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionDispatch
|
4
6
|
# :stopdoc:
|
5
7
|
module Journey
|
@@ -52,7 +54,7 @@ module ActionDispatch
|
|
52
54
|
|
53
55
|
##
|
54
56
|
# +path+ is a path constraint.
|
55
|
-
#
|
57
|
+
# `constraints` is a hash of constraints to be applied to this route.
|
56
58
|
def initialize(name:, app: nil, path:, constraints: {}, required_defaults: [], defaults: {}, request_method_match: nil, precedence: 0, scope_options: {}, internal: false, source_location: nil)
|
57
59
|
@name = name
|
58
60
|
@app = app
|
@@ -82,14 +84,14 @@ module ActionDispatch
|
|
82
84
|
nil
|
83
85
|
end
|
84
86
|
|
85
|
-
# Needed for `bin/rails routes`. Picks up succinctly defined requirements
|
86
|
-
#
|
87
|
+
# Needed for `bin/rails routes`. Picks up succinctly defined requirements for a
|
88
|
+
# route, for example route
|
87
89
|
#
|
88
|
-
#
|
89
|
-
#
|
90
|
+
# get 'photo/:id', :controller => 'photos', :action => 'show',
|
91
|
+
# :id => /[A-Z]\d{5}/
|
90
92
|
#
|
91
|
-
# will have {:controller=>"photos", :action=>"show", :id=>/
|
92
|
-
#
|
93
|
+
# will have {:controller=>"photos", :action=>"show", :[id=>/](A-Z){5}/} as
|
94
|
+
# requirements.
|
93
95
|
def requirements
|
94
96
|
@defaults.merge(path.requirements).delete_if { |_, v|
|
95
97
|
/.+?/m == v
|