ably 1.2.5 → 1.2.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/check.yml +1 -1
- data/CHANGELOG.md +17 -0
- data/README.md +24 -7
- data/SPEC.md +1722 -853
- data/ably.gemspec +1 -1
- data/lib/ably/auth.rb +19 -11
- data/lib/ably/models/protocol_message.rb +5 -26
- data/lib/ably/modules/safe_deferrable.rb +2 -2
- data/lib/ably/modules/state_emitter.rb +1 -1
- data/lib/ably/realtime/auth.rb +4 -0
- data/lib/ably/realtime/channel/channel_manager.rb +51 -48
- data/lib/ably/realtime/channel/channel_properties.rb +9 -0
- data/lib/ably/realtime/channel/channel_state_machine.rb +2 -0
- data/lib/ably/realtime/channel.rb +4 -3
- data/lib/ably/realtime/channels.rb +20 -0
- data/lib/ably/realtime/client/incoming_message_dispatcher.rb +14 -13
- data/lib/ably/realtime/client.rb +14 -6
- data/lib/ably/realtime/connection/connection_manager.rb +21 -22
- data/lib/ably/realtime/connection.rb +77 -109
- data/lib/ably/realtime/presence/members_map.rb +41 -92
- data/lib/ably/realtime/presence/presence_manager.rb +12 -17
- data/lib/ably/realtime/presence.rb +15 -6
- data/lib/ably/realtime/push.rb +0 -27
- data/lib/ably/realtime/recovery_key_context.rb +36 -0
- data/lib/ably/rest/client.rb +4 -6
- data/lib/ably/rest/push/admin.rb +1 -1
- data/lib/ably/rest/push.rb +0 -19
- data/lib/ably/util/ably_extensions.rb +29 -0
- data/lib/ably/util/crypto.rb +2 -2
- data/lib/ably/util/safe_deferrable.rb +1 -1
- data/lib/ably/version.rb +5 -7
- data/spec/acceptance/realtime/channel_history_spec.rb +8 -12
- data/spec/acceptance/realtime/channel_spec.rb +474 -300
- data/spec/acceptance/realtime/client_spec.rb +1 -1
- data/spec/acceptance/realtime/connection_failures_spec.rb +8 -25
- data/spec/acceptance/realtime/connection_spec.rb +28 -120
- data/spec/acceptance/realtime/message_spec.rb +23 -52
- data/spec/acceptance/realtime/presence_spec.rb +123 -92
- data/spec/acceptance/rest/channel_spec.rb +2 -2
- data/spec/acceptance/rest/client_spec.rb +9 -2
- data/spec/acceptance/rest/message_spec.rb +8 -11
- data/spec/acceptance/rest/push_admin_spec.rb +20 -15
- data/spec/shared/client_initializer_behaviour.rb +1 -1
- data/spec/support/markdown_spec_formatter.rb +1 -1
- data/spec/unit/models/protocol_message_spec.rb +0 -78
- data/spec/unit/models/token_details_spec.rb +4 -2
- data/spec/unit/realtime/channels_spec.rb +1 -1
- data/spec/unit/realtime/connection_spec.rb +0 -30
- data/spec/unit/realtime/recovery_key_context_spec.rb +36 -0
- data/spec/unit/util/crypto_spec.rb +15 -15
- metadata +9 -9
- data/spec/acceptance/realtime/push_spec.rb +0 -27
- data/spec/acceptance/rest/push_spec.rb +0 -25
@@ -133,7 +133,7 @@ describe Ably::Realtime::Client, :event_machine do
|
|
133
133
|
end
|
134
134
|
end
|
135
135
|
|
136
|
-
context 'with a wildcard client_id token' do
|
136
|
+
context 'with a wildcard client_id token ' do
|
137
137
|
subject { auto_close Ably::Realtime::Client.new(client_options) }
|
138
138
|
let(:client_options) { default_options.merge(auth_callback: lambda { |token_params| auth_token_object }, client_id: client_id) }
|
139
139
|
let(:rest_auth_client) { Ably::Rest::Client.new(default_options.merge(key: api_key)) }
|
@@ -747,8 +747,6 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
747
747
|
resumed_connection = false
|
748
748
|
|
749
749
|
connection.once(:disconnected) do
|
750
|
-
disconnected_at = Time.now
|
751
|
-
|
752
750
|
allow(connection).to receive(:time_since_connection_confirmed_alive?).and_return(connection.connection_state_ttl + 1)
|
753
751
|
|
754
752
|
# Make sure the next connect does not have the resume param
|
@@ -781,8 +779,6 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
781
779
|
resumed_with_clean_connection = false
|
782
780
|
|
783
781
|
connection.once(:disconnected) do
|
784
|
-
disconnected_at = Time.now
|
785
|
-
|
786
782
|
pseudo_time_passed = connection.connection_state_ttl + connection.details.max_idle_interval + 1
|
787
783
|
allow(connection).to receive(:time_since_connection_confirmed_alive?).and_return(pseudo_time_passed)
|
788
784
|
|
@@ -815,14 +811,11 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
815
811
|
channel_emitted_an_attached = false
|
816
812
|
|
817
813
|
channel.attach do
|
818
|
-
channel.once(:attached) do
|
819
|
-
expect(channel_state_change.resumed).to be_falsey
|
814
|
+
channel.once(:attached) do
|
820
815
|
channel_emitted_an_attached = true
|
821
816
|
end
|
822
817
|
|
823
818
|
connection.once(:disconnected) do
|
824
|
-
disconnected_at = Time.now
|
825
|
-
|
826
819
|
pseudo_time_passed = connection.connection_state_ttl + connection.details.max_idle_interval + 1
|
827
820
|
allow(connection).to receive(:time_since_connection_confirmed_alive?).and_return(pseudo_time_passed)
|
828
821
|
|
@@ -955,7 +948,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
955
948
|
previous_connection_id = connection.id
|
956
949
|
connection.transport.close_connection_after_writing
|
957
950
|
|
958
|
-
expect(connection).to receive(:configure_new).with(previous_connection_id, anything
|
951
|
+
expect(connection).to receive(:configure_new).with(previous_connection_id, anything).and_call_original
|
959
952
|
|
960
953
|
connection.once(:connected) do
|
961
954
|
expect(connection.key).to_not be_nil
|
@@ -1008,16 +1001,6 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
1008
1001
|
end
|
1009
1002
|
end
|
1010
1003
|
|
1011
|
-
it 'executes the resume callback', api_private: true do
|
1012
|
-
channel.attach do
|
1013
|
-
connection.transport.close_connection_after_writing
|
1014
|
-
connection.on_resume do
|
1015
|
-
expect(connection).to be_connected
|
1016
|
-
stop_reactor
|
1017
|
-
end
|
1018
|
-
end
|
1019
|
-
end
|
1020
|
-
|
1021
1004
|
context 'when messages were published whilst the client was disconnected' do
|
1022
1005
|
it 'receives the messages published whilst offline' do
|
1023
1006
|
messages_received = false
|
@@ -1089,7 +1072,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
1089
1072
|
|
1090
1073
|
def kill_connection_transport_and_prevent_valid_resume
|
1091
1074
|
connection.transport.close_connection_after_writing
|
1092
|
-
connection.configure_new '0123456789abcdef', '
|
1075
|
+
connection.configure_new '0123456789abcdef', '0123456789abcdef-99' # force the resume connection key to be invalid
|
1093
1076
|
end
|
1094
1077
|
|
1095
1078
|
it 'updates the connection_id and connection_key' do
|
@@ -1122,7 +1105,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
1122
1105
|
end
|
1123
1106
|
channel.on(:attaching) do |channel_state_change|
|
1124
1107
|
error = channel_state_change.reason
|
1125
|
-
expect(error.message).to match(/
|
1108
|
+
expect(error.message).to match(/Invalid connection key/i)
|
1126
1109
|
reattaching_channels << channel
|
1127
1110
|
end
|
1128
1111
|
channel.on(:attached) do
|
@@ -1222,9 +1205,9 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
1222
1205
|
it 'sets the error reason on each channel' do
|
1223
1206
|
channel.attach do
|
1224
1207
|
channel.on(:attaching) do |state_change|
|
1225
|
-
expect(state_change.reason.message).to match(/
|
1226
|
-
expect(state_change.reason.code).to eql(
|
1227
|
-
expect(channel.error_reason.code).to eql(
|
1208
|
+
expect(state_change.reason.message).to match(/Invalid connection key/i)
|
1209
|
+
expect(state_change.reason.code).to eql(80018)
|
1210
|
+
expect(channel.error_reason.code).to eql(80018)
|
1228
1211
|
|
1229
1212
|
channel.on(:attached) do |state_change|
|
1230
1213
|
stop_reactor
|
@@ -1375,7 +1358,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
1375
1358
|
end)
|
1376
1359
|
end
|
1377
1360
|
|
1378
|
-
|
1361
|
+
it 'triggers a re-authentication and then resumes the connection' do
|
1379
1362
|
# [PENDING] After sandbox env update connection isn't found and a new connection is created. Spec fails
|
1380
1363
|
#
|
1381
1364
|
connection.once(:connected) do
|
@@ -102,6 +102,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
102
102
|
end
|
103
103
|
|
104
104
|
let(:ttl) { 2 }
|
105
|
+
let(:clock_skew) { 0.1 } # 0.1 second clock skew
|
105
106
|
|
106
107
|
it 'renews token every time after it expires' do
|
107
108
|
started_at = Time.now.to_f
|
@@ -114,8 +115,8 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
114
115
|
disconnected_times += 1
|
115
116
|
if disconnected_times == 3
|
116
117
|
expect(connected_times).to eql(3)
|
117
|
-
expect(Time.now.to_f - started_at).to be > ttl * 3
|
118
|
-
expect(Time.now.to_f - started_at).to be < (ttl * 2) * 3
|
118
|
+
expect((Time.now.to_f - started_at) + clock_skew).to be > ttl * 3
|
119
|
+
expect((Time.now.to_f - started_at) - clock_skew).to be < (ttl * 2) * 3
|
119
120
|
stop_reactor
|
120
121
|
end
|
121
122
|
end
|
@@ -386,7 +387,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
386
387
|
expect(client.client_id).to eql('incompatible')
|
387
388
|
client.connection.once(:failed) do
|
388
389
|
expect(client.client_id).to eql('incompatible')
|
389
|
-
expect(client.connection.error_reason.code).to eql(
|
390
|
+
expect(client.connection.error_reason.code).to eql(40102) # Incompatible clientId for credentials
|
390
391
|
stop_reactor
|
391
392
|
end
|
392
393
|
end
|
@@ -743,58 +744,6 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
743
744
|
end
|
744
745
|
end
|
745
746
|
|
746
|
-
describe '#serial connection serial' do
|
747
|
-
let(:channel) { client.channel(random_str) }
|
748
|
-
|
749
|
-
it 'is set to -1 when a new connection is opened' do
|
750
|
-
connection.connect do
|
751
|
-
expect(connection.serial).to eql(-1)
|
752
|
-
stop_reactor
|
753
|
-
end
|
754
|
-
end
|
755
|
-
|
756
|
-
context 'when a message is sent but the ACK has not yet been received' do
|
757
|
-
it 'the sent message msgSerial is 0 but the connection serial remains at -1' do
|
758
|
-
channel.attach do
|
759
|
-
connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
760
|
-
if protocol_message.action == :message
|
761
|
-
connection.__outgoing_protocol_msgbus__.unsubscribe
|
762
|
-
expect(protocol_message['msgSerial']).to eql(0)
|
763
|
-
expect(connection.serial).to eql(-1)
|
764
|
-
stop_reactor
|
765
|
-
end
|
766
|
-
end
|
767
|
-
channel.publish('event', 'data')
|
768
|
-
end
|
769
|
-
end
|
770
|
-
end
|
771
|
-
|
772
|
-
it 'is set to 0 when a message is received back' do
|
773
|
-
channel.publish('event', 'data')
|
774
|
-
channel.subscribe do
|
775
|
-
expect(connection.serial).to eql(0)
|
776
|
-
stop_reactor
|
777
|
-
end
|
778
|
-
end
|
779
|
-
|
780
|
-
it 'is set to 1 when the second message is received' do
|
781
|
-
channel.attach do
|
782
|
-
messages = []
|
783
|
-
channel.subscribe do |message|
|
784
|
-
messages << message
|
785
|
-
if messages.length == 2
|
786
|
-
expect(connection.serial).to eql(1)
|
787
|
-
stop_reactor
|
788
|
-
end
|
789
|
-
end
|
790
|
-
|
791
|
-
channel.publish('event', 'data') do
|
792
|
-
channel.publish('event', 'data')
|
793
|
-
end
|
794
|
-
end
|
795
|
-
end
|
796
|
-
end
|
797
|
-
|
798
747
|
describe '#msgSerial' do
|
799
748
|
context 'when messages are queued for publish before a connection is established' do
|
800
749
|
let(:batches) { 6 }
|
@@ -921,7 +870,6 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
921
870
|
let(:protocol_message_attributes) do
|
922
871
|
{
|
923
872
|
action: Ably::Models::ProtocolMessage::ACTION.Connected.to_i,
|
924
|
-
connection_serial: 55,
|
925
873
|
connection_details: {
|
926
874
|
max_idle_interval: 2 * 1000
|
927
875
|
}
|
@@ -1231,7 +1179,6 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1231
1179
|
let(:protocol_message_attributes) do
|
1232
1180
|
{
|
1233
1181
|
action: Ably::Models::ProtocolMessage::ACTION.Connected.to_i,
|
1234
|
-
connection_serial: 55,
|
1235
1182
|
connection_details: {
|
1236
1183
|
max_idle_interval: 2 * 1000
|
1237
1184
|
}
|
@@ -1402,34 +1349,6 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1402
1349
|
let(:states) { Hash.new }
|
1403
1350
|
let(:channel) { client.channel(random_str) }
|
1404
1351
|
|
1405
|
-
it 'is composed of connection key and serial that is kept up to date with each message ACK received' do
|
1406
|
-
connection.on(:connected) do
|
1407
|
-
expected_serial = -1
|
1408
|
-
expect(connection.key).to_not be_nil
|
1409
|
-
expect(connection.serial).to eql(expected_serial)
|
1410
|
-
|
1411
|
-
channel.attach do
|
1412
|
-
channel.publish('event', 'data')
|
1413
|
-
channel.subscribe do
|
1414
|
-
channel.unsubscribe
|
1415
|
-
|
1416
|
-
expected_serial += 1 # attach message received
|
1417
|
-
expect(connection.serial).to eql(expected_serial)
|
1418
|
-
|
1419
|
-
channel.publish('event', 'data')
|
1420
|
-
channel.subscribe do
|
1421
|
-
channel.unsubscribe
|
1422
|
-
expected_serial += 1 # attach message received
|
1423
|
-
expect(connection.serial).to eql(expected_serial)
|
1424
|
-
|
1425
|
-
expect(connection.recovery_key).to eql("#{connection.key}:#{connection.serial}:#{connection.send(:client_msg_serial)}")
|
1426
|
-
stop_reactor
|
1427
|
-
end
|
1428
|
-
end
|
1429
|
-
end
|
1430
|
-
end
|
1431
|
-
end
|
1432
|
-
|
1433
1352
|
it "is available when connection is in one of the states: #{available_states.join(', ')}" do
|
1434
1353
|
connection.once(:connected) do
|
1435
1354
|
allow(client).to receive(:endpoint).and_return(
|
@@ -1445,7 +1364,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1445
1364
|
|
1446
1365
|
available_states.each do |state|
|
1447
1366
|
connection.on(state) do
|
1448
|
-
states[state.to_sym] = true if connection.
|
1367
|
+
states[state.to_sym] = true if connection.create_recovery_key
|
1449
1368
|
end
|
1450
1369
|
end
|
1451
1370
|
|
@@ -1463,7 +1382,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1463
1382
|
it 'is nil when connection is explicitly CLOSED' do
|
1464
1383
|
connection.once(:connected) do
|
1465
1384
|
connection.close do
|
1466
|
-
expect(connection.
|
1385
|
+
expect(connection.create_recovery_key).to be_nil
|
1467
1386
|
stop_reactor
|
1468
1387
|
end
|
1469
1388
|
end
|
@@ -1474,36 +1393,22 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1474
1393
|
context 'connection#id after recovery' do
|
1475
1394
|
it 'remains the same' do
|
1476
1395
|
previous_connection_id = nil
|
1396
|
+
recovery_key = nil
|
1477
1397
|
|
1478
1398
|
connection.once(:connected) do
|
1479
1399
|
previous_connection_id = connection.id
|
1400
|
+
recovery_key = client.connection.create_recovery_key
|
1480
1401
|
connection.transition_state_machine! :failed
|
1481
1402
|
end
|
1482
1403
|
|
1483
1404
|
connection.once(:failed) do
|
1484
|
-
recover_client = auto_close Ably::Realtime::Client.new(default_options.merge(recover:
|
1405
|
+
recover_client = auto_close Ably::Realtime::Client.new(default_options.merge(recover: recovery_key))
|
1485
1406
|
recover_client.connection.on(:connected) do
|
1486
1407
|
expect(recover_client.connection.id).to eql(previous_connection_id)
|
1487
1408
|
stop_reactor
|
1488
1409
|
end
|
1489
1410
|
end
|
1490
1411
|
end
|
1491
|
-
|
1492
|
-
it 'does not call a resume callback', api_private: true do
|
1493
|
-
connection.once(:connected) do
|
1494
|
-
connection.transition_state_machine! :failed
|
1495
|
-
end
|
1496
|
-
|
1497
|
-
connection.once(:failed) do
|
1498
|
-
recover_client = auto_close Ably::Realtime::Client.new(default_options.merge(recover: client.connection.recovery_key))
|
1499
|
-
recover_client.connection.on_resume do
|
1500
|
-
raise 'Should not call the resume callback'
|
1501
|
-
end
|
1502
|
-
recover_client.connection.on(:connected) do
|
1503
|
-
EventMachine.add_timer(0.5) { stop_reactor }
|
1504
|
-
end
|
1505
|
-
end
|
1506
|
-
end
|
1507
1412
|
end
|
1508
1413
|
|
1509
1414
|
context 'when messages have been sent whilst the old connection is disconnected' do
|
@@ -1513,7 +1418,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1513
1418
|
|
1514
1419
|
channel.attach do
|
1515
1420
|
connection_id = client.connection.id
|
1516
|
-
recovery_key = client.connection.
|
1421
|
+
recovery_key = client.connection.create_recovery_key
|
1517
1422
|
connection.transport.__incoming_protocol_msgbus__
|
1518
1423
|
publishing_client_channel.publish('event', 'message') do
|
1519
1424
|
connection.transition_state_machine! :failed
|
@@ -1547,7 +1452,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1547
1452
|
channel.publish('event', 'message') do
|
1548
1453
|
msg_serial = connection.send(:client_msg_serial)
|
1549
1454
|
expect(msg_serial).to eql(0)
|
1550
|
-
recovery_key = client.connection.
|
1455
|
+
recovery_key = client.connection.create_recovery_key
|
1551
1456
|
connection.transition_state_machine! :failed
|
1552
1457
|
end
|
1553
1458
|
end
|
@@ -1578,7 +1483,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1578
1483
|
expect(message.data).to eql('message-1')
|
1579
1484
|
msg_serial = connection.send(:client_msg_serial)
|
1580
1485
|
expect(msg_serial).to eql(0)
|
1581
|
-
recovery_key = client.connection.
|
1486
|
+
recovery_key = client.connection.create_recovery_key
|
1582
1487
|
connection.transition_state_machine! :failed
|
1583
1488
|
end
|
1584
1489
|
channel.publish('event', 'message-1')
|
@@ -1612,23 +1517,29 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1612
1517
|
|
1613
1518
|
context 'with :recover option' do
|
1614
1519
|
context 'with invalid syntax' do
|
1615
|
-
let(:
|
1520
|
+
let(:client_options) { default_options.merge(recover: 'invalid') }
|
1616
1521
|
|
1617
|
-
it '
|
1618
|
-
|
1619
|
-
|
1522
|
+
it 'logs recovery decode error as a warning and connects successfully' do
|
1523
|
+
connection.once(:connected) do
|
1524
|
+
EventMachine.add_timer(1) { stop_reactor }
|
1525
|
+
end
|
1526
|
+
expect(client.logger).to receive(:warn).at_least(:once) do |*args, &block|
|
1527
|
+
expect(args.concat([block ? block.call : nil]).join(',')).to match(/unable to decode recovery key/)
|
1528
|
+
end
|
1620
1529
|
end
|
1621
1530
|
end
|
1622
1531
|
|
1623
|
-
context 'with
|
1624
|
-
|
1532
|
+
context 'with invalid connection key' do
|
1533
|
+
recovery_key = "{\"connection_key\":\"0123456789abcdef-99\",\"msg_serial\":2," <<
|
1534
|
+
"\"channel_serials\":{\"channel1\":\"serial1\",\"channel2\":\"serial2\"}}"
|
1535
|
+
let(:client_options) { default_options.merge(recover: recovery_key, log_level: :fatal) }
|
1625
1536
|
|
1626
1537
|
it 'connects but sets the error reason and includes the reason in the state change' do
|
1627
1538
|
connection.once(:connected) do |state_change|
|
1628
1539
|
expect(connection.state).to eq(:connected)
|
1629
|
-
expect(state_change.reason.message).to match(/
|
1630
|
-
expect(connection.error_reason.message).to match(/
|
1631
|
-
expect(connection.error_reason.code).to eql(
|
1540
|
+
expect(state_change.reason.message).to match(/Invalid connection key/i)
|
1541
|
+
expect(connection.error_reason.message).to match(/Invalid connection key/i)
|
1542
|
+
expect(connection.error_reason.code).to eql(80018)
|
1632
1543
|
expect(connection.error_reason).to eql(state_change.reason)
|
1633
1544
|
stop_reactor
|
1634
1545
|
end
|
@@ -2000,7 +1911,6 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
2000
1911
|
let(:protocol_message_attributes) do
|
2001
1912
|
{
|
2002
1913
|
action: Ably::Models::ProtocolMessage::ACTION.Connected.to_i,
|
2003
|
-
connection_serial: 55,
|
2004
1914
|
connection_details: {
|
2005
1915
|
client_id: 'bob',
|
2006
1916
|
connection_key: connection_key,
|
@@ -2036,7 +1946,6 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
2036
1946
|
connection.once(:update) do |connection_state_change|
|
2037
1947
|
expect(client.auth.client_id).to eql('bob')
|
2038
1948
|
expect(connection.key).to eql(connection_key)
|
2039
|
-
expect(connection.serial).to eql(55)
|
2040
1949
|
expect(connection.connection_state_ttl).to eql(33)
|
2041
1950
|
|
2042
1951
|
expect(connection.details.client_id).to eql('bob')
|
@@ -2059,7 +1968,6 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
2059
1968
|
let(:protocol_message_attributes) do
|
2060
1969
|
{
|
2061
1970
|
action: Ably::Models::ProtocolMessage::ACTION.Connected.to_i,
|
2062
|
-
connection_serial: 22,
|
2063
1971
|
error: { code: 50000, message: 'Internal failure' },
|
2064
1972
|
}
|
2065
1973
|
end
|
@@ -2088,7 +1996,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
2088
1996
|
it 'sends the protocol version param v (#G4, #RTN2f)' do
|
2089
1997
|
expect(EventMachine).to receive(:connect) do |host, port, transport, object, url|
|
2090
1998
|
uri = URI.parse(url)
|
2091
|
-
expect(CGI::parse(uri.query)['v'][0]).to eql('
|
1999
|
+
expect(CGI::parse(uri.query)['v'][0]).to eql('2')
|
2092
2000
|
stop_reactor
|
2093
2001
|
end
|
2094
2002
|
client
|
@@ -304,8 +304,6 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
304
304
|
it 'will not echo messages to the client but will still broadcast messages to other connected clients', em_timeout: 10 do
|
305
305
|
channel.attach do |echo_channel|
|
306
306
|
no_echo_channel.attach do
|
307
|
-
no_echo_channel.publish 'test_event', payload
|
308
|
-
|
309
307
|
no_echo_channel.subscribe('test_event') do |message|
|
310
308
|
fail "Message should not have been echoed back"
|
311
309
|
end
|
@@ -316,6 +314,7 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
316
314
|
stop_reactor
|
317
315
|
end
|
318
316
|
end
|
317
|
+
no_echo_channel.publish 'test_event', payload
|
319
318
|
end
|
320
319
|
end
|
321
320
|
end
|
@@ -418,41 +417,6 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
418
417
|
end
|
419
418
|
end
|
420
419
|
|
421
|
-
context 'server incorrectly resends a message that was already received by the client library' do
|
422
|
-
let(:messages_received) { [] }
|
423
|
-
let(:connection) { client.connection }
|
424
|
-
let(:client_options) { default_options.merge(log_level: :fatal) }
|
425
|
-
|
426
|
-
it 'discards the message and logs it as an error to the channel' do
|
427
|
-
first_message_protocol_message = nil
|
428
|
-
connection.__incoming_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
429
|
-
first_message_protocol_message ||= protocol_message unless protocol_message.messages.empty?
|
430
|
-
end
|
431
|
-
|
432
|
-
channel.attach do
|
433
|
-
channel.subscribe do |message|
|
434
|
-
messages_received << message
|
435
|
-
if messages_received.count == 2
|
436
|
-
# simulate a duplicate protocol message being received
|
437
|
-
EventMachine.next_tick do
|
438
|
-
connection.__incoming_protocol_msgbus__.publish :protocol_message, first_message_protocol_message
|
439
|
-
end
|
440
|
-
end
|
441
|
-
end
|
442
|
-
2.times { |i| EventMachine.add_timer(i.to_f / 5) { channel.publish('event', 'data') } }
|
443
|
-
|
444
|
-
expect(client.logger).to receive(:error) do |*args, &block|
|
445
|
-
expect(args.concat([block ? block.call : nil]).join(',')).to match(/duplicate/)
|
446
|
-
|
447
|
-
EventMachine.add_timer(0.5) do
|
448
|
-
expect(messages_received.count).to eql(2)
|
449
|
-
stop_reactor
|
450
|
-
end
|
451
|
-
end
|
452
|
-
end
|
453
|
-
end
|
454
|
-
end
|
455
|
-
|
456
420
|
context 'encoding and decoding encrypted messages' do
|
457
421
|
shared_examples 'an Ably encrypter and decrypter' do |item, data|
|
458
422
|
let(:algorithm) { data['algorithm'].upcase }
|
@@ -622,11 +586,13 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
622
586
|
let(:payload) { MessagePack.pack({ 'key' => random_str }) }
|
623
587
|
|
624
588
|
it 'does not attempt to decrypt the message' do
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
589
|
+
wait_until(lambda { client.connection.state == :connected and other_client.connection.state == :connected }) do
|
590
|
+
encrypted_channel_client2.subscribe do |message|
|
591
|
+
expect(message.data).to eql(payload)
|
592
|
+
expect(message.encoding).to be_nil
|
593
|
+
stop_reactor
|
594
|
+
end
|
595
|
+
unencrypted_channel_client1.publish 'example', payload
|
630
596
|
end
|
631
597
|
end
|
632
598
|
end
|
@@ -671,11 +637,13 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
671
637
|
let(:payload) { MessagePack.pack({ 'key' => random_str }) }
|
672
638
|
|
673
639
|
it 'delivers the message but still encrypted with the cipher detials in the #encoding attribute (#RTL7e)' do
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
640
|
+
encrypted_channel_client2.attach do
|
641
|
+
encrypted_channel_client2.subscribe do |message|
|
642
|
+
expect(message.data).to_not eql(payload)
|
643
|
+
expect(message.encoding).to match(/^cipher\+aes-256-cbc/)
|
644
|
+
stop_reactor
|
645
|
+
end
|
646
|
+
encrypted_channel_client1.publish 'example', payload
|
679
647
|
end
|
680
648
|
end
|
681
649
|
|
@@ -751,10 +719,13 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
751
719
|
end
|
752
720
|
end
|
753
721
|
|
754
|
-
channel
|
755
|
-
|
756
|
-
|
757
|
-
|
722
|
+
# Attaching channel first before publishing message in order to get channel serial set on channel
|
723
|
+
channel.attach do
|
724
|
+
channel.publish(event_name).tap do |deferrable|
|
725
|
+
deferrable.callback { message_state << :delivered }
|
726
|
+
deferrable.errback do
|
727
|
+
raise 'Message delivery should not fail'
|
728
|
+
end
|
758
729
|
end
|
759
730
|
end
|
760
731
|
|
@@ -777,7 +748,7 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
777
748
|
if protocol_message.messages.find { |message| message.name == event_name }
|
778
749
|
EventMachine.add_timer(0.0001) do
|
779
750
|
connection.transport.unbind # trigger failure
|
780
|
-
connection.configure_new '0123456789abcdef', 'wVIsgTHAB1UvXh7z-1991d8586'
|
751
|
+
connection.configure_new '0123456789abcdef', 'wVIsgTHAB1UvXh7z-1991d8586' # force the resume connection key to be invalid
|
781
752
|
end
|
782
753
|
end
|
783
754
|
end
|