actionpack 5.2.1 → 7.0.2.4
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 +264 -220
- data/MIT-LICENSE +1 -1
- data/README.rdoc +6 -6
- data/lib/abstract_controller/asset_paths.rb +1 -1
- data/lib/abstract_controller/base.rb +24 -4
- data/lib/abstract_controller/caching/fragments.rb +8 -24
- data/lib/abstract_controller/caching.rb +2 -2
- data/lib/abstract_controller/callbacks.rb +34 -8
- data/lib/abstract_controller/collector.rb +5 -4
- data/lib/abstract_controller/error.rb +1 -1
- data/lib/abstract_controller/helpers.rb +107 -90
- data/lib/abstract_controller/logger.rb +1 -1
- data/lib/abstract_controller/railties/routes_helpers.rb +19 -1
- data/lib/abstract_controller/rendering.rb +9 -9
- data/lib/abstract_controller/translation.rb +12 -5
- data/lib/abstract_controller/url_for.rb +4 -6
- data/lib/abstract_controller.rb +2 -0
- data/lib/action_controller/api.rb +5 -4
- data/lib/action_controller/base.rb +6 -9
- data/lib/action_controller/caching.rb +1 -3
- data/lib/action_controller/log_subscriber.rb +13 -9
- data/lib/action_controller/metal/basic_implicit_render.rb +1 -1
- data/lib/action_controller/metal/conditional_get.rb +57 -6
- data/lib/action_controller/metal/content_security_policy.rb +2 -3
- data/lib/action_controller/metal/cookies.rb +4 -2
- data/lib/action_controller/metal/data_streaming.rb +9 -18
- data/lib/action_controller/metal/default_headers.rb +17 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +4 -6
- data/lib/action_controller/metal/exceptions.rb +55 -12
- data/lib/action_controller/metal/flash.rb +10 -6
- data/lib/action_controller/metal/head.rb +7 -4
- data/lib/action_controller/metal/helpers.rb +15 -6
- data/lib/action_controller/metal/http_authentication.rb +41 -39
- data/lib/action_controller/metal/implicit_render.rb +5 -15
- data/lib/action_controller/metal/instrumentation.rb +59 -55
- data/lib/action_controller/metal/live.rb +80 -33
- data/lib/action_controller/metal/logging.rb +20 -0
- data/lib/action_controller/metal/mime_responds.rb +22 -7
- data/lib/action_controller/metal/parameter_encoding.rb +35 -4
- data/lib/action_controller/metal/params_wrapper.rb +50 -31
- data/lib/action_controller/metal/permissions_policy.rb +46 -0
- data/lib/action_controller/metal/redirecting.rb +93 -23
- data/lib/action_controller/metal/renderers.rb +4 -4
- data/lib/action_controller/metal/rendering.rb +14 -9
- data/lib/action_controller/metal/request_forgery_protection.rb +160 -58
- data/lib/action_controller/metal/rescue.rb +2 -2
- data/lib/action_controller/metal/streaming.rb +1 -4
- data/lib/action_controller/metal/strong_parameters.rb +236 -88
- data/lib/action_controller/metal/testing.rb +9 -2
- data/lib/action_controller/metal/url_for.rb +1 -1
- data/lib/action_controller/metal.rb +16 -17
- data/lib/action_controller/railtie.rb +49 -6
- data/lib/action_controller/railties/helpers.rb +1 -1
- data/lib/action_controller/renderer.rb +37 -13
- data/lib/action_controller/template_assertions.rb +1 -1
- data/lib/action_controller/test_case.rb +98 -68
- data/lib/action_controller.rb +4 -5
- data/lib/action_dispatch/http/cache.rb +45 -32
- data/lib/action_dispatch/http/content_disposition.rb +45 -0
- data/lib/action_dispatch/http/content_security_policy.rb +69 -56
- data/lib/action_dispatch/http/filter_parameters.rb +14 -8
- data/lib/action_dispatch/http/filter_redirect.rb +2 -3
- data/lib/action_dispatch/http/headers.rb +4 -4
- data/lib/action_dispatch/http/mime_negotiation.rb +44 -16
- data/lib/action_dispatch/http/mime_type.rb +47 -30
- data/lib/action_dispatch/http/parameters.rb +18 -27
- data/lib/action_dispatch/http/permissions_policy.rb +173 -0
- data/lib/action_dispatch/http/request.rb +49 -35
- data/lib/action_dispatch/http/response.rb +34 -26
- data/lib/action_dispatch/http/upload.rb +9 -1
- data/lib/action_dispatch/http/url.rb +86 -94
- data/lib/action_dispatch/journey/formatter.rb +55 -31
- data/lib/action_dispatch/journey/gtg/builder.rb +30 -46
- data/lib/action_dispatch/journey/gtg/simulator.rb +15 -8
- data/lib/action_dispatch/journey/gtg/transition_table.rb +78 -21
- data/lib/action_dispatch/journey/nfa/dot.rb +0 -11
- data/lib/action_dispatch/journey/nodes/node.rb +83 -16
- data/lib/action_dispatch/journey/parser.rb +13 -13
- data/lib/action_dispatch/journey/parser.y +1 -1
- data/lib/action_dispatch/journey/path/pattern.rb +42 -34
- data/lib/action_dispatch/journey/route.rb +14 -31
- data/lib/action_dispatch/journey/router/utils.rb +16 -14
- data/lib/action_dispatch/journey/router.rb +27 -35
- data/lib/action_dispatch/journey/routes.rb +3 -5
- data/lib/action_dispatch/journey/scanner.rb +10 -4
- data/lib/action_dispatch/journey/visitors.rb +1 -4
- data/lib/action_dispatch/journey/visualizer/fsm.js +49 -24
- data/lib/action_dispatch/journey/visualizer/index.html.erb +1 -1
- data/lib/action_dispatch/journey.rb +0 -2
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +45 -0
- data/lib/action_dispatch/middleware/callbacks.rb +2 -4
- data/lib/action_dispatch/middleware/cookies.rb +136 -113
- data/lib/action_dispatch/middleware/debug_exceptions.rb +47 -68
- data/lib/action_dispatch/middleware/debug_locks.rb +8 -8
- data/lib/action_dispatch/middleware/debug_view.rb +66 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +79 -30
- data/lib/action_dispatch/middleware/executor.rb +4 -1
- data/lib/action_dispatch/middleware/flash.rb +10 -12
- data/lib/action_dispatch/middleware/host_authorization.rb +159 -0
- data/lib/action_dispatch/middleware/public_exceptions.rb +6 -3
- data/lib/action_dispatch/middleware/remote_ip.rb +30 -20
- data/lib/action_dispatch/middleware/request_id.rb +5 -6
- data/lib/action_dispatch/middleware/server_timing.rb +33 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +16 -3
- data/lib/action_dispatch/middleware/session/cache_store.rb +11 -6
- data/lib/action_dispatch/middleware/session/cookie_store.rb +24 -19
- data/lib/action_dispatch/middleware/show_exceptions.rb +20 -11
- data/lib/action_dispatch/middleware/ssl.rb +20 -15
- data/lib/action_dispatch/middleware/stack.rb +79 -7
- data/lib/action_dispatch/middleware/static.rb +150 -94
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
- data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +6 -11
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +4 -2
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +46 -36
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +8 -0
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +7 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +25 -6
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +9 -6
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +4 -1
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +121 -15
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +5 -5
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +5 -5
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +16 -2
- data/lib/action_dispatch/railtie.rb +16 -4
- data/lib/action_dispatch/request/session.rb +59 -22
- data/lib/action_dispatch/request/utils.rb +28 -2
- data/lib/action_dispatch/routing/inspector.rb +102 -54
- data/lib/action_dispatch/routing/mapper.rb +184 -156
- data/lib/action_dispatch/routing/polymorphic_routes.rb +21 -19
- data/lib/action_dispatch/routing/redirection.rb +4 -6
- data/lib/action_dispatch/routing/route_set.rb +83 -73
- data/lib/action_dispatch/routing/routes_proxy.rb +1 -1
- data/lib/action_dispatch/routing/url_for.rb +2 -3
- data/lib/action_dispatch/routing.rb +23 -22
- data/lib/action_dispatch/system_test_case.rb +65 -16
- data/lib/action_dispatch/system_testing/browser.rb +43 -16
- data/lib/action_dispatch/system_testing/driver.rb +42 -10
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +58 -12
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +3 -10
- data/lib/action_dispatch/testing/assertion_response.rb +0 -1
- data/lib/action_dispatch/testing/assertions/response.rb +4 -7
- data/lib/action_dispatch/testing/assertions/routing.rb +20 -8
- data/lib/action_dispatch/testing/assertions.rb +3 -6
- data/lib/action_dispatch/testing/integration.rb +61 -30
- data/lib/action_dispatch/testing/request_encoder.rb +2 -2
- data/lib/action_dispatch/testing/test_process.rb +8 -6
- data/lib/action_dispatch/testing/test_request.rb +3 -3
- data/lib/action_dispatch/testing/test_response.rb +4 -32
- data/lib/action_dispatch.rb +15 -7
- data/lib/action_pack/gem_version.rb +4 -4
- data/lib/action_pack.rb +1 -1
- metadata +44 -25
- data/lib/action_controller/metal/force_ssl.rb +0 -99
- data/lib/action_dispatch/http/parameter_filter.rb +0 -86
- data/lib/action_dispatch/journey/nfa/builder.rb +0 -78
- data/lib/action_dispatch/journey/nfa/simulator.rb +0 -49
- data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -120
- data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +0 -26
@@ -120,8 +120,7 @@ module ActionDispatch
|
|
120
120
|
opts
|
121
121
|
end
|
122
122
|
|
123
|
-
# Returns the path component of a URL for the given record.
|
124
|
-
# <tt>polymorphic_url</tt> with <tt>routing_type: :path</tt>.
|
123
|
+
# Returns the path component of a URL for the given record.
|
125
124
|
def polymorphic_path(record_or_hash_or_array, options = {})
|
126
125
|
if Hash === record_or_hash_or_array
|
127
126
|
options = record_or_hash_or_array.merge(options)
|
@@ -146,6 +145,7 @@ module ActionDispatch
|
|
146
145
|
|
147
146
|
%w(edit new).each do |action|
|
148
147
|
module_eval <<-EOT, __FILE__, __LINE__ + 1
|
148
|
+
# frozen_string_literal: true
|
149
149
|
def #{action}_polymorphic_url(record_or_hash, options = {})
|
150
150
|
polymorphic_url_for_action("#{action}", record_or_hash, options)
|
151
151
|
end
|
@@ -157,7 +157,6 @@ module ActionDispatch
|
|
157
157
|
end
|
158
158
|
|
159
159
|
private
|
160
|
-
|
161
160
|
def polymorphic_url_for_action(action, record_or_hash, options)
|
162
161
|
polymorphic_url(record_or_hash, options.merge(action: action))
|
163
162
|
end
|
@@ -175,15 +174,15 @@ module ActionDispatch
|
|
175
174
|
end
|
176
175
|
|
177
176
|
class HelperMethodBuilder # :nodoc:
|
178
|
-
CACHE = {
|
177
|
+
CACHE = { path: {}, url: {} }
|
179
178
|
|
180
179
|
def self.get(action, type)
|
181
|
-
type = type.
|
180
|
+
type = type.to_sym
|
182
181
|
CACHE[type].fetch(action) { build action, type }
|
183
182
|
end
|
184
183
|
|
185
|
-
def self.url; CACHE[
|
186
|
-
def self.path; CACHE[
|
184
|
+
def self.url; CACHE[:url][nil]; end
|
185
|
+
def self.path; CACHE[:path][nil]; end
|
187
186
|
|
188
187
|
def self.build(action, type)
|
189
188
|
prefix = action ? "#{action}_" : ""
|
@@ -229,9 +228,9 @@ module ActionDispatch
|
|
229
228
|
end
|
230
229
|
|
231
230
|
if options.empty?
|
232
|
-
recipient.
|
231
|
+
recipient.public_send(method, *args)
|
233
232
|
else
|
234
|
-
recipient.
|
233
|
+
recipient.public_send(method, *args, options)
|
235
234
|
end
|
236
235
|
end
|
237
236
|
|
@@ -248,7 +247,7 @@ module ActionDispatch
|
|
248
247
|
end
|
249
248
|
|
250
249
|
def handle_string_call(target, str)
|
251
|
-
target.
|
250
|
+
target.public_send get_method_for_string str
|
252
251
|
end
|
253
252
|
|
254
253
|
def handle_class(klass)
|
@@ -256,7 +255,7 @@ module ActionDispatch
|
|
256
255
|
end
|
257
256
|
|
258
257
|
def handle_class_call(target, klass)
|
259
|
-
target.
|
258
|
+
target.public_send get_method_for_class klass
|
260
259
|
end
|
261
260
|
|
262
261
|
def handle_model(record)
|
@@ -278,7 +277,7 @@ module ActionDispatch
|
|
278
277
|
mapping.call(target, [record], suffix == "path")
|
279
278
|
else
|
280
279
|
method, args = handle_model(record)
|
281
|
-
target.
|
280
|
+
target.public_send(method, *args)
|
282
281
|
end
|
283
282
|
end
|
284
283
|
|
@@ -288,10 +287,12 @@ module ActionDispatch
|
|
288
287
|
|
289
288
|
args = []
|
290
289
|
|
291
|
-
route = record_list.map
|
290
|
+
route = record_list.map do |parent|
|
292
291
|
case parent
|
293
|
-
when Symbol
|
292
|
+
when Symbol
|
294
293
|
parent.to_s
|
294
|
+
when String
|
295
|
+
raise(ArgumentError, "Please use symbols for polymorphic route arguments.")
|
295
296
|
when Class
|
296
297
|
args << parent
|
297
298
|
parent.model_name.singular_route_key
|
@@ -299,12 +300,14 @@ module ActionDispatch
|
|
299
300
|
args << parent.to_model
|
300
301
|
parent.to_model.model_name.singular_route_key
|
301
302
|
end
|
302
|
-
|
303
|
+
end
|
303
304
|
|
304
305
|
route <<
|
305
306
|
case record
|
306
|
-
when Symbol
|
307
|
+
when Symbol
|
307
308
|
record.to_s
|
309
|
+
when String
|
310
|
+
raise(ArgumentError, "Please use symbols for polymorphic route arguments.")
|
308
311
|
when Class
|
309
312
|
@key_strategy.call record.model_name
|
310
313
|
else
|
@@ -324,7 +327,6 @@ module ActionDispatch
|
|
324
327
|
end
|
325
328
|
|
326
329
|
private
|
327
|
-
|
328
330
|
def polymorphic_mapping(target, record)
|
329
331
|
if record.respond_to?(:to_model)
|
330
332
|
target._routes.polymorphic_mappings[record.to_model.model_name.name]
|
@@ -343,8 +345,8 @@ module ActionDispatch
|
|
343
345
|
end
|
344
346
|
|
345
347
|
[nil, "new", "edit"].each do |action|
|
346
|
-
CACHE[
|
347
|
-
CACHE[
|
348
|
+
CACHE[:url][action] = build action, "url"
|
349
|
+
CACHE[:path][action] = build action, "path"
|
348
350
|
end
|
349
351
|
end
|
350
352
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "action_dispatch/http/request"
|
4
|
-
require "active_support/core_ext/uri"
|
5
3
|
require "active_support/core_ext/array/extract_options"
|
6
4
|
require "rack/utils"
|
7
5
|
require "action_controller/metal/exceptions"
|
@@ -65,15 +63,15 @@ module ActionDispatch
|
|
65
63
|
end
|
66
64
|
|
67
65
|
def escape(params)
|
68
|
-
|
66
|
+
params.transform_values { |v| Rack::Utils.escape(v) }
|
69
67
|
end
|
70
68
|
|
71
69
|
def escape_fragment(params)
|
72
|
-
|
70
|
+
params.transform_values { |v| Journey::Router::Utils.escape_fragment(v) }
|
73
71
|
end
|
74
72
|
|
75
73
|
def escape_path(params)
|
76
|
-
|
74
|
+
params.transform_values { |v| Journey::Router::Utils.escape_path(v) }
|
77
75
|
end
|
78
76
|
end
|
79
77
|
|
@@ -164,7 +162,7 @@ module ActionDispatch
|
|
164
162
|
# "http://#{request.host_with_port}/#{path}"
|
165
163
|
# }
|
166
164
|
#
|
167
|
-
# Note that the
|
165
|
+
# Note that the <tt>do end</tt> syntax for the redirect block wouldn't work, as Ruby would pass
|
168
166
|
# the block to +get+ instead of +redirect+. Use <tt>{ ... }</tt> instead.
|
169
167
|
#
|
170
168
|
# The options version of redirect allows you to supply only the parts of the URL which need
|
@@ -2,12 +2,10 @@
|
|
2
2
|
|
3
3
|
require "action_dispatch/journey"
|
4
4
|
require "active_support/core_ext/object/to_query"
|
5
|
-
require "active_support/core_ext/hash/slice"
|
6
5
|
require "active_support/core_ext/module/redefine_method"
|
7
6
|
require "active_support/core_ext/module/remove_method"
|
8
7
|
require "active_support/core_ext/array/extract_options"
|
9
8
|
require "action_controller/metal/exceptions"
|
10
|
-
require "action_dispatch/http/request"
|
11
9
|
require "action_dispatch/routing/endpoint"
|
12
10
|
|
13
11
|
module ActionDispatch
|
@@ -36,12 +34,11 @@ module ActionDispatch
|
|
36
34
|
if @raise_on_name_error
|
37
35
|
raise
|
38
36
|
else
|
39
|
-
|
37
|
+
[404, { "X-Cascade" => "pass" }, []]
|
40
38
|
end
|
41
39
|
end
|
42
40
|
|
43
41
|
private
|
44
|
-
|
45
42
|
def controller(req)
|
46
43
|
req.controller_class
|
47
44
|
rescue NameError => e
|
@@ -60,7 +57,6 @@ module ActionDispatch
|
|
60
57
|
end
|
61
58
|
|
62
59
|
private
|
63
|
-
|
64
60
|
def controller(_); @controller_class; end
|
65
61
|
end
|
66
62
|
|
@@ -91,11 +87,11 @@ module ActionDispatch
|
|
91
87
|
|
92
88
|
def clear!
|
93
89
|
@path_helpers.each do |helper|
|
94
|
-
@path_helpers_module.
|
90
|
+
@path_helpers_module.remove_method helper
|
95
91
|
end
|
96
92
|
|
97
93
|
@url_helpers.each do |helper|
|
98
|
-
@url_helpers_module.
|
94
|
+
@url_helpers_module.remove_method helper
|
99
95
|
end
|
100
96
|
|
101
97
|
@routes.clear
|
@@ -109,12 +105,14 @@ module ActionDispatch
|
|
109
105
|
url_name = :"#{name}_url"
|
110
106
|
|
111
107
|
if routes.key? key
|
112
|
-
@path_helpers_module.
|
113
|
-
@url_helpers_module.
|
108
|
+
@path_helpers_module.undef_method path_name
|
109
|
+
@url_helpers_module.undef_method url_name
|
114
110
|
end
|
115
111
|
routes[key] = route
|
116
|
-
|
117
|
-
|
112
|
+
|
113
|
+
helper = UrlHelper.create(route, route.defaults, name)
|
114
|
+
define_url_helper @path_helpers_module, path_name, helper, PATH
|
115
|
+
define_url_helper @url_helpers_module, url_name, helper, UNKNOWN
|
118
116
|
|
119
117
|
@path_helpers << path_name
|
120
118
|
@url_helpers << url_name
|
@@ -133,8 +131,8 @@ module ActionDispatch
|
|
133
131
|
alias [] get
|
134
132
|
alias clear clear!
|
135
133
|
|
136
|
-
def each
|
137
|
-
routes.each
|
134
|
+
def each(&block)
|
135
|
+
routes.each(&block)
|
138
136
|
self
|
139
137
|
end
|
140
138
|
|
@@ -154,13 +152,13 @@ module ActionDispatch
|
|
154
152
|
url_name = :"#{name}_url"
|
155
153
|
|
156
154
|
@path_helpers_module.module_eval do
|
157
|
-
|
155
|
+
redefine_method(path_name) do |*args|
|
158
156
|
helper.call(self, args, true)
|
159
157
|
end
|
160
158
|
end
|
161
159
|
|
162
160
|
@url_helpers_module.module_eval do
|
163
|
-
|
161
|
+
redefine_method(url_name) do |*args|
|
164
162
|
helper.call(self, args, false)
|
165
163
|
end
|
166
164
|
end
|
@@ -172,30 +170,30 @@ module ActionDispatch
|
|
172
170
|
end
|
173
171
|
|
174
172
|
class UrlHelper
|
175
|
-
def self.create(route, options, route_name
|
173
|
+
def self.create(route, options, route_name)
|
176
174
|
if optimize_helper?(route)
|
177
|
-
OptimizedUrlHelper.new(route, options, route_name
|
175
|
+
OptimizedUrlHelper.new(route, options, route_name)
|
178
176
|
else
|
179
|
-
new
|
177
|
+
new(route, options, route_name)
|
180
178
|
end
|
181
179
|
end
|
182
180
|
|
183
181
|
def self.optimize_helper?(route)
|
184
|
-
|
182
|
+
route.path.requirements.empty? && !route.glob?
|
185
183
|
end
|
186
184
|
|
187
|
-
attr_reader :
|
185
|
+
attr_reader :route_name
|
188
186
|
|
189
187
|
class OptimizedUrlHelper < UrlHelper
|
190
188
|
attr_reader :arg_size
|
191
189
|
|
192
|
-
def initialize(route, options, route_name
|
190
|
+
def initialize(route, options, route_name)
|
193
191
|
super
|
194
192
|
@required_parts = @route.required_parts
|
195
193
|
@arg_size = @required_parts.size
|
196
194
|
end
|
197
195
|
|
198
|
-
def call(t, args, inner_options)
|
196
|
+
def call(t, method_name, args, inner_options, url_strategy)
|
199
197
|
if args.size == arg_size && !inner_options && optimize_routes_generation?(t)
|
200
198
|
options = t.url_options.merge @options
|
201
199
|
options[:path] = optimized_helper(args)
|
@@ -216,7 +214,6 @@ module ActionDispatch
|
|
216
214
|
end
|
217
215
|
|
218
216
|
private
|
219
|
-
|
220
217
|
def optimized_helper(args)
|
221
218
|
params = parameterize_args(args) do
|
222
219
|
raise_generation_error(args)
|
@@ -246,22 +243,21 @@ module ActionDispatch
|
|
246
243
|
missing_keys << missing_key
|
247
244
|
}
|
248
245
|
constraints = Hash[@route.requirements.merge(params).sort_by { |k, v| k.to_s }]
|
249
|
-
message = "No route matches #{constraints.inspect}"
|
246
|
+
message = +"No route matches #{constraints.inspect}"
|
250
247
|
message << ", missing required keys: #{missing_keys.sort.inspect}"
|
251
248
|
|
252
249
|
raise ActionController::UrlGenerationError, message
|
253
250
|
end
|
254
251
|
end
|
255
252
|
|
256
|
-
def initialize(route, options, route_name
|
253
|
+
def initialize(route, options, route_name)
|
257
254
|
@options = options
|
258
255
|
@segment_keys = route.segment_keys.uniq
|
259
256
|
@route = route
|
260
|
-
@url_strategy = url_strategy
|
261
257
|
@route_name = route_name
|
262
258
|
end
|
263
259
|
|
264
|
-
def call(t, args, inner_options)
|
260
|
+
def call(t, method_name, args, inner_options, url_strategy)
|
265
261
|
controller_options = t.url_options
|
266
262
|
options = controller_options.merge @options
|
267
263
|
hash = handle_positional_args(controller_options,
|
@@ -270,7 +266,7 @@ module ActionDispatch
|
|
270
266
|
options,
|
271
267
|
@segment_keys)
|
272
268
|
|
273
|
-
t._routes.url_for(hash, route_name, url_strategy)
|
269
|
+
t._routes.url_for(hash, route_name, url_strategy, method_name)
|
274
270
|
end
|
275
271
|
|
276
272
|
def handle_positional_args(controller_options, inner_options, args, result, path_params)
|
@@ -316,31 +312,28 @@ module ActionDispatch
|
|
316
312
|
#
|
317
313
|
# foo_url(bar, baz, bang, sort_by: 'baz')
|
318
314
|
#
|
319
|
-
def define_url_helper(mod,
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
end
|
331
|
-
helper.call self, args, options
|
332
|
-
end
|
315
|
+
def define_url_helper(mod, name, helper, url_strategy)
|
316
|
+
mod.define_method(name) do |*args|
|
317
|
+
last = args.last
|
318
|
+
options = \
|
319
|
+
case last
|
320
|
+
when Hash
|
321
|
+
args.pop
|
322
|
+
when ActionController::Parameters
|
323
|
+
args.pop.to_h
|
324
|
+
end
|
325
|
+
helper.call(self, name, args, options, url_strategy)
|
333
326
|
end
|
334
327
|
end
|
335
328
|
end
|
336
329
|
|
337
|
-
# strategy for building
|
330
|
+
# strategy for building URLs to send to the client
|
338
331
|
PATH = ->(options) { ActionDispatch::Http::URL.path_for(options) }
|
339
332
|
UNKNOWN = ->(options) { ActionDispatch::Http::URL.url_for(options) }
|
340
333
|
|
341
334
|
attr_accessor :formatter, :set, :named_routes, :default_scope, :router
|
342
335
|
attr_accessor :disable_clear_and_finalize, :resources_path_names
|
343
|
-
attr_accessor :default_url_options
|
336
|
+
attr_accessor :default_url_options, :draw_paths
|
344
337
|
attr_reader :env_key, :polymorphic_mappings
|
345
338
|
|
346
339
|
alias :routes :set
|
@@ -372,13 +365,14 @@ module ActionDispatch
|
|
372
365
|
self.named_routes = NamedRouteCollection.new
|
373
366
|
self.resources_path_names = self.class.default_resources_path_names
|
374
367
|
self.default_url_options = {}
|
368
|
+
self.draw_paths = []
|
375
369
|
|
376
370
|
@config = config
|
377
371
|
@append = []
|
378
372
|
@prepend = []
|
379
373
|
@disable_clear_and_finalize = false
|
380
374
|
@finalized = false
|
381
|
-
@env_key = "ROUTES_#{object_id}_SCRIPT_NAME"
|
375
|
+
@env_key = "ROUTES_#{object_id}_SCRIPT_NAME"
|
382
376
|
|
383
377
|
@set = Journey::Routes.new
|
384
378
|
@router = Journey::Router.new @set
|
@@ -482,6 +476,14 @@ module ActionDispatch
|
|
482
476
|
end
|
483
477
|
|
484
478
|
def url_helpers(supports_path = true)
|
479
|
+
if supports_path
|
480
|
+
@url_helpers_with_paths ||= generate_url_helpers(true)
|
481
|
+
else
|
482
|
+
@url_helpers_without_paths ||= generate_url_helpers(false)
|
483
|
+
end
|
484
|
+
end
|
485
|
+
|
486
|
+
def generate_url_helpers(supports_path)
|
485
487
|
routes = self
|
486
488
|
|
487
489
|
Module.new do
|
@@ -585,7 +587,7 @@ module ActionDispatch
|
|
585
587
|
"You may have defined two routes with the same name using the `:as` option, or " \
|
586
588
|
"you may be overriding a route already defined by a resource with the same naming. " \
|
587
589
|
"For the latter, you can restrict the routes created with `resources` as explained here: \n" \
|
588
|
-
"
|
590
|
+
"https://guides.rubyonrails.org/routing.html#restricting-the-routes-created"
|
589
591
|
end
|
590
592
|
|
591
593
|
route = @set.add_route(name, mapping)
|
@@ -594,14 +596,14 @@ module ActionDispatch
|
|
594
596
|
if route.segment_keys.include?(:controller)
|
595
597
|
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
596
598
|
Using a dynamic :controller segment in a route is deprecated and
|
597
|
-
will be removed in Rails
|
599
|
+
will be removed in Rails 7.1.
|
598
600
|
MSG
|
599
601
|
end
|
600
602
|
|
601
603
|
if route.segment_keys.include?(:action)
|
602
604
|
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
603
605
|
Using a dynamic :action segment in a route is deprecated and
|
604
|
-
will be removed in Rails
|
606
|
+
will be removed in Rails 7.1.
|
605
607
|
MSG
|
606
608
|
end
|
607
609
|
|
@@ -647,14 +649,6 @@ module ActionDispatch
|
|
647
649
|
end
|
648
650
|
|
649
651
|
class Generator
|
650
|
-
PARAMETERIZE = lambda do |name, value|
|
651
|
-
if name == :controller
|
652
|
-
value
|
653
|
-
else
|
654
|
-
value.to_param
|
655
|
-
end
|
656
|
-
end
|
657
|
-
|
658
652
|
attr_reader :options, :recall, :set, :named_route
|
659
653
|
|
660
654
|
def initialize(named_route, options, recall, set)
|
@@ -730,7 +724,7 @@ module ActionDispatch
|
|
730
724
|
# Remove leading slashes from controllers
|
731
725
|
def normalize_controller!
|
732
726
|
if controller
|
733
|
-
if controller.start_with?("/"
|
727
|
+
if controller.start_with?("/")
|
734
728
|
@options[:controller] = controller[1..-1]
|
735
729
|
else
|
736
730
|
@options[:controller] = controller
|
@@ -738,10 +732,10 @@ module ActionDispatch
|
|
738
732
|
end
|
739
733
|
end
|
740
734
|
|
741
|
-
# Generates a path from routes, returns
|
742
|
-
#
|
735
|
+
# Generates a path from routes, returns a RouteWithParams or MissingRoute.
|
736
|
+
# MissingRoute will raise ActionController::UrlGenerationError.
|
743
737
|
def generate
|
744
|
-
@set.formatter.generate(named_route, options, recall
|
738
|
+
@set.formatter.generate(named_route, options, recall)
|
745
739
|
end
|
746
740
|
|
747
741
|
def different_controller?
|
@@ -766,13 +760,18 @@ module ActionDispatch
|
|
766
760
|
end
|
767
761
|
|
768
762
|
def generate_extras(options, recall = {})
|
769
|
-
|
770
|
-
|
771
|
-
|
763
|
+
if recall
|
764
|
+
options = options.merge(_recall: recall)
|
765
|
+
end
|
766
|
+
|
767
|
+
route_name = options.delete :use_route
|
768
|
+
generator = generate(route_name, options, recall)
|
769
|
+
path_info = path_for(options, route_name, [])
|
770
|
+
[URI(path_info).path, generator.params.except(:_recall).keys]
|
772
771
|
end
|
773
772
|
|
774
|
-
def generate(
|
775
|
-
Generator.new(
|
773
|
+
def generate(route_name, options, recall = {}, method_name = nil)
|
774
|
+
Generator.new(route_name, options, recall, self).generate
|
776
775
|
end
|
777
776
|
private :generate
|
778
777
|
|
@@ -792,12 +791,12 @@ module ActionDispatch
|
|
792
791
|
options.delete(:relative_url_root) || relative_url_root
|
793
792
|
end
|
794
793
|
|
795
|
-
def path_for(options, route_name = nil)
|
796
|
-
url_for(options, route_name, PATH)
|
794
|
+
def path_for(options, route_name = nil, reserved = RESERVED_OPTIONS)
|
795
|
+
url_for(options, route_name, PATH, nil, reserved)
|
797
796
|
end
|
798
797
|
|
799
798
|
# The +options+ argument must be a hash whose keys are *symbols*.
|
800
|
-
def url_for(options, route_name = nil, url_strategy = UNKNOWN)
|
799
|
+
def url_for(options, route_name = nil, url_strategy = UNKNOWN, method_name = nil, reserved = RESERVED_OPTIONS)
|
801
800
|
options = default_url_options.merge options
|
802
801
|
|
803
802
|
user = password = nil
|
@@ -817,12 +816,23 @@ module ActionDispatch
|
|
817
816
|
end
|
818
817
|
|
819
818
|
path_options = options.dup
|
820
|
-
|
819
|
+
reserved.each { |ro| path_options.delete ro }
|
821
820
|
|
822
|
-
|
821
|
+
route_with_params = generate(route_name, path_options, recall)
|
822
|
+
path = route_with_params.path(method_name)
|
823
|
+
|
824
|
+
if options[:trailing_slash] && !options[:format] && !path.end_with?("/")
|
825
|
+
path += "/"
|
826
|
+
end
|
827
|
+
|
828
|
+
params = route_with_params.params
|
823
829
|
|
824
830
|
if options.key? :params
|
825
|
-
|
831
|
+
if options[:params]&.respond_to?(:to_hash)
|
832
|
+
params.merge! options[:params]
|
833
|
+
else
|
834
|
+
params[:params] = options[:params]
|
835
|
+
end
|
826
836
|
end
|
827
837
|
|
828
838
|
options[:path] = path
|
@@ -842,7 +852,7 @@ module ActionDispatch
|
|
842
852
|
|
843
853
|
def recognize_path(path, environment = {})
|
844
854
|
method = (environment[:method] || "GET").to_s.upcase
|
845
|
-
path = Journey::Router::Utils.normalize_path(path) unless
|
855
|
+
path = Journey::Router::Utils.normalize_path(path) unless %r{://}.match?(path)
|
846
856
|
extras = environment[:extras] || {}
|
847
857
|
|
848
858
|
begin
|
@@ -861,7 +871,7 @@ module ActionDispatch
|
|
861
871
|
params.each do |key, value|
|
862
872
|
if value.is_a?(String)
|
863
873
|
value = value.dup.force_encoding(Encoding::BINARY)
|
864
|
-
params[key] = URI.
|
874
|
+
params[key] = URI::DEFAULT_PARSER.unescape(value)
|
865
875
|
end
|
866
876
|
end
|
867
877
|
req.path_parameters = params
|
@@ -103,7 +103,7 @@ module ActionDispatch
|
|
103
103
|
include(*_url_for_modules) if respond_to?(:_url_for_modules)
|
104
104
|
end
|
105
105
|
|
106
|
-
def initialize(
|
106
|
+
def initialize(...)
|
107
107
|
@_routes = nil
|
108
108
|
super
|
109
109
|
end
|
@@ -133,6 +133,7 @@ module ActionDispatch
|
|
133
133
|
# <tt>ActionDispatch::Http::URL.tld_length</tt>, which in turn defaults to 1.
|
134
134
|
# * <tt>:port</tt> - Optionally specify the port to connect to.
|
135
135
|
# * <tt>:anchor</tt> - An anchor name to be appended to the path.
|
136
|
+
# * <tt>:params</tt> - The query parameters to be appended to the path.
|
136
137
|
# * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in "/archive/2009/"
|
137
138
|
# * <tt>:script_name</tt> - Specifies application path relative to domain root. If provided, prepends application path.
|
138
139
|
#
|
@@ -214,13 +215,11 @@ module ActionDispatch
|
|
214
215
|
end
|
215
216
|
|
216
217
|
protected
|
217
|
-
|
218
218
|
def optimize_routes_generation?
|
219
219
|
_routes.optimize_routes_generation? && default_url_options.empty?
|
220
220
|
end
|
221
221
|
|
222
222
|
private
|
223
|
-
|
224
223
|
def _with_routes(routes) # :doc:
|
225
224
|
old_routes, @_routes = @_routes, routes
|
226
225
|
yield
|