ably-rest 1.2.6 → 1.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -22,10 +22,11 @@ Gem::Specification.new do |spec|
22
22
  spec.add_runtime_dependency 'ably-em-http-request', '~> 1.1.8'
23
23
  spec.add_runtime_dependency 'statesman', '~> 9.0'
24
24
  spec.add_runtime_dependency 'faraday', '~> 2.2'
25
- spec.add_runtime_dependency 'faraday-typhoeus', '~> 0.2.0'
25
+ spec.add_runtime_dependency 'faraday-typhoeus', '~> 1.1.0'
26
26
  spec.add_runtime_dependency 'typhoeus', '~> 1.4'
27
27
  spec.add_runtime_dependency 'json'
28
- spec.add_runtime_dependency 'websocket-driver', '~> 0.7'
28
+ # We disallow minor version updates, because this gem has introduced breaking API changes in minor releases before (which it's within its rights to do, given it's pre-v1). If you want to allow a new minor version, bump here and run the tests.
29
+ spec.add_runtime_dependency 'websocket-driver', '~> 0.8.0'
29
30
  spec.add_runtime_dependency 'msgpack', '>= 1.3.0'
30
31
  spec.add_runtime_dependency 'addressable', '>= 2.0.0'
31
32
 
@@ -249,7 +249,6 @@ module Ably::Models
249
249
  # Return a JSON ready object from the underlying #attributes using Ably naming conventions for keys
250
250
  def as_json(*args)
251
251
  raise TypeError, ':action is missing, cannot generate a valid Hash for ProtocolMessage' unless action
252
- raise TypeError, ':msg_serial is missing, cannot generate a valid Hash for ProtocolMessage' if ack_required? && !has_message_serial?
253
252
 
254
253
  attributes.dup.tap do |hash_object|
255
254
  hash_object['action'] = action.to_i
@@ -257,7 +257,7 @@ module Ably::Realtime
257
257
  when :json
258
258
  JSON.parse(data)
259
259
  when :msgpack
260
- MessagePack.unpack(data.pack('C*'))
260
+ MessagePack.unpack(data)
261
261
  else
262
262
  client.logger.fatal { "WebsocketTransport: Unsupported Protocol Message format #{client.protocol}" }
263
263
  data
@@ -690,16 +690,44 @@ module Ably
690
690
  end
691
691
 
692
692
  def use_fallback_if_disconnected?
693
- second_reconnect_attempt_for(:disconnected, 1)
693
+ unless second_reconnect_attempt_for(:disconnected, 1)
694
+ return false
695
+ end
696
+
697
+ does_error_necessitate_fallback(reason_for_last_time_in(:disconnected))
694
698
  end
695
699
 
696
700
  def use_fallback_if_suspended?
697
- second_reconnect_attempt_for(:suspended, 2) # on first suspended state use default Ably host again
701
+ unless second_reconnect_attempt_for(:suspended, 2) # on first suspended state use default Ably host again
702
+ return false
703
+ end
704
+
705
+ does_error_necessitate_fallback(reason_for_last_time_in(:suspended))
698
706
  end
699
707
 
700
708
  def second_reconnect_attempt_for(state, first_attempt_count)
701
709
  previous_state == state && manager.retry_count_for_state(state) >= first_attempt_count
702
710
  end
711
+
712
+ # Provides a partial implementation of RTN17f's logic for whether an error necessitates a fallback host.
713
+ def does_error_necessitate_fallback(error)
714
+ return false unless error
715
+
716
+ # For now we just explicitly exclude token errors. TODO: implement properly in https://github.com/ably/ably-ruby/issues/444
717
+
718
+ if error.respond_to?(:status_code) && error.status_code == 401 && error.respond_to?(:code) && Ably::Exceptions::TOKEN_EXPIRED_CODE.include?(error.code)
719
+ return false
720
+ end
721
+
722
+ true
723
+ end
724
+
725
+ # Returns the error associated with the last state change to the given state (e.g. :disconnected).
726
+ def reason_for_last_time_in(state)
727
+ history_item = state_history.reverse.find do |history_item|
728
+ history_item.fetch(:state) == state
729
+ end.fetch(:metadata).reason
730
+ end
703
731
  end
704
732
  end
705
733
  end
@@ -1,5 +1,5 @@
1
1
  module Ably
2
- VERSION = '1.2.6'
2
+ VERSION = '1.2.8'
3
3
  # The level of compatibility with the Ably service that this SDK supports.
4
4
  # Also referred to as the 'wire protocol version'.
5
5
  # spec : CSV2
@@ -617,7 +617,6 @@ describe Ably::Realtime::Auth, :event_machine do
617
617
  deferrable.errback do |error|
618
618
  EventMachine.add_timer(0.2) do
619
619
  expect(connection_failed).to eql(true)
620
- expect(error.message).to match(/invalid.*accessToken/i)
621
620
  expect(error.code).to eql(40005)
622
621
  stop_reactor
623
622
  end
@@ -627,7 +626,6 @@ describe Ably::Realtime::Auth, :event_machine do
627
626
  end
628
627
 
629
628
  client.connection.once(:failed) do
630
- expect(client.connection.error_reason.message).to match(/invalid.*accessToken/i)
631
629
  expect(client.connection.error_reason.code).to eql(40005)
632
630
  connection_failed = true
633
631
  end
@@ -664,7 +662,6 @@ describe Ably::Realtime::Auth, :event_machine do
664
662
  channel.attach do
665
663
  channel.publish('not-allowed').errback do |error|
666
664
  expect(error.code).to eql(40160)
667
- expect(error.message).to match(/permission denied/)
668
665
 
669
666
  client.auth.authorize(nil, auth_callback: upgraded_token_cb)
670
667
  client.connection.once(:update) do
@@ -1058,7 +1055,6 @@ describe Ably::Realtime::Auth, :event_machine do
1058
1055
 
1059
1056
  it 'disconnected includes and invalid signature message' do
1060
1057
  client.connection.once(:disconnected) do |state_change|
1061
- expect(state_change.reason.message.match(/signature verification failed/i)).to_not be_nil
1062
1058
  expect(state_change.reason.code).to eql(40144)
1063
1059
  stop_reactor
1064
1060
  end
@@ -1111,7 +1107,6 @@ describe Ably::Realtime::Auth, :event_machine do
1111
1107
 
1112
1108
  it 'authentication fails and reason for disconnection is invalid signature' do
1113
1109
  client.connection.once(:disconnected) do |state_change|
1114
- expect(state_change.reason.message.match(/signature verification failed/i)).to_not be_nil
1115
1110
  expect(state_change.reason.code).to eql(40144)
1116
1111
  stop_reactor
1117
1112
  end
@@ -1143,7 +1138,6 @@ describe Ably::Realtime::Auth, :event_machine do
1143
1138
 
1144
1139
  it 'fails with an invalid signature error' do
1145
1140
  client.connection.once(:disconnected) do |state_change|
1146
- expect(state_change.reason.message.match(/signature verification failed/i)).to_not be_nil
1147
1141
  expect(state_change.reason.code).to eql(40144)
1148
1142
  stop_reactor
1149
1143
  end
@@ -1248,7 +1242,6 @@ describe Ably::Realtime::Auth, :event_machine do
1248
1242
  allowed_channel = client.channels.get(channel_with_publish_permissions)
1249
1243
  forbidden_channel.publish('not-allowed').errback do |error|
1250
1244
  expect(error.code).to eql(40160)
1251
- expect(error.message).to match(/permission denied/)
1252
1245
 
1253
1246
  allowed_channel.publish(message_name) do |message|
1254
1247
  expect(message.name).to eql(message_name)
@@ -34,7 +34,7 @@ describe Ably::Realtime::Client, :event_machine do
34
34
  client.connection.once(:failed) do
35
35
  expect(custom_logger_object.logs.find do |severity, message|
36
36
  next unless %w(fatal error).include?(severity.to_s)
37
- message.match(%r{https://help.ably.io/error/40400})
37
+ message.match(%r{https://help.ably.io/error/40101})
38
38
  end).to_not be_nil
39
39
  stop_reactor
40
40
  end
@@ -26,13 +26,13 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
26
26
  context 'with invalid app part of the key' do
27
27
  let(:invalid_key) { 'not_an_app.invalid_key_name:invalid_key_value' }
28
28
 
29
- it 'enters the failed state and returns a not found error' do
29
+ it 'enters the failed state and returns an invalid credentials error' do
30
30
  connection.on(:failed) do |connection_state_change|
31
31
  error = connection_state_change.reason
32
32
  expect(connection.state).to eq(:failed)
33
33
  # TODO: Check error type is an InvalidToken exception
34
- expect(error.status).to eq(404)
35
- expect(error.code).to eq(40400) # not found
34
+ expect(error.status).to eq(401)
35
+ expect(error.code).to eq(40101) # invalid credentials
36
36
  stop_reactor
37
37
  end
38
38
  end
@@ -46,7 +46,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
46
46
  error = connection_state_change.reason
47
47
  expect(connection.state).to eq(:failed)
48
48
  # TODO: Check error type is a TokenNotFound exception
49
- expect(error.status).to eq(401)
49
+ expect(error.status).to eq(404)
50
50
  expect(error.code).to eq(40400) # not found
51
51
  stop_reactor
52
52
  end
@@ -1396,10 +1396,10 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
1396
1396
  channel = client.channels.get("foo")
1397
1397
  channel.attach do
1398
1398
  connection.once(:failed) do |state_change|
1399
- expect(state_change.reason.code).to eql(40400)
1400
- expect(connection.error_reason.code).to eql(40400)
1399
+ expect(state_change.reason.code).to eql(40101)
1400
+ expect(connection.error_reason.code).to eql(40101)
1401
1401
  expect(channel).to be_failed
1402
- expect(channel.error_reason.code).to eql(40400)
1402
+ expect(channel.error_reason.code).to eql(40101)
1403
1403
  stop_reactor
1404
1404
  end
1405
1405
 
@@ -173,7 +173,7 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
173
173
  end
174
174
 
175
175
  context 'JSON Array' do
176
- let(:data) { { 'push' => { 'data' => { 'key' => [ true, false, 55, nil, 'string', { 'Hash' => true }, ['array'] ] } } } }
176
+ let(:data) { { 'push' => { 'data' => { 'key' => [ true, false, 55.1, nil, 'string', { 'Hash' => true }, ['array'] ] } } } }
177
177
 
178
178
  it 'is encoded and decoded to the same Array' do
179
179
  publish_and_check_extras data
@@ -72,13 +72,12 @@ describe Ably::Rest do
72
72
 
73
73
  describe 'failed requests' do
74
74
  context 'due to invalid Auth' do
75
- it 'should raise an InvalidRequest exception with a valid error message and code' do
75
+ it 'should raise an UnauthorizedRequest exception with a valid error message and code' do
76
76
  invalid_client = Ably::Rest::Client.new(key: 'appid.keyuid:keysecret', environment: environment)
77
77
  expect { invalid_client.channel('test').publish('foo', 'choo') }.to raise_error do |error|
78
- expect(error).to be_a(Ably::Exceptions::ResourceMissing)
79
- expect(error.message).to match(/No application found/)
80
- expect(error.code).to eql(40400)
81
- expect(error.status).to eql(404)
78
+ expect(error).to be_a(Ably::Exceptions::UnauthorizedRequest)
79
+ expect(error.code).to eql(40101)
80
+ expect(error.status).to eql(401)
82
81
  end
83
82
  end
84
83
  end
@@ -33,9 +33,9 @@ describe Ably::Rest::Client do
33
33
  it 'logs an entry with a help href url matching the code #TI5' do
34
34
  begin
35
35
  client.channels.get('foo').publish('test')
36
- raise 'Expected Ably::Exceptions::ResourceMissing'
37
- rescue Ably::Exceptions::ResourceMissing => err
38
- expect err.to_s.match(%r{https://help.ably.io/error/40400})
36
+ raise 'Expected Ably::Exceptions::UnauthorizedRequest'
37
+ rescue Ably::Exceptions::UnauthorizedRequest => err
38
+ expect err.to_s.match(%r{https://help.ably.io/error/40101})
39
39
  end
40
40
  end
41
41
  end
@@ -397,14 +397,6 @@ describe Ably::Models::ProtocolMessage do
397
397
  end
398
398
  end
399
399
 
400
- context 'with missing msg_serial for ack message' do
401
- let(:model) { new_protocol_message({ :action => message_action }) }
402
-
403
- it 'it raises an exception' do
404
- expect { model.to_json }.to raise_error TypeError, /msg_serial.*missing/
405
- end
406
- end
407
-
408
400
  context 'is aliased by #to_s' do
409
401
  let(:model) { new_protocol_message({ :action => attached_action, :channelSerial => 'unique', messages: [message1, message2, message3], :timestamp => as_since_epoch(Time.now) }) }
410
402
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ably-rest
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.6
4
+ version: 1.2.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew O'Riordan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-08 00:00:00.000000000 Z
11
+ date: 2025-06-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.2'
27
- - !ruby/object:Gem::Dependency
28
- name: excon
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '0.55'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '0.55'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: typhoeus
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -58,14 +44,14 @@ dependencies:
58
44
  requirements:
59
45
  - - "~>"
60
46
  - !ruby/object:Gem::Version
61
- version: 0.2.0
47
+ version: 1.1.0
62
48
  type: :runtime
63
49
  prerelease: false
64
50
  version_requirements: !ruby/object:Gem::Requirement
65
51
  requirements:
66
52
  - - "~>"
67
53
  - !ruby/object:Gem::Version
68
- version: 0.2.0
54
+ version: 1.1.0
69
55
  - !ruby/object:Gem::Dependency
70
56
  name: json
71
57
  requirement: !ruby/object:Gem::Requirement
@@ -86,20 +72,14 @@ dependencies:
86
72
  requirements:
87
73
  - - ">="
88
74
  - !ruby/object:Gem::Version
89
- version: 1.5.2
90
- - - "<"
91
- - !ruby/object:Gem::Version
92
- version: '2.0'
75
+ version: 1.3.0
93
76
  type: :runtime
94
77
  prerelease: false
95
78
  version_requirements: !ruby/object:Gem::Requirement
96
79
  requirements:
97
80
  - - ">="
98
81
  - !ruby/object:Gem::Version
99
- version: 1.5.2
100
- - - "<"
101
- - !ruby/object:Gem::Version
102
- version: '2.0'
82
+ version: 1.3.0
103
83
  - !ruby/object:Gem::Dependency
104
84
  name: addressable
105
85
  requirement: !ruby/object:Gem::Requirement
@@ -134,14 +114,14 @@ dependencies:
134
114
  requirements:
135
115
  - - "~>"
136
116
  - !ruby/object:Gem::Version
137
- version: 13.0.6
117
+ version: '13.0'
138
118
  type: :development
139
119
  prerelease: false
140
120
  version_requirements: !ruby/object:Gem::Requirement
141
121
  requirements:
142
122
  - - "~>"
143
123
  - !ruby/object:Gem::Version
144
- version: 13.0.6
124
+ version: '13.0'
145
125
  - !ruby/object:Gem::Dependency
146
126
  name: redcarpet
147
127
  requirement: !ruby/object:Gem::Requirement
@@ -162,28 +142,28 @@ dependencies:
162
142
  requirements:
163
143
  - - "~>"
164
144
  - !ruby/object:Gem::Version
165
- version: '3.11'
145
+ version: 3.11.0
166
146
  type: :development
167
147
  prerelease: false
168
148
  version_requirements: !ruby/object:Gem::Requirement
169
149
  requirements:
170
150
  - - "~>"
171
151
  - !ruby/object:Gem::Version
172
- version: '3.11'
152
+ version: 3.11.0
173
153
  - !ruby/object:Gem::Dependency
174
154
  name: rspec-retry
175
155
  requirement: !ruby/object:Gem::Requirement
176
156
  requirements:
177
157
  - - "~>"
178
158
  - !ruby/object:Gem::Version
179
- version: 0.6.2
159
+ version: '0.6'
180
160
  type: :development
181
161
  prerelease: false
182
162
  version_requirements: !ruby/object:Gem::Requirement
183
163
  requirements:
184
164
  - - "~>"
185
165
  - !ruby/object:Gem::Version
186
- version: 0.6.2
166
+ version: '0.6'
187
167
  - !ruby/object:Gem::Dependency
188
168
  name: yard
189
169
  requirement: !ruby/object:Gem::Requirement
@@ -204,28 +184,14 @@ dependencies:
204
184
  requirements:
205
185
  - - "~>"
206
186
  - !ruby/object:Gem::Version
207
- version: 3.14.0
187
+ version: '3.11'
208
188
  type: :development
209
189
  prerelease: false
210
190
  version_requirements: !ruby/object:Gem::Requirement
211
191
  requirements:
212
192
  - - "~>"
213
193
  - !ruby/object:Gem::Version
214
- version: 3.14.0
215
- - !ruby/object:Gem::Dependency
216
- name: coveralls
217
- requirement: !ruby/object:Gem::Requirement
218
- requirements:
219
- - - ">="
220
- - !ruby/object:Gem::Version
221
- version: '0'
222
- type: :development
223
- prerelease: false
224
- version_requirements: !ruby/object:Gem::Requirement
225
- requirements:
226
- - - ">="
227
- - !ruby/object:Gem::Version
228
- version: '0'
194
+ version: '3.11'
229
195
  - !ruby/object:Gem::Dependency
230
196
  name: pry
231
197
  requirement: !ruby/object:Gem::Requirement
@@ -244,16 +210,16 @@ dependencies:
244
210
  name: pry-byebug
245
211
  requirement: !ruby/object:Gem::Requirement
246
212
  requirements:
247
- - - ">="
213
+ - - "~>"
248
214
  - !ruby/object:Gem::Version
249
- version: '0'
215
+ version: 3.8.0
250
216
  type: :development
251
217
  prerelease: false
252
218
  version_requirements: !ruby/object:Gem::Requirement
253
219
  requirements:
254
- - - ">="
220
+ - - "~>"
255
221
  - !ruby/object:Gem::Version
256
- version: '0'
222
+ version: 3.8.0
257
223
  - !ruby/object:Gem::Dependency
258
224
  name: webrick
259
225
  requirement: !ruby/object:Gem::Requirement
@@ -536,7 +502,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
536
502
  - !ruby/object:Gem::Version
537
503
  version: '0'
538
504
  requirements: []
539
- rubygems_version: 3.5.4
505
+ rubygems_version: 3.3.7
540
506
  signing_key:
541
507
  specification_version: 4
542
508
  summary: A Ruby REST only client library for ably.io realtime messaging