mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Stop trying to reconnect on unauthorized cable connections
This commit is contained in:
parent
b802e08273
commit
58dbc1c2ed
9 changed files with 46 additions and 10 deletions
|
@ -1,3 +1,8 @@
|
|||
* 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 @@ module ActionCable
|
|||
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 @@ module ActionCable
|
|||
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 @@ module ActionCable
|
|||
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 @@ module ActionCable
|
|||
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 @@ class ActionCable::Connection::AuthorizationTest < ActionCable::TestCase
|
|||
"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 @@ class ActionCable::Connection::BaseTest < ActionCable::TestCase
|
|||
connection.process
|
||||
|
||||
assert_called(connection.websocket, :close) do
|
||||
connection.close
|
||||
connection.close(reason: "testing")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -58,7 +58,7 @@ class ActionCable::Connection::ClientSocketTest < ActionCable::TestCase
|
|||
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
|
||||
|
|
Loading…
Reference in a new issue