提交 2bce7777 编写于 作者: P palkan

[Fix #28751] Hash stream long stream identifiers when using Postgres adapter

上级 c8ce3459
* Hash long stream identifiers when using Postgres adapter.
PostgreSQL has a limit on identifiers length (63 chars, [docs](https://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS)).
Provided fix minifies identifiers longer than 63 chars by hashing them with SHA1.
Fixes #28751.
*Vladimir Dementyev*
* ActionCable's `redis` adapter allows for other common redis-rb options (`host`, `port`, `db`, `password`) in cable.yml.
Previously, it accepts only a [redis:// url](https://www.iana.org/assignments/uri-schemes/prov/redis) as an option.
......
gem "pg", "~> 0.18"
require "pg"
require "thread"
require "digest/sha1"
module ActionCable
module SubscriptionAdapter
......@@ -12,16 +13,16 @@ def initialize(*)
def broadcast(channel, payload)
with_connection do |pg_conn|
pg_conn.exec("NOTIFY #{pg_conn.escape_identifier(channel)}, '#{pg_conn.escape_string(payload)}'")
pg_conn.exec("NOTIFY #{pg_conn.escape_identifier(channel_identifier(channel))}, '#{pg_conn.escape_string(payload)}'")
end
end
def subscribe(channel, callback, success_callback = nil)
listener.add_subscriber(channel, callback, success_callback)
listener.add_subscriber(channel_identifier(channel), callback, success_callback)
end
def unsubscribe(channel, callback)
listener.remove_subscriber(channel, callback)
listener.remove_subscriber(channel_identifier(channel), callback)
end
def shutdown
......@@ -41,6 +42,10 @@ def with_connection(&block) # :nodoc:
end
private
def channel_identifier(channel)
channel.size > 63 ? Digest::SHA1.hexdigest(channel) : channel
end
def listener
@listener || @server.mutex.synchronize { @listener ||= Listener.new(self, @server.event_loop) }
end
......
......@@ -112,4 +112,18 @@ def test_channel_filtered_broadcast
assert_equal "two", queue.pop
end
end
def test_long_identifiers
channel_1 = "a" * 100 + "1"
channel_2 = "a" * 100 + "2"
subscribe_as_queue(channel_1) do |queue|
subscribe_as_queue(channel_2) do |queue_2|
@tx_adapter.broadcast(channel_1, "apples")
@tx_adapter.broadcast(channel_2, "oranges")
assert_equal "apples", queue.pop
assert_equal "oranges", queue_2.pop
end
end
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册