Anchor the Action Cable server's route

Fixes https://github.com/rails/rails/issues/45489

- Adds `anchor: true` to the Action Cable server mount, so that it only strictly matches `/cable` rather than anything that starts with that.
- Uses `reverse_merge` instead of `merge` in `Mapper#mount`, so that you can override these options if you need to.
This commit is contained in:
Alex Ghiculescu 2022-06-29 11:42:02 -05:00
parent c3c747547a
commit 1ee984dfe4
4 changed files with 17 additions and 2 deletions

View File

@ -1,3 +1,9 @@
* The Action Cable server is now mounted with `anchor: true`.
This means that routes that also start with `/cable` will no longer clash with Action Cable.
*Alex Ghiculescu*
* `ActionCable.server.remote_connections.where(...).disconnect` now sends `disconnect` message
before closing the connection with the reconnection strategy specified (defaults to `true`).

View File

@ -51,7 +51,7 @@ module ActionCable
config = app.config
unless config.action_cable.mount_path.nil?
app.routes.prepend do
mount ActionCable.server => config.action_cable.mount_path, internal: true
mount ActionCable.server => config.action_cable.mount_path, internal: true, anchor: true
end
end
end

View File

@ -609,7 +609,7 @@ module ActionDispatch
target_as = name_for_action(options[:as], path)
options[:via] ||= :all
match(path, options.merge(to: app, anchor: false, format: false))
match(path, { to: app, anchor: false, format: false }.merge(options))
define_generate_prefix(app, target_as) if rails_app
self

View File

@ -172,6 +172,15 @@ module ActionDispatch
assert_equal "/*path.:format", fakeset.asts.first.to_s
end
def test_can_pass_anchor_to_mount
fakeset = FakeSet.new
mapper = Mapper.new fakeset
app = lambda { |env| [200, {}, [""]] }
mapper.mount app => "/path", anchor: true
assert_equal "/path", fakeset.asts.first.to_s
assert fakeset.routes.first.path.anchored
end
def test_raising_error_when_path_is_not_passed
fakeset = FakeSet.new
mapper = Mapper.new fakeset