ably-rest 1.1.2 → 1.2.2
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.
- checksums.yaml +4 -4
- data/.travis.yml +3 -0
- data/CHANGELOG.md +1 -1
- data/MAINTAINERS.md +1 -0
- data/README.md +4 -2
- data/ably-rest.gemspec +15 -18
- data/lib/ably-rest.rb +2 -0
- data/lib/submodules/ably-ruby/.github/workflows/check.yml +50 -0
- data/lib/submodules/ably-ruby/CHANGELOG.md +200 -0
- data/lib/submodules/ably-ruby/COPYRIGHT +1 -0
- data/lib/submodules/ably-ruby/LICENSE +172 -11
- data/lib/submodules/ably-ruby/MAINTAINERS.md +1 -0
- data/lib/submodules/ably-ruby/README.md +24 -22
- data/lib/submodules/ably-ruby/SPEC.md +1020 -929
- data/lib/submodules/ably-ruby/UPDATING.md +30 -0
- data/lib/submodules/ably-ruby/ably.gemspec +16 -23
- data/lib/submodules/ably-ruby/lib/ably/agent.rb +3 -0
- data/lib/submodules/ably-ruby/lib/ably/auth.rb +20 -10
- data/lib/submodules/ably-ruby/lib/ably/exceptions.rb +8 -2
- data/lib/submodules/ably-ruby/lib/ably/logger.rb +4 -4
- data/lib/submodules/ably-ruby/lib/ably/models/channel_details.rb +59 -0
- data/lib/submodules/ably-ruby/lib/ably/models/channel_metrics.rb +84 -0
- data/lib/submodules/ably-ruby/lib/ably/models/channel_occupancy.rb +43 -0
- data/lib/submodules/ably-ruby/lib/ably/models/channel_options.rb +97 -0
- data/lib/submodules/ably-ruby/lib/ably/models/channel_status.rb +53 -0
- data/lib/submodules/ably-ruby/lib/ably/models/connection_details.rb +8 -0
- data/lib/submodules/ably-ruby/lib/ably/models/delta_extras.rb +29 -0
- data/lib/submodules/ably-ruby/lib/ably/models/device_details.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/models/error_info.rb +6 -2
- data/lib/submodules/ably-ruby/lib/ably/models/idiomatic_ruby_wrapper.rb +4 -0
- data/lib/submodules/ably-ruby/lib/ably/models/message.rb +28 -3
- data/lib/submodules/ably-ruby/lib/ably/models/presence_message.rb +14 -0
- data/lib/submodules/ably-ruby/lib/ably/models/protocol_message.rb +31 -14
- data/lib/submodules/ably-ruby/lib/ably/models/token_details.rb +7 -2
- data/lib/submodules/ably-ruby/lib/ably/models/token_request.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/modules/ably.rb +11 -1
- data/lib/submodules/ably-ruby/lib/ably/modules/channels_collection.rb +22 -2
- data/lib/submodules/ably-ruby/lib/ably/modules/conversions.rb +34 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/auth.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +19 -7
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_properties.rb +24 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_state_machine.rb +10 -1
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/publisher.rb +6 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +56 -28
- data/lib/submodules/ably-ruby/lib/ably/realtime/channels.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/realtime/client/incoming_message_dispatcher.rb +14 -6
- data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +9 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +13 -4
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_state_machine.rb +4 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/websocket_transport.rb +67 -1
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +6 -5
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence.rb +0 -14
- data/lib/submodules/ably-ruby/lib/ably/rest/channel.rb +44 -29
- data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +60 -29
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/encoder.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/exceptions.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/external_exceptions.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/fail_if_unsupported_mime_type.rb +5 -2
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/logger.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/parse_json.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/parse_message_pack.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/util/crypto.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/version.rb +2 -14
- data/lib/submodules/ably-ruby/lib/ably.rb +1 -0
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/auth_spec.rb +4 -4
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_history_spec.rb +25 -0
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +476 -21
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channels_spec.rb +59 -7
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +72 -16
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +85 -13
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +301 -34
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +77 -0
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_history_spec.rb +3 -59
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +84 -158
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/push_admin_spec.rb +3 -19
- data/lib/submodules/ably-ruby/spec/acceptance/rest/auth_spec.rb +24 -75
- data/lib/submodules/ably-ruby/spec/acceptance/rest/base_spec.rb +8 -4
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +141 -10
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channels_spec.rb +23 -6
- data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +146 -47
- data/lib/submodules/ably-ruby/spec/acceptance/rest/message_spec.rb +61 -3
- data/lib/submodules/ably-ruby/spec/acceptance/rest/push_admin_spec.rb +3 -19
- data/lib/submodules/ably-ruby/spec/lib/unit/models/channel_options_spec.rb +52 -0
- data/lib/submodules/ably-ruby/spec/run_parallel_tests +2 -7
- data/lib/submodules/ably-ruby/spec/shared/client_initializer_behaviour.rb +131 -8
- data/lib/submodules/ably-ruby/spec/shared/model_behaviour.rb +1 -1
- data/lib/submodules/ably-ruby/spec/spec_helper.rb +12 -2
- data/lib/submodules/ably-ruby/spec/support/serialization_helper.rb +21 -0
- data/lib/submodules/ably-ruby/spec/support/test_app.rb +3 -3
- data/lib/submodules/ably-ruby/spec/unit/logger_spec.rb +6 -14
- data/lib/submodules/ably-ruby/spec/unit/models/channel_details_spec.rb +30 -0
- data/lib/submodules/ably-ruby/spec/unit/models/channel_metrics_spec.rb +42 -0
- data/lib/submodules/ably-ruby/spec/unit/models/channel_occupancy_spec.rb +17 -0
- data/lib/submodules/ably-ruby/spec/unit/models/channel_status_spec.rb +36 -0
- data/lib/submodules/ably-ruby/spec/unit/models/delta_extras_spec.rb +14 -0
- data/lib/submodules/ably-ruby/spec/unit/models/error_info_spec.rb +17 -1
- data/lib/submodules/ably-ruby/spec/unit/models/message_spec.rb +97 -0
- data/lib/submodules/ably-ruby/spec/unit/models/presence_message_spec.rb +49 -0
- data/lib/submodules/ably-ruby/spec/unit/models/protocol_message_spec.rb +125 -27
- data/lib/submodules/ably-ruby/spec/unit/models/token_details_spec.rb +14 -0
- data/lib/submodules/ably-ruby/spec/unit/realtime/channel_spec.rb +3 -2
- data/lib/submodules/ably-ruby/spec/unit/realtime/channels_spec.rb +53 -15
- data/lib/submodules/ably-ruby/spec/unit/realtime/client_spec.rb +19 -6
- data/lib/submodules/ably-ruby/spec/unit/realtime/incoming_message_dispatcher_spec.rb +38 -0
- data/lib/submodules/ably-ruby/spec/unit/rest/channel_spec.rb +44 -1
- data/lib/submodules/ably-ruby/spec/unit/rest/channels_spec.rb +81 -14
- data/lib/submodules/ably-ruby/spec/unit/rest/client_spec.rb +47 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/unit/client_spec.rb +30 -0
- metadata +88 -25
- data/lib/submodules/ably-ruby/.travis.yml +0 -19
|
@@ -121,15 +121,23 @@ module Ably::Realtime
|
|
|
121
121
|
presence.manager.sync_process_messages protocol_message.channel_serial, protocol_message.presence
|
|
122
122
|
|
|
123
123
|
when ACTION.Presence
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
presence.
|
|
124
|
+
if protocol_message.has_correct_message_size?
|
|
125
|
+
presence = get_channel(protocol_message.channel).presence
|
|
126
|
+
protocol_message.presence.each do |presence_message|
|
|
127
|
+
presence.__incoming_msgbus__.publish :presence, presence_message
|
|
128
|
+
end
|
|
129
|
+
else
|
|
130
|
+
logger.fatal Ably::Exceptions::ProtocolError.new("Not published. Channel message limit exceeded #{protocol_message.message_size} bytes", 400, Ably::Exceptions::Codes::UNABLE_TO_RECOVER_CHANNEL_MESSAGE_LIMIT_EXCEEDED).message
|
|
127
131
|
end
|
|
128
132
|
|
|
129
133
|
when ACTION.Message
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
134
|
+
if protocol_message.has_correct_message_size?
|
|
135
|
+
channel = get_channel(protocol_message.channel)
|
|
136
|
+
protocol_message.messages.each do |message|
|
|
137
|
+
channel.__incoming_msgbus__.publish :message, message
|
|
138
|
+
end
|
|
139
|
+
else
|
|
140
|
+
logger.fatal Ably::Exceptions::ProtocolError.new("Not published. Channel message limit exceeded #{protocol_message.message_size} bytes", 400, Ably::Exceptions::Codes::UNABLE_TO_RECOVER_CHANNEL_MESSAGE_LIMIT_EXCEEDED).message
|
|
133
141
|
end
|
|
134
142
|
|
|
135
143
|
when ACTION.Auth
|
|
@@ -65,11 +65,16 @@ module Ably
|
|
|
65
65
|
# @return [String,Nil]
|
|
66
66
|
attr_reader :recover
|
|
67
67
|
|
|
68
|
+
# Additional parameters to be sent in the querystring when initiating a realtime connection
|
|
69
|
+
# @return [Hash]
|
|
70
|
+
attr_reader :transport_params
|
|
71
|
+
|
|
68
72
|
def_delegators :auth, :client_id, :auth_options
|
|
69
73
|
def_delegators :@rest_client, :encoders
|
|
70
74
|
def_delegators :@rest_client, :use_tls?, :protocol, :protocol_binary?
|
|
71
75
|
def_delegators :@rest_client, :environment, :custom_host, :custom_port, :custom_tls_port
|
|
72
76
|
def_delegators :@rest_client, :log_level
|
|
77
|
+
def_delegators :@rest_client, :options
|
|
73
78
|
|
|
74
79
|
# Creates a {Ably::Realtime::Client Realtime Client} and configures the {Ably::Auth} object for the connection.
|
|
75
80
|
#
|
|
@@ -82,6 +87,7 @@ module Ably
|
|
|
82
87
|
# @option options [Boolean] :echo_messages If false, prevents messages originating from this connection being echoed back on the same connection
|
|
83
88
|
# @option options [String] :recover When a recover option is specified a connection inherits the state of a previous connection that may have existed under a different instance of the Realtime library, please refer to the API documentation for further information on connection state recovery
|
|
84
89
|
# @option options [Boolean] :auto_connect By default as soon as the client library is instantiated it will connect to Ably. You can optionally set this to false and explicitly connect.
|
|
90
|
+
# @option options [Hash] :transport_params Additional parameters to be sent in the querystring when initiating a realtime connection. Keys are Strings, values are Stringifiable(a value must respond to #to_s)
|
|
85
91
|
#
|
|
86
92
|
# @option options [Integer] :channel_retry_timeout (15 seconds). When a channel becomes SUSPENDED, after this delay in seconds, the channel will automatically attempt to reattach if the connection is CONNECTED
|
|
87
93
|
# @option options [Integer] :disconnected_retry_timeout (15 seconds). When the connection enters the DISCONNECTED state, after this delay in seconds, if the state is still DISCONNECTED, the client library will attempt to reconnect automatically
|
|
@@ -109,6 +115,9 @@ module Ably
|
|
|
109
115
|
end
|
|
110
116
|
end
|
|
111
117
|
|
|
118
|
+
@transport_params = options.delete(:transport_params).to_h.each_with_object({}) do |(key, value), acc|
|
|
119
|
+
acc[key.to_s] = value.to_s
|
|
120
|
+
end
|
|
112
121
|
@rest_client = Ably::Rest::Client.new(options.merge(realtime_client: self))
|
|
113
122
|
@echo_messages = rest_client.options.fetch(:echo_messages, true) == false ? false : true
|
|
114
123
|
@queue_messages = rest_client.options.fetch(:queue_messages, true) == false ? false : true
|
|
@@ -117,17 +117,17 @@ module Ably::Realtime
|
|
|
117
117
|
EventMachine.next_tick { connection.trigger_resumed }
|
|
118
118
|
resend_pending_message_ack_queue
|
|
119
119
|
else
|
|
120
|
-
logger.debug { "ConnectionManager: Connection was not resumed, old connection ID #{connection.id} has been updated with new connection ID #{protocol_message.connection_id} and key #{protocol_message.connection_key}" }
|
|
120
|
+
logger.debug { "ConnectionManager: Connection was not resumed, old connection ID #{connection.id} has been updated with new connection ID #{protocol_message.connection_id} and key #{protocol_message.connection_details.connection_key}" }
|
|
121
121
|
nack_messages_on_all_channels protocol_message.error
|
|
122
122
|
force_reattach_on_channels protocol_message.error
|
|
123
123
|
end
|
|
124
124
|
else
|
|
125
|
-
logger.debug { "ConnectionManager: New connection created with ID #{protocol_message.connection_id} and key #{protocol_message.connection_key}" }
|
|
125
|
+
logger.debug { "ConnectionManager: New connection created with ID #{protocol_message.connection_id} and key #{protocol_message.connection_details.connection_key}" }
|
|
126
126
|
end
|
|
127
127
|
|
|
128
128
|
reattach_suspended_channels protocol_message.error
|
|
129
129
|
|
|
130
|
-
connection.configure_new protocol_message.connection_id, protocol_message.connection_key, protocol_message.connection_serial
|
|
130
|
+
connection.configure_new protocol_message.connection_id, protocol_message.connection_details.connection_key, protocol_message.connection_serial
|
|
131
131
|
end
|
|
132
132
|
|
|
133
133
|
# When connection is CONNECTED and receives an update
|
|
@@ -139,7 +139,7 @@ module Ably::Realtime
|
|
|
139
139
|
# Update the connection details and any associated defaults
|
|
140
140
|
connection.set_connection_details protocol_message.connection_details
|
|
141
141
|
|
|
142
|
-
connection.configure_new protocol_message.connection_id, protocol_message.connection_key, protocol_message.connection_serial
|
|
142
|
+
connection.configure_new protocol_message.connection_id, protocol_message.connection_details.connection_key, protocol_message.connection_serial
|
|
143
143
|
|
|
144
144
|
state_change = Ably::Models::ConnectionStateChange.new(
|
|
145
145
|
current: connection.state,
|
|
@@ -319,6 +319,15 @@ module Ably::Realtime
|
|
|
319
319
|
end
|
|
320
320
|
end
|
|
321
321
|
|
|
322
|
+
# @api private
|
|
323
|
+
def reintialize_failed_chanels
|
|
324
|
+
channels.select do |channel|
|
|
325
|
+
channel.failed?
|
|
326
|
+
end.each do |channel|
|
|
327
|
+
channel.transition_state_machine :initialized
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
|
|
322
331
|
# When continuity on a connection is lost all messages
|
|
323
332
|
# whether queued or awaiting an ACK must be NACK'd as we now have a new connection
|
|
324
333
|
def nack_messages_on_all_channels(error)
|
|
@@ -36,6 +36,10 @@ module Ably::Realtime
|
|
|
36
36
|
connection.manager.setup_transport
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
+
after_transition(to: [:connecting], from: [:failed]) do |connection|
|
|
40
|
+
connection.manager.reintialize_failed_chanels
|
|
41
|
+
end
|
|
42
|
+
|
|
39
43
|
after_transition(to: [:connecting], from: [:disconnected, :suspended]) do |connection|
|
|
40
44
|
connection.manager.reconnect_transport
|
|
41
45
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require 'openssl'
|
|
2
|
+
|
|
1
3
|
module Ably::Realtime
|
|
2
4
|
class Connection
|
|
3
5
|
# EventMachine WebSocket transport
|
|
@@ -16,10 +18,13 @@ module Ably::Realtime
|
|
|
16
18
|
)
|
|
17
19
|
include Ably::Modules::StateEmitter
|
|
18
20
|
|
|
21
|
+
attr_reader :host
|
|
22
|
+
|
|
19
23
|
def initialize(connection, url)
|
|
20
24
|
@connection = connection
|
|
21
25
|
@state = STATE.Initialized
|
|
22
26
|
@url = url
|
|
27
|
+
@host = URI.parse(url).hostname
|
|
23
28
|
|
|
24
29
|
setup_event_handlers
|
|
25
30
|
end
|
|
@@ -49,7 +54,7 @@ module Ably::Realtime
|
|
|
49
54
|
# Required {http://www.rubydoc.info/github/eventmachine/eventmachine/EventMachine/Connection EventMachine::Connection} interface
|
|
50
55
|
def connection_completed
|
|
51
56
|
change_state STATE.Connected
|
|
52
|
-
start_tls if client.use_tls?
|
|
57
|
+
start_tls(tls_opts) if client.use_tls?
|
|
53
58
|
driver.start
|
|
54
59
|
end
|
|
55
60
|
|
|
@@ -77,6 +82,51 @@ module Ably::Realtime
|
|
|
77
82
|
send_data(data)
|
|
78
83
|
end
|
|
79
84
|
|
|
85
|
+
# TLS verification support, original implementation by Mislav Marohnić:
|
|
86
|
+
#
|
|
87
|
+
# https://github.com/lostisland/faraday/commit/63cf47c95b573539f047c729bd9ad67560bc83ff
|
|
88
|
+
def ssl_verify_peer(cert_string)
|
|
89
|
+
cert = nil
|
|
90
|
+
begin
|
|
91
|
+
cert = OpenSSL::X509::Certificate.new(cert_string)
|
|
92
|
+
rescue OpenSSL::X509::CertificateError => e
|
|
93
|
+
disconnect_with_reason "Websocket host '#{host}' returned an invalid TLS certificate: #{e.message}"
|
|
94
|
+
return false
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
@last_seen_cert = cert
|
|
98
|
+
|
|
99
|
+
if certificate_store.verify(@last_seen_cert)
|
|
100
|
+
begin
|
|
101
|
+
certificate_store.add_cert(@last_seen_cert)
|
|
102
|
+
rescue OpenSSL::X509::StoreError => e
|
|
103
|
+
unless e.message == 'cert already in hash table'
|
|
104
|
+
disconnect_with_reason "Websocket host '#{host}' returned an invalid TLS certificate: #{e.message}"
|
|
105
|
+
return false
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
true
|
|
109
|
+
else
|
|
110
|
+
disconnect_with_reason "Websocket host '#{host}' returned an invalid TLS certificate"
|
|
111
|
+
false
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def ssl_handshake_completed
|
|
116
|
+
unless OpenSSL::SSL.verify_certificate_identity(@last_seen_cert, host)
|
|
117
|
+
disconnect_with_reason "Websocket host '#{host}' returned an invalid TLS certificate"
|
|
118
|
+
false
|
|
119
|
+
else
|
|
120
|
+
true
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def certificate_store
|
|
125
|
+
@certificate_store ||= OpenSSL::X509::Store.new.tap do |store|
|
|
126
|
+
store.set_default_paths
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
80
130
|
# True if socket connection is ready to be released
|
|
81
131
|
# i.e. it is not currently connecting or connected
|
|
82
132
|
def ready_for_release?
|
|
@@ -106,6 +156,12 @@ module Ably::Realtime
|
|
|
106
156
|
@connection
|
|
107
157
|
end
|
|
108
158
|
|
|
159
|
+
def disconnect_with_reason(reason)
|
|
160
|
+
client.logger.error { "WebsocketTransport: Disconnecting due to error: #{reason}" }
|
|
161
|
+
@reason_closed = reason
|
|
162
|
+
disconnect
|
|
163
|
+
end
|
|
164
|
+
|
|
109
165
|
def reason_closed
|
|
110
166
|
@reason_closed
|
|
111
167
|
end
|
|
@@ -214,6 +270,16 @@ module Ably::Realtime
|
|
|
214
270
|
end
|
|
215
271
|
)
|
|
216
272
|
end
|
|
273
|
+
|
|
274
|
+
# TLS options to pass to EventMachine::Connection#start_tls
|
|
275
|
+
#
|
|
276
|
+
# See https://www.rubydoc.info/github/eventmachine/eventmachine/EventMachine/Connection#start_tls-instance_method
|
|
277
|
+
def tls_opts
|
|
278
|
+
{
|
|
279
|
+
sni_hostname: host,
|
|
280
|
+
verify_peer: true,
|
|
281
|
+
}
|
|
282
|
+
end
|
|
217
283
|
end
|
|
218
284
|
end
|
|
219
285
|
end
|
|
@@ -292,7 +292,7 @@ module Ably
|
|
|
292
292
|
def internet_up?
|
|
293
293
|
url = "http#{'s' if client.use_tls?}:#{Ably::INTERNET_CHECK.fetch(:url)}"
|
|
294
294
|
EventMachine::DefaultDeferrable.new.tap do |deferrable|
|
|
295
|
-
EventMachine::HttpRequest.new(url).get.tap do |http|
|
|
295
|
+
EventMachine::HttpRequest.new(url, tls: { verify_peer: true }).get.tap do |http|
|
|
296
296
|
http.errback do
|
|
297
297
|
yield false if block_given?
|
|
298
298
|
deferrable.fail Ably::Exceptions::ConnectionFailed.new("Unable to connect to #{url}", nil, Ably::Exceptions::Codes::CONNECTION_FAILED)
|
|
@@ -431,10 +431,10 @@ module Ably
|
|
|
431
431
|
client.auth.auth_params.tap do |auth_deferrable|
|
|
432
432
|
auth_deferrable.callback do |auth_params|
|
|
433
433
|
url_params = auth_params.merge(
|
|
434
|
-
format
|
|
435
|
-
echo
|
|
436
|
-
v
|
|
437
|
-
|
|
434
|
+
'format' => client.protocol,
|
|
435
|
+
'echo' => client.echo_messages,
|
|
436
|
+
'v' => Ably::PROTOCOL_VERSION,
|
|
437
|
+
'agent' => client.rest_client.agent
|
|
438
438
|
)
|
|
439
439
|
|
|
440
440
|
# Use native websocket heartbeats if possible, but allow Ably protocol heartbeats
|
|
@@ -445,6 +445,7 @@ module Ably
|
|
|
445
445
|
end
|
|
446
446
|
|
|
447
447
|
url_params['clientId'] = client.auth.client_id if client.auth.has_client_id?
|
|
448
|
+
url_params.merge!(client.transport_params)
|
|
448
449
|
|
|
449
450
|
if connection_resumable?
|
|
450
451
|
url_params.merge! resume: key, connection_serial: serial
|
|
@@ -278,28 +278,14 @@ module Ably::Realtime
|
|
|
278
278
|
|
|
279
279
|
# Return the presence messages history for the channel
|
|
280
280
|
#
|
|
281
|
-
# Once attached to a channel, you can retrieve presence message history on the channel before the
|
|
282
|
-
# channel was attached with the option <tt>until_attach: true</tt>. This is very useful for
|
|
283
|
-
# developers who wish to capture new presence events as well as retrieve historical presence state with
|
|
284
|
-
# the guarantee that no presence history has been missed.
|
|
285
|
-
#
|
|
286
281
|
# @param (see Ably::Rest::Presence#history)
|
|
287
282
|
# @option options (see Ably::Rest::Presence#history)
|
|
288
|
-
# @option options [Boolean] :until_attach When true, request for history will be limited only to messages published before the associated channel was attached. The associated channel must be attached.
|
|
289
283
|
#
|
|
290
284
|
# @yield [Ably::Models::PaginatedResult<Ably::Models::PresenceMessage>] First {Ably::Models::PaginatedResult page} of {Ably::Models::PresenceMessage} objects accessible with {Ably::Models::PaginatedResult#items #items}.
|
|
291
285
|
#
|
|
292
286
|
# @return [Ably::Util::SafeDeferrable]
|
|
293
287
|
#
|
|
294
288
|
def history(options = {}, &callback)
|
|
295
|
-
if options.delete(:until_attach)
|
|
296
|
-
unless channel.attached?
|
|
297
|
-
error = Ably::Exceptions::InvalidRequest.new('option :until_attach is invalid as the channel is not attached')
|
|
298
|
-
return Ably::Util::SafeDeferrable.new_and_fail_immediately(logger, error)
|
|
299
|
-
end
|
|
300
|
-
options[:from_serial] = channel.attached_serial
|
|
301
|
-
end
|
|
302
|
-
|
|
303
289
|
async_wrap(callback) do
|
|
304
290
|
rest_presence.history(options.merge(async_blocking_operations: true))
|
|
305
291
|
end
|
|
@@ -28,57 +28,60 @@ module Ably
|
|
|
28
28
|
#
|
|
29
29
|
# @param client [Ably::Rest::Client]
|
|
30
30
|
# @param name [String] The name of the channel
|
|
31
|
-
# @param channel_options [Hash]
|
|
32
|
-
# @option channel_options [Hash,Ably::Models::CipherParams] :cipher A hash of options or a {Ably::Models::CipherParams} to configure the encryption. *:key* is required, all other options are optional. See {Ably::Util::Crypto#initialize} for a list of +:cipher+ options
|
|
31
|
+
# @param channel_options [Hash, Ably::Models::ChannelOptions] A hash of options or a {Ably::Models::ChannelOptions}
|
|
33
32
|
#
|
|
34
33
|
def initialize(client, name, channel_options = {})
|
|
35
34
|
name = (ensure_utf_8 :name, name)
|
|
36
35
|
|
|
37
|
-
|
|
36
|
+
@options = Ably::Models::ChannelOptions(channel_options)
|
|
38
37
|
@client = client
|
|
39
38
|
@name = name
|
|
40
39
|
@push = PushChannel.new(self)
|
|
41
40
|
end
|
|
42
41
|
|
|
43
|
-
# Publish one or more messages to the channel.
|
|
44
|
-
#
|
|
45
|
-
# @param
|
|
46
|
-
# @param
|
|
47
|
-
# @param attributes [Hash, nil] Optional additional message attributes such as :extras, :id, :client_id or :connection_id, applied when name attribute is nil or a string
|
|
42
|
+
# Publish one or more messages to the channel. Five overloaded forms
|
|
43
|
+
# @param name [String, Array<Ably::Models::Message|Hash>, Ably::Models::Message, nil] The event name of the message to publish, or an Array of [Ably::Model::Message] objects or [Hash] objects with +:name+ and +:data+ pairs, or a single Ably::Model::Message object
|
|
44
|
+
# @param data [String, Array, Hash, nil] The message payload unless an Array of [Ably::Model::Message] objects passed in the first argument, in which case an optional hash of query parameters
|
|
45
|
+
# @param attributes [Hash, nil] Optional additional message attributes such as :extras, :id, :client_id or :connection_id, applied when name attribute is nil or a string (Deprecated, will be removed in 2.0 in favour of constructing a Message object)
|
|
48
46
|
# @return [Boolean] true if the message was published, otherwise false
|
|
49
47
|
#
|
|
50
48
|
# @example
|
|
51
|
-
# # Publish a single message
|
|
49
|
+
# # Publish a single message with (name, data) form
|
|
52
50
|
# channel.publish 'click', { x: 1, y: 2 }
|
|
53
51
|
#
|
|
54
|
-
# # Publish
|
|
52
|
+
# # Publish a single message with single Hash form
|
|
53
|
+
# message = { name: 'click', data: { x: 1, y: 2 } }
|
|
54
|
+
# channel.publish message
|
|
55
|
+
#
|
|
56
|
+
# # Publish an array of message Hashes form
|
|
55
57
|
# messages = [
|
|
56
|
-
# { name: 'click', { x: 1, y: 2 } },
|
|
57
|
-
# { name: 'click', { x: 2, y: 3 } }
|
|
58
|
+
# { name: 'click', data: { x: 1, y: 2 } },
|
|
59
|
+
# { name: 'click', data: { x: 2, y: 3 } }
|
|
58
60
|
# ]
|
|
59
61
|
# channel.publish messages
|
|
60
62
|
#
|
|
61
|
-
# # Publish an array of Ably::Models::Message objects
|
|
63
|
+
# # Publish an array of Ably::Models::Message objects form
|
|
62
64
|
# messages = [
|
|
63
|
-
# Ably::Models::Message(name: 'click', { x: 1, y: 2 })
|
|
64
|
-
# Ably::Models::Message(name: 'click', { x: 2, y: 3 })
|
|
65
|
+
# Ably::Models::Message(name: 'click', data: { x: 1, y: 2 })
|
|
66
|
+
# Ably::Models::Message(name: 'click', data: { x: 2, y: 3 })
|
|
65
67
|
# ]
|
|
66
68
|
# channel.publish messages
|
|
67
69
|
#
|
|
70
|
+
# # Publish a single Ably::Models::Message object form
|
|
71
|
+
# message = Ably::Models::Message(name: 'click', data: { x: 1, y: 2 })
|
|
72
|
+
# channel.publish message
|
|
73
|
+
#
|
|
68
74
|
def publish(name, data = nil, attributes = {})
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
raise ArgumentError, "name argument does not support single Message objects, only arrays of Message objects"
|
|
74
|
-
end
|
|
75
|
+
qs_params = nil
|
|
76
|
+
qs_params = data if name.kind_of?(Enumerable) || name.kind_of?(Ably::Models::Message)
|
|
77
|
+
|
|
78
|
+
messages = build_messages(name, data, attributes) # (RSL1a, RSL1b)
|
|
75
79
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
[{ name: name, data: data }.merge(attributes)]
|
|
80
|
+
if messages.sum(&:size) > (max_message_size = client.max_message_size || Ably::Rest::Client::MAX_MESSAGE_SIZE)
|
|
81
|
+
raise Ably::Exceptions::MaxMessageSizeExceeded.new("Maximum message size exceeded #{max_message_size} bytes.")
|
|
79
82
|
end
|
|
80
83
|
|
|
81
|
-
payload = messages.
|
|
84
|
+
payload = messages.map do |message|
|
|
82
85
|
Ably::Models::Message(message.dup).tap do |msg|
|
|
83
86
|
msg.encode client.encoders, options
|
|
84
87
|
|
|
@@ -103,7 +106,8 @@ module Ably
|
|
|
103
106
|
end
|
|
104
107
|
end
|
|
105
108
|
|
|
106
|
-
|
|
109
|
+
options = qs_params ? { qs_params: qs_params } : {}
|
|
110
|
+
response = client.post("#{base_path}/publish", payload.length == 1 ? payload.first : payload, options)
|
|
107
111
|
|
|
108
112
|
[201, 204].include?(response.status)
|
|
109
113
|
end
|
|
@@ -149,12 +153,23 @@ module Ably
|
|
|
149
153
|
@presence ||= Presence.new(client, self)
|
|
150
154
|
end
|
|
151
155
|
|
|
152
|
-
#
|
|
153
|
-
|
|
154
|
-
|
|
156
|
+
# Sets or updates the stored channel options. (#RSL7)
|
|
157
|
+
# @param channel_options [Hash, Ably::Models::ChannelOptions] A hash of options or a {Ably::Models::ChannelOptions}
|
|
158
|
+
# @return [Ably::Models::ChannelOptions]
|
|
159
|
+
def set_options(channel_options)
|
|
160
|
+
@options = Ably::Models::ChannelOptions(channel_options)
|
|
161
|
+
end
|
|
162
|
+
alias options= set_options
|
|
163
|
+
|
|
164
|
+
# Makes GET request for channel details (#RSL8, #RSL8a)
|
|
165
|
+
#
|
|
166
|
+
# @return [Ably::Models::ChannelDetails]
|
|
167
|
+
def status
|
|
168
|
+
Ably::Models::ChannelDetails.new(client.get(base_path).body)
|
|
155
169
|
end
|
|
156
170
|
|
|
157
171
|
private
|
|
172
|
+
|
|
158
173
|
def base_path
|
|
159
174
|
"/channels/#{URI.encode_www_form_component(name)}"
|
|
160
175
|
end
|
|
@@ -3,6 +3,9 @@ require 'json'
|
|
|
3
3
|
require 'logger'
|
|
4
4
|
require 'uri'
|
|
5
5
|
|
|
6
|
+
require 'typhoeus'
|
|
7
|
+
require 'faraday/typhoeus'
|
|
8
|
+
|
|
6
9
|
require 'ably/rest/middleware/exceptions'
|
|
7
10
|
|
|
8
11
|
module Ably
|
|
@@ -22,6 +25,9 @@ module Ably
|
|
|
22
25
|
# Default Ably domain for REST
|
|
23
26
|
DOMAIN = 'rest.ably.io'
|
|
24
27
|
|
|
28
|
+
MAX_MESSAGE_SIZE = 65536 # See spec TO3l8
|
|
29
|
+
MAX_FRAME_SIZE = 524288 # See spec TO3l8
|
|
30
|
+
|
|
25
31
|
# Configuration for HTTP timeouts and HTTP request reattempts to fallback hosts
|
|
26
32
|
HTTP_DEFAULTS = {
|
|
27
33
|
open_timeout: 4,
|
|
@@ -32,6 +38,13 @@ module Ably
|
|
|
32
38
|
|
|
33
39
|
FALLBACK_RETRY_TIMEOUT = 10 * 60
|
|
34
40
|
|
|
41
|
+
# Faraday 1.0 introduced new error types, however we want to support Faraday <1 too which only used Faraday::ClientError
|
|
42
|
+
FARADAY_CLIENT_OR_SERVER_ERRORS = if defined?(Faraday::ParsingError)
|
|
43
|
+
[Faraday::ClientError, Faraday::ServerError, Faraday::ConnectionFailed, Faraday::SSLError, Faraday::ParsingError]
|
|
44
|
+
else
|
|
45
|
+
Faraday::ClientError
|
|
46
|
+
end
|
|
47
|
+
|
|
35
48
|
def_delegators :auth, :client_id, :auth_options
|
|
36
49
|
|
|
37
50
|
# Custom environment to use such as 'sandbox' when testing the client library against an alternate Ably environment
|
|
@@ -42,6 +55,10 @@ module Ably
|
|
|
42
55
|
# @return [Symbol]
|
|
43
56
|
attr_reader :protocol
|
|
44
57
|
|
|
58
|
+
# Client agent i.e. `example-gem/1.2.0 ably-ruby/1.1.5 ruby/3.1.1`
|
|
59
|
+
# @return [String]
|
|
60
|
+
attr_reader :agent
|
|
61
|
+
|
|
45
62
|
# {Ably::Auth} authentication object configured for this connection
|
|
46
63
|
# @return [Ably::Auth]
|
|
47
64
|
attr_reader :auth
|
|
@@ -102,6 +119,14 @@ module Ably
|
|
|
102
119
|
# @return [Boolean]
|
|
103
120
|
attr_reader :idempotent_rest_publishing
|
|
104
121
|
|
|
122
|
+
# Max message size (TO2, TO3l8) by default (65536 bytes) 64KiB
|
|
123
|
+
# @return [Integer]
|
|
124
|
+
attr_reader :max_message_size
|
|
125
|
+
|
|
126
|
+
# Max frame size (TO2, TO3l8) by default (524288 bytes) 512KiB
|
|
127
|
+
# @return [Integer]
|
|
128
|
+
attr_reader :max_frame_size
|
|
129
|
+
|
|
105
130
|
# Creates a {Ably::Rest::Client Rest Client} and configures the {Ably::Auth} object for the connection.
|
|
106
131
|
#
|
|
107
132
|
# @param [Hash,String] options an options Hash used to configure the client and the authentication, or String with an API key or Token ID
|
|
@@ -114,7 +139,7 @@ module Ably
|
|
|
114
139
|
# @option options [Symbol] :protocol (:msgpack) Protocol used to communicate with Ably, :json and :msgpack currently supported
|
|
115
140
|
# @option options [Boolean] :use_binary_protocol (true) When true will use the MessagePack binary protocol, when false it will use JSON encoding. This option will overide :protocol option
|
|
116
141
|
# @option options [Logger::Severity,Symbol] :log_level (Logger::WARN) Log level for the standard Logger that outputs to STDOUT. Can be set to :fatal (Logger::FATAL), :error (Logger::ERROR), :warn (Logger::WARN), :info (Logger::INFO), :debug (Logger::DEBUG) or :none
|
|
117
|
-
# @option options [Logger] :logger A custom logger can be used however it must adhere to the Ruby Logger interface, see http://www.ruby-doc.org/stdlib-1.
|
|
142
|
+
# @option options [Logger] :logger A custom logger can be used however it must adhere to the Ruby Logger interface, see http://www.ruby-doc.org/stdlib-3.1.1/libdoc/logger/rdoc/Logger.html
|
|
118
143
|
# @option options [String] :client_id client ID identifying this connection to other clients
|
|
119
144
|
# @option options [String] :auth_url a URL to be used to GET or POST a set of token request params, to obtain a signed token request
|
|
120
145
|
# @option options [Hash] :auth_headers a set of application-specific headers to be added to any request made to the +auth_url+
|
|
@@ -122,7 +147,7 @@ module Ably
|
|
|
122
147
|
# @option options [Symbol] :auth_method (:get) HTTP method to use with +auth_url+, must be either +:get+ or +:post+
|
|
123
148
|
# @option options [Proc] :auth_callback when provided, the Proc will be called with the token params hash as the first argument, whenever a new token is required.
|
|
124
149
|
# The Proc should return a token string, {Ably::Models::TokenDetails} or JSON equivalent, {Ably::Models::TokenRequest} or JSON equivalent
|
|
125
|
-
# @option options [Boolean] :query_time when true will query the {https://www.ably.
|
|
150
|
+
# @option options [Boolean] :query_time when true will query the {https://www.ably.com Ably} system for the current time instead of using the local time
|
|
126
151
|
# @option options [Hash] :default_token_params convenience to pass in +token_params+ that will be used as a default for all token requests. See {Auth#create_token_request}
|
|
127
152
|
#
|
|
128
153
|
# @option options [Integer] :http_open_timeout (4 seconds) timeout in seconds for opening an HTTP connection for all HTTP requests
|
|
@@ -136,6 +161,8 @@ module Ably
|
|
|
136
161
|
#
|
|
137
162
|
# @option options [Boolean] :add_request_ids (false) When true, adds a unique request_id to each request sent to Ably servers. This is handy when reporting issues, because you can refer to a specific request.
|
|
138
163
|
# @option options [Boolean] :idempotent_rest_publishing (false if ver < 1.2) When true, idempotent publishing is enabled for all messages published via REST
|
|
164
|
+
# @option options [Integer] :max_message_size (65536 bytes) Maximum size of all messages when publishing via REST publish()
|
|
165
|
+
# @option options [Integer] :max_frame_size (524288 bytes) Maximum size of frame
|
|
139
166
|
#
|
|
140
167
|
# @return [Ably::Rest::Client]
|
|
141
168
|
#
|
|
@@ -158,6 +185,7 @@ module Ably
|
|
|
158
185
|
end
|
|
159
186
|
end
|
|
160
187
|
|
|
188
|
+
@agent = options.delete(:agent) || Ably::AGENT
|
|
161
189
|
@realtime_client = options.delete(:realtime_client)
|
|
162
190
|
@tls = options.delete(:tls) == false ? false : true
|
|
163
191
|
@environment = options.delete(:environment) # nil is production
|
|
@@ -171,19 +199,25 @@ module Ably
|
|
|
171
199
|
@custom_tls_port = options.delete(:tls_port)
|
|
172
200
|
@add_request_ids = options.delete(:add_request_ids)
|
|
173
201
|
@log_retries_as_info = options.delete(:log_retries_as_info)
|
|
174
|
-
@
|
|
202
|
+
@max_message_size = options.delete(:max_message_size) || MAX_MESSAGE_SIZE
|
|
203
|
+
@max_frame_size = options.delete(:max_frame_size) || MAX_FRAME_SIZE
|
|
175
204
|
|
|
205
|
+
if (@idempotent_rest_publishing = options.delete(:idempotent_rest_publishing)).nil?
|
|
206
|
+
@idempotent_rest_publishing = Ably::PROTOCOL_VERSION.to_f > 1.1
|
|
207
|
+
end
|
|
176
208
|
|
|
177
|
-
if options[:fallback_hosts_use_default] && options[:
|
|
178
|
-
raise ArgumentError, "fallback_hosts_use_default cannot be set to
|
|
209
|
+
if options[:fallback_hosts_use_default] && options[:fallback_hosts]
|
|
210
|
+
raise ArgumentError, "fallback_hosts_use_default cannot be set to try when fallback_hosts is also provided"
|
|
179
211
|
end
|
|
180
212
|
@fallback_hosts = case
|
|
181
213
|
when options.delete(:fallback_hosts_use_default)
|
|
182
214
|
Ably::FALLBACK_HOSTS
|
|
183
215
|
when options_fallback_hosts = options.delete(:fallback_hosts)
|
|
184
216
|
options_fallback_hosts
|
|
185
|
-
when
|
|
217
|
+
when custom_host || options[:realtime_host] || custom_port || custom_tls_port
|
|
186
218
|
[]
|
|
219
|
+
when environment
|
|
220
|
+
CUSTOM_ENVIRONMENT_FALLBACKS_SUFFIXES.map { |host| "#{environment}#{host}" }
|
|
187
221
|
else
|
|
188
222
|
Ably::FALLBACK_HOSTS
|
|
189
223
|
end
|
|
@@ -195,6 +229,8 @@ module Ably
|
|
|
195
229
|
@http_defaults = HTTP_DEFAULTS.dup
|
|
196
230
|
options.each do |key, val|
|
|
197
231
|
if http_key = key[/^http_(.+)/, 1]
|
|
232
|
+
# Typhoeus converts decimal durations to milliseconds, so 0.0001 timeout is treated as 0 (no timeout)
|
|
233
|
+
val = 0.001 if val.kind_of?(Numeric) && (val > 0) && (val < 0.001)
|
|
198
234
|
@http_defaults[http_key.to_sym] = val if val && @http_defaults.has_key?(http_key.to_sym)
|
|
199
235
|
end
|
|
200
236
|
end
|
|
@@ -336,14 +372,17 @@ module Ably
|
|
|
336
372
|
#
|
|
337
373
|
# @return [Ably::Models::HttpPaginatedResponse<>]
|
|
338
374
|
def request(method, path, params = {}, body = nil, headers = {}, options = {})
|
|
339
|
-
raise "Method #{method.to_s.upcase} not supported" unless
|
|
375
|
+
raise "Method #{method.to_s.upcase} not supported" unless %i(get put patch post delete).include?(method.to_sym)
|
|
340
376
|
|
|
341
377
|
response = case method.to_sym
|
|
342
|
-
when :get
|
|
378
|
+
when :get, :delete
|
|
343
379
|
reauthorize_on_authorization_failure do
|
|
344
380
|
send_request(method, path, params, headers: headers)
|
|
345
381
|
end
|
|
346
|
-
when :post
|
|
382
|
+
when :post, :patch, :put
|
|
383
|
+
if body.to_json.bytesize > max_frame_size
|
|
384
|
+
raise Ably::Exceptions::MaxFrameSizeExceeded.new("Maximum frame size exceeded #{max_frame_size} bytes.")
|
|
385
|
+
end
|
|
347
386
|
path_with_params = Addressable::URI.new
|
|
348
387
|
path_with_params.query_values = params || {}
|
|
349
388
|
query = path_with_params.query
|
|
@@ -459,16 +498,6 @@ module Ably
|
|
|
459
498
|
end
|
|
460
499
|
end
|
|
461
500
|
|
|
462
|
-
# Library Ably version user agent
|
|
463
|
-
# @api private
|
|
464
|
-
def lib_version_id
|
|
465
|
-
@lib_version_id ||= [
|
|
466
|
-
'ruby',
|
|
467
|
-
Ably.lib_variant,
|
|
468
|
-
Ably::VERSION
|
|
469
|
-
].compact.join('-')
|
|
470
|
-
end
|
|
471
|
-
|
|
472
501
|
# Allowable duration for an external auth request
|
|
473
502
|
# For REST client this defaults to request_timeout
|
|
474
503
|
# For Realtime clients this defaults to 250ms less than the realtime_request_timeout
|
|
@@ -559,12 +588,14 @@ module Ably
|
|
|
559
588
|
request.options.context = {} if request.options.context.nil?
|
|
560
589
|
request.options.context[:request_id] = request_id
|
|
561
590
|
end
|
|
591
|
+
if options[:qs_params]
|
|
592
|
+
request.params.merge!(options[:qs_params])
|
|
593
|
+
end
|
|
562
594
|
unless options[:send_auth_header] == false
|
|
563
595
|
request.headers[:authorization] = auth.auth_header
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
end
|
|
596
|
+
|
|
597
|
+
options[:headers].to_h.merge(auth.extra_auth_headers).map do |key, val|
|
|
598
|
+
request.headers[key] = val
|
|
568
599
|
end
|
|
569
600
|
end
|
|
570
601
|
end.tap do
|
|
@@ -578,7 +609,7 @@ module Ably
|
|
|
578
609
|
end
|
|
579
610
|
end
|
|
580
611
|
|
|
581
|
-
rescue Faraday::TimeoutError,
|
|
612
|
+
rescue *([Faraday::TimeoutError, Ably::Exceptions::ServerError] + FARADAY_CLIENT_OR_SERVER_ERRORS) => error
|
|
582
613
|
retry_sequence_id ||= SecureRandom.urlsafe_base64(4)
|
|
583
614
|
time_passed = Time.now - requested_at
|
|
584
615
|
|
|
@@ -598,7 +629,7 @@ module Ably
|
|
|
598
629
|
case error
|
|
599
630
|
when Faraday::TimeoutError
|
|
600
631
|
raise Ably::Exceptions::ConnectionTimeout.new(error.message, nil, Ably::Exceptions::Codes::CONNECTION_TIMED_OUT, error, { request_id: request_id })
|
|
601
|
-
when
|
|
632
|
+
when *FARADAY_CLIENT_OR_SERVER_ERRORS
|
|
602
633
|
# request_id is also available in the request context
|
|
603
634
|
raise Ably::Exceptions::ConnectionError.new(error.message, nil, Ably::Exceptions::Codes::CONNECTION_FAILED, error, { request_id: request_id })
|
|
604
635
|
else
|
|
@@ -647,7 +678,7 @@ module Ably
|
|
|
647
678
|
accept: mime_type,
|
|
648
679
|
user_agent: user_agent,
|
|
649
680
|
'X-Ably-Version' => Ably::PROTOCOL_VERSION,
|
|
650
|
-
'
|
|
681
|
+
'Ably-Agent' => agent
|
|
651
682
|
},
|
|
652
683
|
request: {
|
|
653
684
|
open_timeout: http_defaults.fetch(:open_timeout),
|
|
@@ -656,7 +687,7 @@ module Ably
|
|
|
656
687
|
}
|
|
657
688
|
end
|
|
658
689
|
|
|
659
|
-
# Return a Faraday middleware stack to initiate the Faraday::
|
|
690
|
+
# Return a Faraday middleware stack to initiate the Faraday::RackBuilder with
|
|
660
691
|
#
|
|
661
692
|
# @see http://mislav.uniqpath.com/2011/07/faraday-advanced-http/
|
|
662
693
|
def middleware
|
|
@@ -668,8 +699,8 @@ module Ably
|
|
|
668
699
|
|
|
669
700
|
setup_incoming_middleware builder, logger, fail_if_unsupported_mime_type: true
|
|
670
701
|
|
|
671
|
-
# Set Faraday's HTTP adapter
|
|
672
|
-
builder.adapter :
|
|
702
|
+
# Set Faraday's HTTP adapter with support for HTTP/2
|
|
703
|
+
builder.adapter :typhoeus, http_version: :httpv2_0
|
|
673
704
|
end
|
|
674
705
|
end
|
|
675
706
|
|