actionpack 7.0.4 → 7.1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +495 -257
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -4
- data/lib/abstract_controller/base.rb +20 -11
- data/lib/abstract_controller/caching/fragments.rb +2 -0
- data/lib/abstract_controller/callbacks.rb +31 -6
- data/lib/abstract_controller/deprecator.rb +7 -0
- data/lib/abstract_controller/helpers.rb +75 -28
- data/lib/abstract_controller/railties/routes_helpers.rb +1 -16
- data/lib/abstract_controller/rendering.rb +12 -14
- data/lib/abstract_controller/translation.rb +11 -6
- data/lib/abstract_controller/url_for.rb +2 -0
- data/lib/abstract_controller.rb +6 -0
- data/lib/action_controller/api.rb +6 -4
- data/lib/action_controller/base.rb +3 -17
- data/lib/action_controller/caching.rb +2 -0
- data/lib/action_controller/deprecator.rb +7 -0
- data/lib/action_controller/form_builder.rb +2 -0
- data/lib/action_controller/log_subscriber.rb +16 -4
- data/lib/action_controller/metal/basic_implicit_render.rb +3 -1
- data/lib/action_controller/metal/conditional_get.rb +121 -123
- data/lib/action_controller/metal/content_security_policy.rb +5 -5
- data/lib/action_controller/metal/data_streaming.rb +20 -18
- data/lib/action_controller/metal/default_headers.rb +2 -0
- data/lib/action_controller/metal/etag_with_flash.rb +3 -1
- data/lib/action_controller/metal/etag_with_template_digest.rb +2 -0
- data/lib/action_controller/metal/exceptions.rb +8 -0
- data/lib/action_controller/metal/head.rb +9 -7
- data/lib/action_controller/metal/helpers.rb +3 -14
- data/lib/action_controller/metal/http_authentication.rb +15 -9
- data/lib/action_controller/metal/implicit_render.rb +5 -3
- data/lib/action_controller/metal/instrumentation.rb +8 -1
- data/lib/action_controller/metal/live.rb +25 -1
- data/lib/action_controller/metal/mime_responds.rb +2 -2
- data/lib/action_controller/metal/params_wrapper.rb +4 -2
- data/lib/action_controller/metal/permissions_policy.rb +2 -2
- data/lib/action_controller/metal/redirecting.rb +29 -8
- data/lib/action_controller/metal/renderers.rb +4 -4
- data/lib/action_controller/metal/rendering.rb +114 -9
- data/lib/action_controller/metal/request_forgery_protection.rb +144 -53
- data/lib/action_controller/metal/rescue.rb +6 -3
- data/lib/action_controller/metal/streaming.rb +71 -31
- data/lib/action_controller/metal/strong_parameters.rb +200 -103
- data/lib/action_controller/metal/url_for.rb +9 -4
- data/lib/action_controller/metal.rb +79 -21
- data/lib/action_controller/railtie.rb +24 -10
- data/lib/action_controller/renderer.rb +99 -85
- data/lib/action_controller/test_case.rb +18 -8
- data/lib/action_controller.rb +13 -3
- data/lib/action_dispatch/constants.rb +32 -0
- data/lib/action_dispatch/deprecator.rb +7 -0
- data/lib/action_dispatch/http/cache.rb +9 -11
- data/lib/action_dispatch/http/content_security_policy.rb +35 -13
- data/lib/action_dispatch/http/filter_parameters.rb +23 -32
- data/lib/action_dispatch/http/headers.rb +3 -1
- data/lib/action_dispatch/http/mime_negotiation.rb +22 -22
- data/lib/action_dispatch/http/mime_type.rb +37 -11
- data/lib/action_dispatch/http/mime_types.rb +3 -1
- data/lib/action_dispatch/http/parameters.rb +1 -1
- data/lib/action_dispatch/http/permissions_policy.rb +38 -23
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +85 -32
- data/lib/action_dispatch/http/response.rb +80 -63
- data/lib/action_dispatch/http/upload.rb +15 -2
- data/lib/action_dispatch/journey/formatter.rb +8 -2
- data/lib/action_dispatch/journey/path/pattern.rb +14 -14
- data/lib/action_dispatch/journey/route.rb +3 -2
- data/lib/action_dispatch/journey/router.rb +9 -8
- data/lib/action_dispatch/journey/routes.rb +2 -2
- data/lib/action_dispatch/log_subscriber.rb +23 -0
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +5 -6
- data/lib/action_dispatch/middleware/assume_ssl.rb +24 -0
- data/lib/action_dispatch/middleware/callbacks.rb +2 -0
- data/lib/action_dispatch/middleware/cookies.rb +108 -117
- data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -25
- data/lib/action_dispatch/middleware/debug_locks.rb +4 -1
- data/lib/action_dispatch/middleware/debug_view.rb +7 -2
- data/lib/action_dispatch/middleware/exception_wrapper.rb +186 -27
- data/lib/action_dispatch/middleware/executor.rb +7 -1
- data/lib/action_dispatch/middleware/flash.rb +7 -0
- data/lib/action_dispatch/middleware/host_authorization.rb +18 -8
- data/lib/action_dispatch/middleware/public_exceptions.rb +5 -3
- data/lib/action_dispatch/middleware/reloader.rb +7 -5
- data/lib/action_dispatch/middleware/remote_ip.rb +21 -20
- data/lib/action_dispatch/middleware/request_id.rb +4 -2
- data/lib/action_dispatch/middleware/server_timing.rb +4 -4
- data/lib/action_dispatch/middleware/session/abstract_store.rb +5 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +2 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +11 -5
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +3 -1
- data/lib/action_dispatch/middleware/show_exceptions.rb +39 -22
- data/lib/action_dispatch/middleware/ssl.rb +18 -6
- data/lib/action_dispatch/middleware/stack.rb +7 -2
- data/lib/action_dispatch/middleware/static.rb +14 -10
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +8 -1
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -3
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -3
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +7 -7
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +17 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +16 -12
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +3 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +59 -41
- data/lib/action_dispatch/railtie.rb +13 -4
- data/lib/action_dispatch/request/session.rb +16 -6
- data/lib/action_dispatch/request/utils.rb +8 -3
- data/lib/action_dispatch/routing/inspector.rb +54 -6
- data/lib/action_dispatch/routing/mapper.rb +97 -26
- data/lib/action_dispatch/routing/polymorphic_routes.rb +2 -0
- data/lib/action_dispatch/routing/redirection.rb +15 -6
- data/lib/action_dispatch/routing/route_set.rb +53 -23
- data/lib/action_dispatch/routing/routes_proxy.rb +10 -15
- data/lib/action_dispatch/routing/url_for.rb +26 -22
- data/lib/action_dispatch/routing.rb +7 -7
- data/lib/action_dispatch/system_test_case.rb +3 -3
- data/lib/action_dispatch/system_testing/browser.rb +25 -19
- data/lib/action_dispatch/system_testing/driver.rb +15 -23
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +27 -16
- data/lib/action_dispatch/testing/assertion_response.rb +1 -1
- data/lib/action_dispatch/testing/assertions/response.rb +14 -7
- data/lib/action_dispatch/testing/assertions/routing.rb +67 -28
- data/lib/action_dispatch/testing/assertions.rb +3 -1
- data/lib/action_dispatch/testing/integration.rb +27 -17
- data/lib/action_dispatch/testing/request_encoder.rb +4 -1
- data/lib/action_dispatch/testing/test_process.rb +4 -3
- data/lib/action_dispatch/testing/test_request.rb +1 -1
- data/lib/action_dispatch/testing/test_response.rb +23 -9
- data/lib/action_dispatch.rb +41 -4
- data/lib/action_pack/gem_version.rb +4 -4
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_pack.rb +1 -1
- metadata +68 -32
@@ -10,8 +10,20 @@ require "action_dispatch/routing/endpoint"
|
|
10
10
|
module ActionDispatch
|
11
11
|
module Routing
|
12
12
|
class Mapper
|
13
|
+
class BacktraceCleaner < ActiveSupport::BacktraceCleaner # :nodoc:
|
14
|
+
def initialize
|
15
|
+
super
|
16
|
+
remove_silencers!
|
17
|
+
add_core_silencer
|
18
|
+
add_stdlib_silencer
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
13
22
|
URL_OPTIONS = [:protocol, :subdomain, :domain, :host, :port]
|
14
23
|
|
24
|
+
cattr_accessor :route_source_locations, instance_accessor: false, default: false
|
25
|
+
cattr_accessor :backtrace_cleaner, instance_accessor: false, default: BacktraceCleaner.new
|
26
|
+
|
15
27
|
class Constraints < Routing::Endpoint # :nodoc:
|
16
28
|
attr_reader :app, :constraints
|
17
29
|
|
@@ -43,7 +55,7 @@ module ActionDispatch
|
|
43
55
|
end
|
44
56
|
|
45
57
|
def serve(req)
|
46
|
-
return [ 404, {
|
58
|
+
return [ 404, { Constants::X_CASCADE => "pass" }, [] ] unless matches?(req)
|
47
59
|
|
48
60
|
@strategy.call @app, req
|
49
61
|
end
|
@@ -170,7 +182,7 @@ module ActionDispatch
|
|
170
182
|
Journey::Route.new(name: name, app: application, path: path, constraints: conditions,
|
171
183
|
required_defaults: required_defaults, defaults: defaults,
|
172
184
|
request_method_match: request_method, precedence: precedence,
|
173
|
-
scope_options: scope_options, internal: @internal)
|
185
|
+
scope_options: scope_options, internal: @internal, source_location: route_source_location)
|
174
186
|
end
|
175
187
|
|
176
188
|
def application
|
@@ -214,9 +226,21 @@ module ActionDispatch
|
|
214
226
|
if to.respond_to?(:action) || to.respond_to?(:call)
|
215
227
|
options
|
216
228
|
else
|
217
|
-
|
218
|
-
|
219
|
-
|
229
|
+
if to.nil?
|
230
|
+
controller = default_controller
|
231
|
+
action = default_action
|
232
|
+
elsif to.is_a?(String)
|
233
|
+
if to.include?("#")
|
234
|
+
to_endpoint = to.split("#").map!(&:-@)
|
235
|
+
controller = to_endpoint[0]
|
236
|
+
action = to_endpoint[1]
|
237
|
+
else
|
238
|
+
controller = default_controller
|
239
|
+
action = to
|
240
|
+
end
|
241
|
+
else
|
242
|
+
raise ArgumentError, ":to must respond to `action` or `call`, or it must be a String that includes '#', or the controller should be implicit"
|
243
|
+
end
|
220
244
|
|
221
245
|
controller = add_controller_module(controller, modyoule)
|
222
246
|
|
@@ -305,14 +329,6 @@ module ActionDispatch
|
|
305
329
|
hash
|
306
330
|
end
|
307
331
|
|
308
|
-
def split_to(to)
|
309
|
-
if /#/.match?(to)
|
310
|
-
to.split("#").map!(&:-@)
|
311
|
-
else
|
312
|
-
[]
|
313
|
-
end
|
314
|
-
end
|
315
|
-
|
316
332
|
def add_controller_module(controller, modyoule)
|
317
333
|
if modyoule && !controller.is_a?(Regexp)
|
318
334
|
if controller&.start_with?("/")
|
@@ -356,6 +372,38 @@ module ActionDispatch
|
|
356
372
|
def dispatcher(raise_on_name_error)
|
357
373
|
Routing::RouteSet::Dispatcher.new raise_on_name_error
|
358
374
|
end
|
375
|
+
|
376
|
+
if Thread.respond_to?(:each_caller_location)
|
377
|
+
def route_source_location
|
378
|
+
if Mapper.route_source_locations
|
379
|
+
action_dispatch_dir = File.expand_path("..", __dir__)
|
380
|
+
Thread.each_caller_location do |location|
|
381
|
+
next if location.path.start_with?(action_dispatch_dir)
|
382
|
+
|
383
|
+
cleaned_path = Mapper.backtrace_cleaner.clean_frame(location.path)
|
384
|
+
next if cleaned_path.nil?
|
385
|
+
|
386
|
+
return "#{cleaned_path}:#{location.lineno}"
|
387
|
+
end
|
388
|
+
nil
|
389
|
+
end
|
390
|
+
end
|
391
|
+
else
|
392
|
+
def route_source_location
|
393
|
+
if Mapper.route_source_locations
|
394
|
+
action_dispatch_dir = File.expand_path("..", __dir__)
|
395
|
+
caller_locations.each do |location|
|
396
|
+
next if location.path.start_with?(action_dispatch_dir)
|
397
|
+
|
398
|
+
cleaned_path = Mapper.backtrace_cleaner.clean_frame(location.path)
|
399
|
+
next if cleaned_path.nil?
|
400
|
+
|
401
|
+
return "#{cleaned_path}:#{location.lineno}"
|
402
|
+
end
|
403
|
+
nil
|
404
|
+
end
|
405
|
+
end
|
406
|
+
end
|
359
407
|
end
|
360
408
|
|
361
409
|
# Invokes Journey::Router::Utils.normalize_path, then ensures that
|
@@ -652,7 +700,7 @@ module ActionDispatch
|
|
652
700
|
|
653
701
|
script_namer = ->(options) do
|
654
702
|
prefix_options = options.slice(*_route.segment_keys)
|
655
|
-
prefix_options[:
|
703
|
+
prefix_options[:script_name] = "" if options[:original_script_name]
|
656
704
|
|
657
705
|
if options[:_recall]
|
658
706
|
prefix_options.reverse_merge!(options[:_recall].slice(*_route.segment_keys))
|
@@ -669,7 +717,7 @@ module ActionDispatch
|
|
669
717
|
def optimize_routes_generation?; false; end
|
670
718
|
|
671
719
|
define_method :find_script_name do |options|
|
672
|
-
if options.key? :script_name
|
720
|
+
if options.key?(:script_name) && options[:script_name].present?
|
673
721
|
super(options)
|
674
722
|
else
|
675
723
|
script_namer.call(options)
|
@@ -748,7 +796,7 @@ module ActionDispatch
|
|
748
796
|
# end
|
749
797
|
#
|
750
798
|
# This will create a number of routes for each of the posts and comments
|
751
|
-
# controller. For
|
799
|
+
# controller. For +Admin::PostsController+, \Rails will create:
|
752
800
|
#
|
753
801
|
# GET /admin/posts
|
754
802
|
# GET /admin/posts/new
|
@@ -759,7 +807,7 @@ module ActionDispatch
|
|
759
807
|
# DELETE /admin/posts/1
|
760
808
|
#
|
761
809
|
# If you want to route /posts (without the prefix /admin) to
|
762
|
-
#
|
810
|
+
# +Admin::PostsController+, you could use
|
763
811
|
#
|
764
812
|
# scope module: "admin" do
|
765
813
|
# resources :posts
|
@@ -808,7 +856,7 @@ module ActionDispatch
|
|
808
856
|
#
|
809
857
|
# Takes same options as <tt>Base#match</tt> and <tt>Resources#resources</tt>.
|
810
858
|
#
|
811
|
-
# # route /posts (without the prefix /admin) to
|
859
|
+
# # route /posts (without the prefix /admin) to +Admin::PostsController+
|
812
860
|
# scope module: "admin" do
|
813
861
|
# resources :posts
|
814
862
|
# end
|
@@ -917,7 +965,7 @@ module ActionDispatch
|
|
917
965
|
# resources :posts
|
918
966
|
# end
|
919
967
|
#
|
920
|
-
# # maps to
|
968
|
+
# # maps to +Sekret::PostsController+ rather than +Admin::PostsController+
|
921
969
|
# namespace :admin, module: "sekret" do
|
922
970
|
# resources :posts
|
923
971
|
# end
|
@@ -1318,7 +1366,7 @@ module ActionDispatch
|
|
1318
1366
|
self
|
1319
1367
|
end
|
1320
1368
|
|
1321
|
-
# In Rails, a resourceful route provides a mapping between HTTP verbs
|
1369
|
+
# In \Rails, a resourceful route provides a mapping between HTTP verbs
|
1322
1370
|
# and URLs and controller actions. By convention, each action also maps
|
1323
1371
|
# to particular CRUD operations in a database. A single entry in the
|
1324
1372
|
# routing file, such as
|
@@ -1450,7 +1498,7 @@ module ActionDispatch
|
|
1450
1498
|
#
|
1451
1499
|
# === Examples
|
1452
1500
|
#
|
1453
|
-
# # routes call
|
1501
|
+
# # routes call +Admin::PostsController+
|
1454
1502
|
# resources :posts, module: "admin"
|
1455
1503
|
#
|
1456
1504
|
# # resource actions are at /admin/posts.
|
@@ -1493,7 +1541,7 @@ module ActionDispatch
|
|
1493
1541
|
# end
|
1494
1542
|
# end
|
1495
1543
|
#
|
1496
|
-
# This will enable Rails to recognize paths such as <tt>/photos/search</tt>
|
1544
|
+
# This will enable \Rails to recognize paths such as <tt>/photos/search</tt>
|
1497
1545
|
# with GET, and route to the search action of +PhotosController+. It will also
|
1498
1546
|
# create the <tt>search_photos_url</tt> and <tt>search_photos_path</tt>
|
1499
1547
|
# route helpers.
|
@@ -1584,6 +1632,29 @@ module ActionDispatch
|
|
1584
1632
|
!parent_resource.singleton? && @scope[:shallow]
|
1585
1633
|
end
|
1586
1634
|
|
1635
|
+
# Loads another routes file with the given +name+ located inside the
|
1636
|
+
# +config/routes+ directory. In that file, you can use the normal
|
1637
|
+
# routing DSL, but <i>do not</i> surround it with a
|
1638
|
+
# +Rails.application.routes.draw+ block.
|
1639
|
+
#
|
1640
|
+
# # config/routes.rb
|
1641
|
+
# Rails.application.routes.draw do
|
1642
|
+
# draw :admin # Loads `config/routes/admin.rb`
|
1643
|
+
# draw "third_party/some_gem" # Loads `config/routes/third_party/some_gem.rb`
|
1644
|
+
# end
|
1645
|
+
#
|
1646
|
+
# # config/routes/admin.rb
|
1647
|
+
# namespace :admin do
|
1648
|
+
# resources :accounts
|
1649
|
+
# end
|
1650
|
+
#
|
1651
|
+
# # config/routes/third_party/some_gem.rb
|
1652
|
+
# mount SomeGem::Engine, at: "/some_gem"
|
1653
|
+
#
|
1654
|
+
# <b>CAUTION:</b> Use this feature with care. Having multiple routes
|
1655
|
+
# files can negatively impact discoverability and readability. For most
|
1656
|
+
# applications — even those with a few hundred routes — it's easier for
|
1657
|
+
# developers to have a single routes file.
|
1587
1658
|
def draw(name)
|
1588
1659
|
path = @draw_paths.find do |_path|
|
1589
1660
|
File.exist? "#{_path}/#{name}.rb"
|
@@ -1617,7 +1688,7 @@ module ActionDispatch
|
|
1617
1688
|
when Symbol
|
1618
1689
|
options[:action] = to
|
1619
1690
|
when String
|
1620
|
-
if
|
1691
|
+
if to.include?("#")
|
1621
1692
|
options[:to] = to
|
1622
1693
|
else
|
1623
1694
|
options[:controller] = to
|
@@ -1640,7 +1711,7 @@ module ActionDispatch
|
|
1640
1711
|
end
|
1641
1712
|
end
|
1642
1713
|
|
1643
|
-
# You can specify what Rails should route "/" to with the root method:
|
1714
|
+
# You can specify what \Rails should route "/" to with the root method:
|
1644
1715
|
#
|
1645
1716
|
# root to: 'pages#main'
|
1646
1717
|
#
|
@@ -1652,7 +1723,7 @@ module ActionDispatch
|
|
1652
1723
|
#
|
1653
1724
|
# You should put the root route at the top of <tt>config/routes.rb</tt>,
|
1654
1725
|
# because this means it will be matched first. As this is the most popular route
|
1655
|
-
# of most Rails applications, this is beneficial.
|
1726
|
+
# of most \Rails applications, this is beneficial.
|
1656
1727
|
def root(path, options = {})
|
1657
1728
|
if path.is_a?(String)
|
1658
1729
|
options[:to] = path
|
@@ -1955,7 +2026,7 @@ module ActionDispatch
|
|
1955
2026
|
name_for_action(options.delete(:as), action)
|
1956
2027
|
end
|
1957
2028
|
|
1958
|
-
path = Mapping.normalize_path
|
2029
|
+
path = Mapping.normalize_path RFC2396_PARSER.escape(path), formatted
|
1959
2030
|
ast = Journey::Parser.parse path
|
1960
2031
|
|
1961
2032
|
mapping = Mapping.build(@scope, @set, ast, controller, default_action, to, via, formatted, options_constraints, anchor, options)
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
module ActionDispatch
|
4
4
|
module Routing
|
5
|
+
# = Action Dispatch Routing \PolymorphicRoutes
|
6
|
+
#
|
5
7
|
# Polymorphic URL helpers are methods for smart resolution to a named route call when
|
6
8
|
# given an Active Record model instance. They are to be used in combination with
|
7
9
|
# ActionController::Resources.
|
@@ -18,10 +18,19 @@ module ActionDispatch
|
|
18
18
|
def redirect?; true; end
|
19
19
|
|
20
20
|
def call(env)
|
21
|
-
|
21
|
+
ActiveSupport::Notifications.instrument("redirect.action_dispatch") do |payload|
|
22
|
+
request = Request.new(env)
|
23
|
+
response = build_response(request)
|
24
|
+
|
25
|
+
payload[:status] = @status
|
26
|
+
payload[:location] = response.headers["Location"]
|
27
|
+
payload[:request] = request
|
28
|
+
|
29
|
+
response.to_a
|
30
|
+
end
|
22
31
|
end
|
23
32
|
|
24
|
-
def
|
33
|
+
def build_response(req)
|
25
34
|
uri = URI.parse(path(req.path_parameters, req))
|
26
35
|
|
27
36
|
unless uri.host
|
@@ -38,15 +47,15 @@ module ActionDispatch
|
|
38
47
|
|
39
48
|
req.commit_flash
|
40
49
|
|
41
|
-
body =
|
50
|
+
body = ""
|
42
51
|
|
43
52
|
headers = {
|
44
53
|
"Location" => uri.to_s,
|
45
|
-
"Content-Type" => "text/html",
|
54
|
+
"Content-Type" => "text/html; charset=#{ActionDispatch::Response.default_charset}",
|
46
55
|
"Content-Length" => body.length.to_s
|
47
56
|
}
|
48
57
|
|
49
|
-
|
58
|
+
ActionDispatch::Response.new(status, headers, body)
|
50
59
|
end
|
51
60
|
|
52
61
|
def path(params, request)
|
@@ -59,7 +68,7 @@ module ActionDispatch
|
|
59
68
|
|
60
69
|
private
|
61
70
|
def relative_path?(path)
|
62
|
-
path && !path.empty? && path
|
71
|
+
path && !path.empty? && !path.start_with?("/")
|
63
72
|
end
|
64
73
|
|
65
74
|
def escape(params)
|
@@ -34,20 +34,20 @@ module ActionDispatch
|
|
34
34
|
if @raise_on_name_error
|
35
35
|
raise
|
36
36
|
else
|
37
|
-
[404, {
|
37
|
+
[404, { Constants::X_CASCADE => "pass" }, []]
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
41
|
+
private
|
42
|
+
def controller(req)
|
43
|
+
req.controller_class
|
44
|
+
rescue NameError => e
|
45
|
+
raise ActionController::RoutingError, e.message, e.backtrace
|
46
|
+
end
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
48
|
+
def dispatch(controller, action, req, res)
|
49
|
+
controller.dispatch(action, req, res)
|
50
|
+
end
|
51
51
|
end
|
52
52
|
|
53
53
|
class StaticDispatcher < Dispatcher
|
@@ -282,7 +282,7 @@ module ActionDispatch
|
|
282
282
|
|
283
283
|
if args.size < path_params_size
|
284
284
|
path_params -= controller_options.keys
|
285
|
-
path_params -= result.keys
|
285
|
+
path_params -= (result[:path_params] || {}).merge(result).keys
|
286
286
|
else
|
287
287
|
path_params = path_params.dup
|
288
288
|
end
|
@@ -375,6 +375,7 @@ module ActionDispatch
|
|
375
375
|
@disable_clear_and_finalize = false
|
376
376
|
@finalized = false
|
377
377
|
@env_key = "ROUTES_#{object_id}_SCRIPT_NAME"
|
378
|
+
@default_env = nil
|
378
379
|
|
379
380
|
@set = Journey::Routes.new
|
380
381
|
@router = Journey::Router.new @set
|
@@ -405,6 +406,25 @@ module ActionDispatch
|
|
405
406
|
end
|
406
407
|
private :make_request
|
407
408
|
|
409
|
+
def default_env
|
410
|
+
if default_url_options != @default_env&.[]("action_dispatch.routes.default_url_options")
|
411
|
+
url_options = default_url_options.dup.freeze
|
412
|
+
uri = URI(ActionDispatch::Http::URL.full_url_for(host: "example.org", **url_options))
|
413
|
+
|
414
|
+
@default_env = {
|
415
|
+
"action_dispatch.routes" => self,
|
416
|
+
"action_dispatch.routes.default_url_options" => url_options,
|
417
|
+
"HTTPS" => uri.scheme == "https" ? "on" : "off",
|
418
|
+
"rack.url_scheme" => uri.scheme,
|
419
|
+
"HTTP_HOST" => uri.port == uri.default_port ? uri.host : "#{uri.host}:#{uri.port}",
|
420
|
+
"SCRIPT_NAME" => uri.path.chomp("/"),
|
421
|
+
"rack.input" => "",
|
422
|
+
}.freeze
|
423
|
+
end
|
424
|
+
|
425
|
+
@default_env
|
426
|
+
end
|
427
|
+
|
408
428
|
def draw(&block)
|
409
429
|
clear! unless @disable_clear_and_finalize
|
410
430
|
eval_block(block)
|
@@ -574,6 +594,20 @@ module ActionDispatch
|
|
574
594
|
end
|
575
595
|
|
576
596
|
private :_generate_paths_by_default
|
597
|
+
|
598
|
+
# If the module is included more than once (for example, in a subclass
|
599
|
+
# of an ancestor that includes the module), ensure that the `_routes`
|
600
|
+
# singleton and instance methods return the desired route set by
|
601
|
+
# including a new copy of the module (recursively if necessary). Note
|
602
|
+
# that this method is called for each inclusion, whereas the above
|
603
|
+
# `included` block is run only for the initial inclusion of each copy.
|
604
|
+
def self.included(base)
|
605
|
+
super
|
606
|
+
if base.respond_to?(:_routes) && !base._routes.equal?(@_proxy._routes)
|
607
|
+
@dup_for_reinclude ||= self.dup
|
608
|
+
base.include @dup_for_reinclude
|
609
|
+
end
|
610
|
+
end
|
577
611
|
end
|
578
612
|
end
|
579
613
|
|
@@ -596,16 +630,16 @@ module ActionDispatch
|
|
596
630
|
named_routes[name] = route if name
|
597
631
|
|
598
632
|
if route.segment_keys.include?(:controller)
|
599
|
-
|
633
|
+
ActionDispatch.deprecator.warn(<<-MSG.squish)
|
600
634
|
Using a dynamic :controller segment in a route is deprecated and
|
601
|
-
will be removed in Rails 7.
|
635
|
+
will be removed in Rails 7.2.
|
602
636
|
MSG
|
603
637
|
end
|
604
638
|
|
605
639
|
if route.segment_keys.include?(:action)
|
606
|
-
|
640
|
+
ActionDispatch.deprecator.warn(<<-MSG.squish)
|
607
641
|
Using a dynamic :action segment in a route is deprecated and
|
608
|
-
will be removed in Rails 7.
|
642
|
+
will be removed in Rails 7.2.
|
609
643
|
MSG
|
610
644
|
end
|
611
645
|
|
@@ -779,18 +813,14 @@ module ActionDispatch
|
|
779
813
|
|
780
814
|
RESERVED_OPTIONS = [:host, :protocol, :port, :subdomain, :domain, :tld_length,
|
781
815
|
:trailing_slash, :anchor, :params, :only_path, :script_name,
|
782
|
-
:original_script_name
|
816
|
+
:original_script_name]
|
783
817
|
|
784
818
|
def optimize_routes_generation?
|
785
819
|
default_url_options.empty?
|
786
820
|
end
|
787
821
|
|
788
822
|
def find_script_name(options)
|
789
|
-
options.delete(:script_name) ||
|
790
|
-
end
|
791
|
-
|
792
|
-
def find_relative_url_root(options)
|
793
|
-
options.delete(:relative_url_root) || relative_url_root
|
823
|
+
options.delete(:script_name) || relative_url_root || ""
|
794
824
|
end
|
795
825
|
|
796
826
|
def path_for(options, route_name = nil, reserved = RESERVED_OPTIONS)
|
@@ -854,7 +884,7 @@ module ActionDispatch
|
|
854
884
|
|
855
885
|
def recognize_path(path, environment = {})
|
856
886
|
method = (environment[:method] || "GET").to_s.upcase
|
857
|
-
path = Journey::Router::Utils.normalize_path(path) unless
|
887
|
+
path = Journey::Router::Utils.normalize_path(path) unless path&.include?("://")
|
858
888
|
extras = environment[:extras] || {}
|
859
889
|
|
860
890
|
begin
|
@@ -873,7 +903,7 @@ module ActionDispatch
|
|
873
903
|
params.each do |key, value|
|
874
904
|
if value.is_a?(String)
|
875
905
|
value = value.dup.force_encoding(Encoding::BINARY)
|
876
|
-
params[key] =
|
906
|
+
params[key] = RFC2396_PARSER.unescape(value)
|
877
907
|
end
|
878
908
|
end
|
879
909
|
req.path_parameters = params
|
@@ -29,23 +29,18 @@ module ActionDispatch
|
|
29
29
|
|
30
30
|
def method_missing(method, *args)
|
31
31
|
if @helpers.respond_to?(method)
|
32
|
-
|
33
|
-
|
34
|
-
options = args.extract_options!
|
35
|
-
options = url_options.merge((options || {}).symbolize_keys)
|
32
|
+
options = args.extract_options!
|
33
|
+
options = url_options.merge((options || {}).symbolize_keys)
|
36
34
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
35
|
+
if @script_namer
|
36
|
+
options[:script_name] = merge_script_names(
|
37
|
+
options[:script_name],
|
38
|
+
@script_namer.call(options)
|
39
|
+
)
|
40
|
+
end
|
43
41
|
|
44
|
-
|
45
|
-
|
46
|
-
end
|
47
|
-
RUBY
|
48
|
-
public_send(method, *args)
|
42
|
+
args << options
|
43
|
+
@helpers.public_send(method, *args)
|
49
44
|
else
|
50
45
|
super
|
51
46
|
end
|
@@ -2,20 +2,22 @@
|
|
2
2
|
|
3
3
|
module ActionDispatch
|
4
4
|
module Routing
|
5
|
+
# = Action Dispatch Routing \UrlFor
|
6
|
+
#
|
5
7
|
# In <tt>config/routes.rb</tt> you define URL-to-controller mappings, but the reverse
|
6
8
|
# is also possible: a URL can be generated from one of your routing definitions.
|
7
9
|
# URL generation functionality is centralized in this module.
|
8
10
|
#
|
9
|
-
# See ActionDispatch::Routing for general information about routing and routes.rb
|
11
|
+
# See ActionDispatch::Routing for general information about routing and <tt>config/routes.rb</tt>.
|
10
12
|
#
|
11
13
|
# <b>Tip:</b> If you need to generate URLs from your models or some other place,
|
12
|
-
# then
|
14
|
+
# then ActionDispatch::Routing::UrlFor is what you're looking for. Read on for
|
13
15
|
# an introduction. In general, this module should not be included on its own,
|
14
|
-
# as it is usually included by url_helpers (as in Rails.application.routes.url_helpers).
|
16
|
+
# as it is usually included by +url_helpers+ (as in <tt>Rails.application.routes.url_helpers</tt>).
|
15
17
|
#
|
16
18
|
# == URL generation from parameters
|
17
19
|
#
|
18
|
-
# As you may know, some functions, such as ActionController::Base#url_for
|
20
|
+
# As you may know, some functions, such as <tt>ActionController::Base#url_for</tt>
|
19
21
|
# and ActionView::Helpers::UrlHelper#link_to, can generate URLs given a set
|
20
22
|
# of parameters. For example, you've probably had the chance to write code
|
21
23
|
# like this in one of your views:
|
@@ -24,12 +26,12 @@ module ActionDispatch
|
|
24
26
|
# action: 'new', message: 'Welcome!') %>
|
25
27
|
# # => <a href="/users/new?message=Welcome%21">Click here</a>
|
26
28
|
#
|
27
|
-
# link_to
|
28
|
-
# actually use
|
29
|
-
# they use the
|
29
|
+
# +link_to+, and all other functions that require URL generation functionality,
|
30
|
+
# actually use ActionDispatch::Routing::UrlFor under the hood. And in particular,
|
31
|
+
# they use the ActionDispatch::Routing::UrlFor#url_for method. One can generate
|
30
32
|
# the same path as the above example by using the following code:
|
31
33
|
#
|
32
|
-
# include UrlFor
|
34
|
+
# include ActionDispatch::Routing::UrlFor
|
33
35
|
# url_for(controller: 'users',
|
34
36
|
# action: 'new',
|
35
37
|
# message: 'Welcome!',
|
@@ -37,7 +39,7 @@ module ActionDispatch
|
|
37
39
|
# # => "/users/new?message=Welcome%21"
|
38
40
|
#
|
39
41
|
# Notice the <tt>only_path: true</tt> part. This is because UrlFor has no
|
40
|
-
# information about the website hostname that your Rails app is serving. So if you
|
42
|
+
# information about the website hostname that your \Rails app is serving. So if you
|
41
43
|
# want to include the hostname as well, then you must also pass the <tt>:host</tt>
|
42
44
|
# argument:
|
43
45
|
#
|
@@ -48,17 +50,17 @@ module ActionDispatch
|
|
48
50
|
# host: 'www.example.com')
|
49
51
|
# # => "http://www.example.com/users/new?message=Welcome%21"
|
50
52
|
#
|
51
|
-
# By default, all controllers and views have access to a special version of url_for
|
52
|
-
# that already knows what the current hostname is. So if you use url_for in your
|
53
|
+
# By default, all controllers and views have access to a special version of +url_for+,
|
54
|
+
# that already knows what the current hostname is. So if you use +url_for+ in your
|
53
55
|
# controllers or your views, then you don't need to explicitly pass the <tt>:host</tt>
|
54
56
|
# argument.
|
55
57
|
#
|
56
|
-
# For convenience
|
57
|
-
#
|
58
|
-
#
|
59
|
-
# the +:host+
|
60
|
-
#
|
61
|
-
#
|
58
|
+
# For convenience, mailers also include ActionDispatch::Routing::UrlFor. So
|
59
|
+
# within mailers, you can use url_for. However, mailers cannot access
|
60
|
+
# incoming web requests in order to derive hostname information, so you have
|
61
|
+
# to provide the +:host+ option or set the default host using
|
62
|
+
# +default_url_options+. For more information on url_for in mailers see the
|
63
|
+
# ActionMailer::Base documentation.
|
62
64
|
#
|
63
65
|
#
|
64
66
|
# == URL generation for named routes
|
@@ -72,7 +74,7 @@ module ActionDispatch
|
|
72
74
|
# This generates, among other things, the method <tt>users_path</tt>. By default,
|
73
75
|
# this method is accessible from your controllers, views, and mailers. If you need
|
74
76
|
# to access this auto-generated method from other places (such as a model), then
|
75
|
-
# you can do that by including Rails.application.routes.url_helpers in your class:
|
77
|
+
# you can do that by including <tt>Rails.application.routes.url_helpers</tt> in your class:
|
76
78
|
#
|
77
79
|
# class User < ActiveRecord::Base
|
78
80
|
# include Rails.application.routes.url_helpers
|
@@ -115,11 +117,11 @@ module ActionDispatch
|
|
115
117
|
default_url_options
|
116
118
|
end
|
117
119
|
|
118
|
-
# Generate a URL based on the options provided, default_url_options
|
119
|
-
# routes defined in routes.rb
|
120
|
+
# Generate a URL based on the options provided, +default_url_options+, and the
|
121
|
+
# routes defined in <tt>config/routes.rb</tt>. The following options are supported:
|
120
122
|
#
|
121
123
|
# * <tt>:only_path</tt> - If true, the relative URL is returned. Defaults to +false+.
|
122
|
-
# * <tt>:protocol</tt> - The protocol to connect to. Defaults to
|
124
|
+
# * <tt>:protocol</tt> - The protocol to connect to. Defaults to <tt>"http"</tt>.
|
123
125
|
# * <tt>:host</tt> - Specifies the host the link should be targeted at.
|
124
126
|
# If <tt>:only_path</tt> is false, this option must be
|
125
127
|
# provided either explicitly, or via +default_url_options+.
|
@@ -134,7 +136,9 @@ module ActionDispatch
|
|
134
136
|
# * <tt>:port</tt> - Optionally specify the port to connect to.
|
135
137
|
# * <tt>:anchor</tt> - An anchor name to be appended to the path.
|
136
138
|
# * <tt>:params</tt> - The query parameters to be appended to the path.
|
137
|
-
# * <tt>:
|
139
|
+
# * <tt>:path_params</tt> - The query parameters that will only be used
|
140
|
+
# for the named dynamic segments of path. If unused, they will be discarded.
|
141
|
+
# * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in <tt>"/archive/2009/"</tt>.
|
138
142
|
# * <tt>:script_name</tt> - Specifies application path relative to domain root. If provided, prepends application path.
|
139
143
|
#
|
140
144
|
# Any other key (<tt>:controller</tt>, <tt>:action</tt>, etc.) given to
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/core_ext/string/filters"
|
4
|
-
|
5
3
|
module ActionDispatch
|
6
4
|
# The routing module provides URL rewriting in native Ruby. It's a way to
|
7
5
|
# redirect incoming requests to controllers and actions. This replaces
|
@@ -119,9 +117,9 @@ module ActionDispatch
|
|
119
117
|
#
|
120
118
|
# # In config/routes.rb
|
121
119
|
# controller :blog do
|
122
|
-
# get 'blog/show'
|
123
|
-
# get 'blog/delete'
|
124
|
-
# get 'blog/edit'
|
120
|
+
# get 'blog/show' => :list
|
121
|
+
# get 'blog/delete' => :delete
|
122
|
+
# get 'blog/edit' => :edit
|
125
123
|
# end
|
126
124
|
#
|
127
125
|
# # provides named routes for show, delete, and edit
|
@@ -240,7 +238,7 @@ module ActionDispatch
|
|
240
238
|
#
|
241
239
|
# == View a list of all your routes
|
242
240
|
#
|
243
|
-
# rails routes
|
241
|
+
# $ bin/rails routes
|
244
242
|
#
|
245
243
|
# Target a specific controller with <tt>-c</tt>, or grep routes
|
246
244
|
# using <tt>-g</tt>. Useful in conjunction with <tt>--expanded</tt>
|
@@ -250,7 +248,9 @@ module ActionDispatch
|
|
250
248
|
|
251
249
|
autoload :Mapper
|
252
250
|
autoload :RouteSet
|
253
|
-
|
251
|
+
eager_autoload do
|
252
|
+
autoload :RoutesProxy
|
253
|
+
end
|
254
254
|
autoload :UrlFor
|
255
255
|
autoload :PolymorphicRoutes
|
256
256
|
|