未验证 提交 d9816546 编写于 作者: R Rafael França 提交者: GitHub

Merge pull request #34194 from staugaard/staugaard/actioncable_unauthorized

Stop trying to reconnect on unauthorized cable connections
* The JavaScript WebSocket client will no longer try to reconnect
when you call `reject_unauthorized_connection` on the connection.
*Mick Staugaard*
* `ActionCable.Connection#getState` now references the configurable
`ActionCable.adapters.WebSocket` property rather than the `WebSocket` global
variable, matching the behavior of `ActionCable.Connection#open`.
......
......@@ -136,10 +136,16 @@
var INTERNAL = {
message_types: {
welcome: "welcome",
disconnect: "disconnect",
ping: "ping",
confirmation: "confirm_subscription",
rejection: "reject_subscription"
},
disconnect_reasons: {
unauthorized: "unauthorized",
invalid_request: "invalid_request",
server_restart: "server_restart"
},
default_mount_path: "/cable",
protocols: [ "actioncable-v1-json", "actioncable-unsupported" ]
};
......@@ -251,12 +257,18 @@
if (!this.isProtocolSupported()) {
return;
}
var _JSON$parse = JSON.parse(event.data), identifier = _JSON$parse.identifier, message = _JSON$parse.message, type = _JSON$parse.type;
var _JSON$parse = JSON.parse(event.data), identifier = _JSON$parse.identifier, message = _JSON$parse.message, reason = _JSON$parse.reason, reconnect = _JSON$parse.reconnect, type = _JSON$parse.type;
switch (type) {
case message_types.welcome:
this.monitor.recordConnect();
return this.subscriptions.reload();
case message_types.disconnect:
logger.log("Disconnecting. Reason: " + reason);
return this.close({
allowReconnect: reconnect
});
case message_types.ping:
return this.monitor.recordPing();
......
......@@ -117,11 +117,14 @@ Connection.reopenDelay = 500
Connection.prototype.events = {
message(event) {
if (!this.isProtocolSupported()) { return }
const {identifier, message, type} = JSON.parse(event.data)
const {identifier, message, reason, reconnect, type} = JSON.parse(event.data)
switch (type) {
case message_types.welcome:
this.monitor.recordConnect()
return this.subscriptions.reload()
case message_types.disconnect:
logger.log(`Disconnecting. Reason: ${reason}`)
return this.close({allowReconnect: reconnect})
case message_types.ping:
return this.monitor.recordPing()
case message_types.confirmation:
......
......@@ -33,10 +33,16 @@ module ActionCable
INTERNAL = {
message_types: {
welcome: "welcome",
disconnect: "disconnect",
ping: "ping",
confirmation: "confirm_subscription",
rejection: "reject_subscription"
},
disconnect_reasons: {
unauthorized: "unauthorized",
invalid_request: "invalid_request",
server_restart: "server_restart"
},
default_mount_path: "/cable",
protocols: ["actioncable-v1-json", "actioncable-unsupported"].freeze
}
......
......@@ -95,7 +95,12 @@ def transmit(cable_message) # :nodoc:
end
# Close the WebSocket connection.
def close
def close(reason: nil, reconnect: true)
transmit(
type: ActionCable::INTERNAL[:message_types][:disconnect],
reason: reason,
reconnect: reconnect
)
websocket.close
end
......@@ -170,7 +175,7 @@ def handle_open
message_buffer.process!
server.add_connection(self)
rescue ActionCable::Connection::Authorization::UnauthorizedError
respond_to_invalid_request
close(reason: ActionCable::INTERNAL[:disconnect_reasons][:unauthorized], reconnect: false) if websocket.alive?
end
def handle_close
......@@ -211,7 +216,7 @@ def respond_to_successful_request
end
def respond_to_invalid_request
close if websocket.alive?
close(reason: ActionCable::INTERNAL[:disconnect_reasons][:invalid_request]) if websocket.alive?
logger.error invalid_request_message
logger.info finished_request_message
......
......@@ -36,7 +36,9 @@ def disconnect(identifiers)
end
def restart
connections.each(&:close)
connections.each do |connection|
connection.close(reason: ActionCable::INTERNAL[:disconnect_reasons][:server_restart])
end
@mutex.synchronize do
# Shutdown the worker pool
......
......@@ -25,8 +25,11 @@ def send_async(method, *args)
"HTTP_HOST" => "localhost", "HTTP_ORIGIN" => "http://rubyonrails.com"
connection = Connection.new(server, env)
assert_called(connection.websocket, :close) do
connection.process
assert_called_with(connection.websocket, :transmit, [{ type: "disconnect", reason: "unauthorized", reconnect: false }.to_json]) do
assert_called(connection.websocket, :close) do
connection.process
end
end
end
end
......
......@@ -108,7 +108,7 @@ def send_async(method, *args)
connection.process
assert_called(connection.websocket, :close) do
connection.close
connection.close(reason: "testing")
end
end
end
......
......@@ -58,7 +58,7 @@ def on_error(message)
client.instance_variable_get("@stream")
.instance_variable_get("@rack_hijack_io")
.define_singleton_method(:close) { event.set }
connection.close
connection.close(reason: "testing")
event.wait
end
end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册