matrix_sdk 2.0.0 → 2.0.1
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/CHANGELOG.md +5 -0
- data/lib/matrix_sdk.rb +3 -0
- data/lib/matrix_sdk/api.rb +28 -15
- data/lib/matrix_sdk/client.rb +10 -1
- data/lib/matrix_sdk/mxid.rb +1 -0
- data/lib/matrix_sdk/protocols/msc.rb +105 -0
- data/lib/matrix_sdk/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e1de46ea35a8763e17d834c9395dc95a12c3084557085a0eb6b8e5f1fa25979a
|
4
|
+
data.tar.gz: 13a55698bf72695e8e690d4d5f6618d7efe595f06c32c65580b10e9bf550724e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 919a27ee7fd758c382eafe3f8aad89c13da2a6cc6542ccd8bfe52d09186d93453b12406dfe6b03b6aa63d1898dbacfb6dbced4f4e9606722ad04df4f237cf600
|
7
|
+
data.tar.gz: a8f5c0bc4fb07a089e0d1daebeb8996c6d36157550e73e3869a8bb55f25cc2c405a064654fc49c8bdb323f9d8c168b3c785e52b9f88fbc168ee29c152f7472a5
|
data/CHANGELOG.md
CHANGED
data/lib/matrix_sdk.rb
CHANGED
data/lib/matrix_sdk/api.rb
CHANGED
@@ -11,10 +11,6 @@ module MatrixSdk
|
|
11
11
|
class Api
|
12
12
|
extend MatrixSdk::Extensions
|
13
13
|
include MatrixSdk::Logging
|
14
|
-
include MatrixSdk::Protocols::AS
|
15
|
-
include MatrixSdk::Protocols::CS
|
16
|
-
include MatrixSdk::Protocols::IS
|
17
|
-
include MatrixSdk::Protocols::SS
|
18
14
|
|
19
15
|
USER_AGENT = "Ruby Matrix SDK v#{MatrixSdk::VERSION}"
|
20
16
|
DEFAULT_HEADERS = {
|
@@ -23,7 +19,7 @@ module MatrixSdk
|
|
23
19
|
}.freeze
|
24
20
|
|
25
21
|
attr_accessor :access_token, :connection_address, :connection_port, :device_id, :autoretry, :global_headers
|
26
|
-
attr_reader :homeserver, :validate_certificate, :open_timeout, :read_timeout, :
|
22
|
+
attr_reader :homeserver, :validate_certificate, :open_timeout, :read_timeout, :well_known, :proxy_uri
|
27
23
|
|
28
24
|
ignore_inspect :access_token, :logger
|
29
25
|
|
@@ -51,10 +47,6 @@ module MatrixSdk
|
|
51
47
|
@homeserver.path.gsub!(/\/?_matrix\/?/, '') if @homeserver.path =~ /_matrix\/?$/
|
52
48
|
raise ArgumentError, 'Please use the base URL for your HS (without /_matrix/)' if @homeserver.path.include? '/_matrix/'
|
53
49
|
|
54
|
-
@protocols = params.fetch(:protocols, %i[CS])
|
55
|
-
@protocols = [@protocols] unless @protocols.is_a? Array
|
56
|
-
@protocols << :CS if @protocols.include?(:AS) && !@protocols.include?(:CS)
|
57
|
-
|
58
50
|
@proxy_uri = params.fetch(:proxy_uri, nil)
|
59
51
|
@connection_address = params.fetch(:address, nil)
|
60
52
|
@connection_port = params.fetch(:port, nil)
|
@@ -71,6 +63,10 @@ module MatrixSdk
|
|
71
63
|
@global_headers.merge!(params.fetch(:global_headers)) if params.key? :global_headers
|
72
64
|
@http = nil
|
73
65
|
|
66
|
+
([params.fetch(:protocols, [:CS])].flatten - protocols).each do |proto|
|
67
|
+
self.class.include MatrixSdk::Protocols.const_get(proto)
|
68
|
+
end
|
69
|
+
|
74
70
|
login(user: @homeserver.user, password: @homeserver.password) if @homeserver.user && @homeserver.password && !@access_token && !params[:skip_login] && protocol?(:CS)
|
75
71
|
@homeserver.userinfo = '' unless params[:skip_login]
|
76
72
|
end
|
@@ -155,6 +151,20 @@ module MatrixSdk
|
|
155
151
|
))
|
156
152
|
end
|
157
153
|
|
154
|
+
# Get a list of enabled protocols on the API client
|
155
|
+
#
|
156
|
+
# @example
|
157
|
+
# MatrixSdk::Api.new_for_domain('matrix.org').protocols
|
158
|
+
# # => [:IS, :CS]
|
159
|
+
#
|
160
|
+
# @return [Symbol[]] An array of enabled APIs
|
161
|
+
def protocols
|
162
|
+
self
|
163
|
+
.class.included_modules
|
164
|
+
.select { |m| m.name.start_with? 'MatrixSdk::Protocols::' }
|
165
|
+
.map { |m| m.name.split('::').last.to_sym }
|
166
|
+
end
|
167
|
+
|
158
168
|
# Check if a protocol is enabled on the API connection
|
159
169
|
#
|
160
170
|
# @example Checking for identity server API support
|
@@ -233,6 +243,7 @@ module MatrixSdk
|
|
233
243
|
# @option options [Hash,String] :body The body to attach to the request, will be JSON-encoded if sent as a hash
|
234
244
|
# @option options [IO] :body_stream A body stream to attach to the request
|
235
245
|
# @option options [Hash] :headers Additional headers to set on the request
|
246
|
+
# @option options [Boolean] :skip_auth (false) Skip authentication
|
236
247
|
def request(method, api, path, **options)
|
237
248
|
url = homeserver.dup.tap do |u|
|
238
249
|
u.path = api_to_path(api) + path
|
@@ -250,7 +261,7 @@ module MatrixSdk
|
|
250
261
|
request.content_length = (request.body || request.body_stream).size
|
251
262
|
end
|
252
263
|
|
253
|
-
request['authorization'] = "Bearer #{access_token}" if access_token
|
264
|
+
request['authorization'] = "Bearer #{access_token}" if access_token && !options.fetch(:skip_auth, false)
|
254
265
|
if options.key? :headers
|
255
266
|
options[:headers].each do |h, v|
|
256
267
|
request[h.to_s.downcase] = v
|
@@ -289,7 +300,7 @@ module MatrixSdk
|
|
289
300
|
|
290
301
|
private
|
291
302
|
|
292
|
-
def print_http(http)
|
303
|
+
def print_http(http, body: true)
|
293
304
|
return unless logger.debug?
|
294
305
|
|
295
306
|
if http.is_a? Net::HTTPRequest
|
@@ -303,10 +314,12 @@ module MatrixSdk
|
|
303
314
|
logger.debug "#{dir} #{h}"
|
304
315
|
end
|
305
316
|
logger.debug dir
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
317
|
+
if body
|
318
|
+
clean_body = JSON.parse(http.body) rescue nil if http.body
|
319
|
+
clean_body.keys.each { |k| clean_body[k] = '[ REDACTED ]' if %w[password access_token].include?(k) }.to_json if clean_body.is_a? Hash
|
320
|
+
clean_body = clean_body.to_s if clean_body
|
321
|
+
logger.debug "#{dir} #{clean_body.length < 200 ? clean_body : clean_body.slice(0..200) + "... [truncated, #{clean_body.length} Bytes]"}" if clean_body
|
322
|
+
end
|
310
323
|
rescue StandardError => e
|
311
324
|
logger.warn "#{e.class} occured while printing request debug; #{e.message}\n#{e.backtrace.join "\n"}"
|
312
325
|
end
|
data/lib/matrix_sdk/client.rb
CHANGED
@@ -423,7 +423,16 @@ module MatrixSdk
|
|
423
423
|
return if listening?
|
424
424
|
|
425
425
|
@should_listen = true
|
426
|
-
|
426
|
+
if api.protocol?(:MSC) && api.msc2108?
|
427
|
+
params[:since] = @next_batch if @next_batch
|
428
|
+
thread = api.msc2108_sync_sse(params) do |data, event:, id:|
|
429
|
+
logger.debug "Handling SSE event '#{event}' from '#{id}'"
|
430
|
+
@next_batch = id if id
|
431
|
+
handle_sync_response(data) if event.to_sym == :sync
|
432
|
+
end
|
433
|
+
else
|
434
|
+
thread = Thread.new { listen_forever(params) }
|
435
|
+
end
|
427
436
|
@sync_thread = thread
|
428
437
|
thread.run
|
429
438
|
end
|
data/lib/matrix_sdk/mxid.rb
CHANGED
@@ -10,6 +10,7 @@ module MatrixSdk
|
|
10
10
|
raise ArgumentError, 'Identifier is too long' if identifier.size > 255
|
11
11
|
raise ArgumentError, 'Identifier lacks required data' unless identifier =~ %r{^([@!$+#][^:]+:[^:]+(?::\d+)?)|(\$[A-Za-z0-9+/]+)$}
|
12
12
|
|
13
|
+
# TODO: Community-as-a-Room / Profile-as-a-Room, in case they're going for room aliases
|
13
14
|
@sigil = identifier[0]
|
14
15
|
@localpart, @domain, @port = identifier[1..-1].split(':')
|
15
16
|
@port = @port.to_i if @port
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Preliminary support for unmerged MSCs (Matrix Spec Changes)
|
4
|
+
module MatrixSdk::Protocols::MSC
|
5
|
+
def self.included(_)
|
6
|
+
@msc = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def refresh_mscs
|
10
|
+
@msc = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
# Check if there's support for MSC2108 - Sync over Server Sent Events
|
14
|
+
def msc2108?
|
15
|
+
@msc[2108] ||= \
|
16
|
+
begin
|
17
|
+
request(:get, :client_r0, '/sync/sse', skip_auth: true, headers: { accept: 'text/event-stream' })
|
18
|
+
rescue MatrixSdk::MatrixNotAuthorizedError # Returns 401 if implemented
|
19
|
+
true
|
20
|
+
rescue MatrixSdk::MatrixRequestError
|
21
|
+
false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Sync over Server Sent Events - MSC2108
|
26
|
+
#
|
27
|
+
# @note With the default Ruby Net::HTTP server, body fragments are cached up to 16kB,
|
28
|
+
# which will result in large batches and delays if your filters trim a lot of data.
|
29
|
+
#
|
30
|
+
# @example Syncing over SSE
|
31
|
+
# @since = 'some token'
|
32
|
+
# api.msc2108_sync_sse(since: @since) do |data, event:, id:|
|
33
|
+
# if event == 'sync'
|
34
|
+
# handle(data) # data is the same as a normal sync response
|
35
|
+
# @since = id
|
36
|
+
# end
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# @see Protocols::CS#sync
|
40
|
+
# @see https://github.com/matrix-org/matrix-doc/pull/2108/
|
41
|
+
def msc2108_sync_sse(since: nil, **params, &on_data)
|
42
|
+
raise ArgumentError, 'Must be given a block accepting two args - data and { event:, id: }' \
|
43
|
+
unless on_data.is_a?(Proc) && on_data.arity == 2
|
44
|
+
raise MatrixNotAuthorizedError unless access_token
|
45
|
+
|
46
|
+
query = params.select do |k, _v|
|
47
|
+
%i[filter full_state set_presence].include? k
|
48
|
+
end
|
49
|
+
query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
|
50
|
+
|
51
|
+
req = Net::HTTP::Get.new(homeserver.dup.tap do |u|
|
52
|
+
u.path = api_to_path(:client_r0) + '/sync/sse'
|
53
|
+
u.query = URI.encode_www_form(query)
|
54
|
+
end)
|
55
|
+
req['accept'] = 'text/event-stream'
|
56
|
+
req['authorization'] = "Bearer #{access_token}"
|
57
|
+
req['last-event-id'] = since if since
|
58
|
+
|
59
|
+
# rubocop:disable Metrics/BlockLength
|
60
|
+
thread = Thread.new do
|
61
|
+
print_http(req)
|
62
|
+
http.request req do |response|
|
63
|
+
print_http(response, body: false)
|
64
|
+
raise MatrixRequestError.new_by_code(JSON.parse(response.body, symbolize_names: true), response.code) unless response.is_a? Net::HTTPSuccess
|
65
|
+
|
66
|
+
buffer = ''
|
67
|
+
response.read_body do |chunk|
|
68
|
+
buffer += chunk
|
69
|
+
logger.debug "< MSC2108: Received #{chunk.length}B of data."
|
70
|
+
|
71
|
+
while (index = buffer.index(/\r\n\r\n|\n\n/))
|
72
|
+
stream = buffer.slice!(0..index)
|
73
|
+
|
74
|
+
data = ''
|
75
|
+
event = nil
|
76
|
+
id = nil
|
77
|
+
|
78
|
+
stream.split(/\r?\n/).each do |part|
|
79
|
+
/^data:(.+)$/.match(part) do |m_data|
|
80
|
+
data += "\n" unless data.empty?
|
81
|
+
data += m_data[1].strip
|
82
|
+
end
|
83
|
+
/^event:(.+)$/.match(part) do |m_event|
|
84
|
+
event = m_event[1].strip
|
85
|
+
end
|
86
|
+
/^id:(.+)$/.match(part) do |m_id|
|
87
|
+
id = m_id[1].strip
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
data = JSON.parse(data, symbolize_names: true)
|
92
|
+
|
93
|
+
yield((MatrixSdk::Response.new self, data), event: event, id: id)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
# rubocop:enable Metrics/BlockLength
|
99
|
+
|
100
|
+
thread.abort_on_exception = true
|
101
|
+
thread.run
|
102
|
+
|
103
|
+
thread
|
104
|
+
end
|
105
|
+
end
|
data/lib/matrix_sdk/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: matrix_sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Olofsson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-03-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mocha
|
@@ -103,6 +103,7 @@ files:
|
|
103
103
|
- lib/matrix_sdk/protocols/as.rb
|
104
104
|
- lib/matrix_sdk/protocols/cs.rb
|
105
105
|
- lib/matrix_sdk/protocols/is.rb
|
106
|
+
- lib/matrix_sdk/protocols/msc.rb
|
106
107
|
- lib/matrix_sdk/protocols/ss.rb
|
107
108
|
- lib/matrix_sdk/response.rb
|
108
109
|
- lib/matrix_sdk/room.rb
|