matrix_sdk 0.0.1 → 0.0.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/.rubocop.yml +39 -0
- data/README.md +27 -2
- data/examples/simple_client.rb +93 -0
- data/lib/matrix_sdk/api.rb +402 -31
- data/lib/matrix_sdk/client.rb +234 -0
- data/lib/matrix_sdk/errors.rb +21 -5
- data/lib/matrix_sdk/extensions.rb +119 -0
- data/lib/matrix_sdk/room.rb +471 -0
- data/lib/matrix_sdk/user.rb +49 -0
- data/lib/matrix_sdk/version.rb +1 -1
- data/lib/matrix_sdk.rb +24 -2
- data/matrix-sdk.gemspec +9 -7
- metadata +27 -8
data/lib/matrix_sdk/api.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'matrix_sdk'
|
2
|
+
|
1
3
|
require 'json'
|
2
4
|
require 'net/http'
|
3
5
|
require 'openssl'
|
@@ -5,17 +7,48 @@ require 'uri'
|
|
5
7
|
|
6
8
|
module MatrixSdk
|
7
9
|
class Api
|
8
|
-
attr_accessor :access_token, :device_id
|
9
|
-
attr_reader :homeserver
|
10
|
+
attr_accessor :access_token, :device_id
|
11
|
+
attr_reader :homeserver, :validate_certificate
|
12
|
+
|
13
|
+
ignore_inspect :access_token
|
10
14
|
|
11
15
|
def initialize(homeserver, params = {})
|
12
16
|
@homeserver = homeserver
|
13
|
-
@homeserver = URI(@homeserver) unless @homeserver.is_a? URI
|
14
|
-
|
17
|
+
@homeserver = URI.parse(@homeserver.to_s) unless @homeserver.is_a? URI
|
18
|
+
if @homeserver.path.end_with? '_matrix/'
|
19
|
+
@homeserver.path = begin
|
20
|
+
split = @homeserver.path.rpartition '_matrix/'
|
21
|
+
(split[(split.find_index '_matrix/')] = '/') rescue nil
|
22
|
+
split.join
|
23
|
+
end
|
24
|
+
end
|
25
|
+
raise 'Please use the base URL for your HS (without /_matrix/)' if @homeserver.path.include? '/_matrix/'
|
15
26
|
|
16
27
|
@access_token = params.fetch(:access_token, nil)
|
17
28
|
@device_id = params.fetch(:device_id, nil)
|
18
29
|
@validate_certificate = params.fetch(:validate_certificate, false)
|
30
|
+
@transaction_id = params.fetch(:transaction_id, 0)
|
31
|
+
@backoff_time = params.fetch(:backoff_time, 5000)
|
32
|
+
|
33
|
+
login(user: @homeserver.user, password: @homeserver.password) if @homeserver.user && @homeserver.password && !@access_token && !params[:skip_login]
|
34
|
+
@homeserver.userinfo = '' unless params[:skip_login]
|
35
|
+
end
|
36
|
+
|
37
|
+
def logger
|
38
|
+
@logger ||= Logging.logger[self.class.name]
|
39
|
+
end
|
40
|
+
|
41
|
+
def validate_certificate=(validate)
|
42
|
+
# The HTTP connection needs to be reopened if this changes
|
43
|
+
@http.finish if @http && validate != @validate_certificate
|
44
|
+
@validate_certificate = validate
|
45
|
+
end
|
46
|
+
|
47
|
+
def homeserver=(hs_info)
|
48
|
+
# TODO: DNS query for SRV information about HS?
|
49
|
+
return unless hs_info.is_a? URI
|
50
|
+
@http.finish if @http
|
51
|
+
@homeserver = hs_info
|
19
52
|
end
|
20
53
|
|
21
54
|
def api_versions
|
@@ -23,33 +56,38 @@ module MatrixSdk
|
|
23
56
|
end
|
24
57
|
|
25
58
|
def sync(params = {})
|
26
|
-
|
27
|
-
timeout: 30.0
|
28
|
-
}.merge(params).select
|
59
|
+
query = {
|
60
|
+
timeout: 30.0
|
61
|
+
}.merge(params).select do |k, _v|
|
29
62
|
%i[since timeout filter full_state set_presence].include? k
|
30
|
-
|
63
|
+
end
|
31
64
|
|
32
|
-
|
33
|
-
|
65
|
+
query[:timeout] = ((query[:timeout] || 30) * 1000).to_i
|
66
|
+
query[:timeout] = params.delete(:timeout_ms).to_i if params.key? :timeout_ms
|
34
67
|
|
35
|
-
request(:get, :client_r0, '/sync', query:
|
68
|
+
request(:get, :client_r0, '/sync', query: query)
|
36
69
|
end
|
37
70
|
|
38
71
|
def register(params = {})
|
39
|
-
|
72
|
+
kind = params.delete(:kind) { 'user' }
|
73
|
+
|
74
|
+
request(:post, :client_r0, '/register', body: params, query: { kind: kind })
|
40
75
|
end
|
41
76
|
|
42
77
|
def login(params = {})
|
43
78
|
options = {}
|
44
79
|
options[:store_token] = params.delete(:store_token) { true }
|
80
|
+
options[:store_device_id] = params.delete(:store_device_id) { true }
|
45
81
|
|
46
82
|
data = {
|
47
|
-
type: params.delete(:login_type) { 'm.login.password' }
|
83
|
+
type: params.delete(:login_type) { 'm.login.password' },
|
84
|
+
initial_device_display_name: params.delete(:initial_device_display_name) { user_agent }
|
48
85
|
}.merge params
|
49
86
|
data[:device_id] = device_id if device_id
|
50
87
|
|
51
88
|
request(:post, :client_r0, '/login', body: data).tap do |resp|
|
52
89
|
@access_token = resp[:token] if resp[:token] && options[:store_token]
|
90
|
+
@device_id = resp[:device_id] if resp[:device_id] && options[:store_device_id]
|
53
91
|
end
|
54
92
|
end
|
55
93
|
|
@@ -58,11 +96,301 @@ module MatrixSdk
|
|
58
96
|
end
|
59
97
|
|
60
98
|
def create_room(params = {})
|
61
|
-
|
99
|
+
content = {
|
100
|
+
visibility: params.fetch(:visibility, :public)
|
101
|
+
}
|
102
|
+
content[:room_alias_name] = params[:room_alias] if params[:room_alias]
|
103
|
+
content[:invite] = [params[:invite]].flatten if params[:invite]
|
104
|
+
|
105
|
+
request(:post, :client_r0, '/createRoom', content)
|
62
106
|
end
|
63
107
|
|
64
108
|
def join_room(id_or_alias)
|
65
|
-
request(:post, :client_r0, "/join/#{
|
109
|
+
request(:post, :client_r0, "/join/#{CGI.escape id_or_alias}")
|
110
|
+
end
|
111
|
+
|
112
|
+
def send_state_event(room_id, event_type, content, params = {})
|
113
|
+
query = {}
|
114
|
+
query[:ts] = params[:timestamp].to_i if params.key? :timestamp
|
115
|
+
|
116
|
+
request(:put, :client_r0, "/rooms/#{room_id}/state/#{event_type}#{"/#{params[:state_key]}" if params.key? :state_key}", body: content, query: query)
|
117
|
+
end
|
118
|
+
|
119
|
+
def send_message_event(room_id, event_type, content, params = {})
|
120
|
+
query = {}
|
121
|
+
query[:ts] = params[:timestamp].to_i if params.key? :timestamp
|
122
|
+
|
123
|
+
txn_id = transaction_id
|
124
|
+
txn_id = params.fetch(:txn_id, "#{txn_id}#{Time.now.to_i}")
|
125
|
+
|
126
|
+
request(:put, :client_r0, "/rooms/#{room_id}/send/#{event_type}/#{txn_id}", body: content, query: query)
|
127
|
+
end
|
128
|
+
|
129
|
+
def redact_event(room_id, event_type, params = {})
|
130
|
+
query = {}
|
131
|
+
query[:ts] = params[:timestamp].to_i if params.key? :timestamp
|
132
|
+
|
133
|
+
content = {}
|
134
|
+
content[:reason] = params[:reason] if params[:reason]
|
135
|
+
|
136
|
+
txn_id = transaction_id
|
137
|
+
txn_id = params.fetch(:txn_id, "#{txn_id}#{Time.now.to_i}")
|
138
|
+
|
139
|
+
request(:put, :client_r0, "/rooms/#{room_id}/redact/#{event_type}/#{txn_id}", body: content, query: query)
|
140
|
+
end
|
141
|
+
|
142
|
+
def send_content(room_id, url, name, msg_type, params = {})
|
143
|
+
content = {
|
144
|
+
url: url,
|
145
|
+
msgtype: msg_type,
|
146
|
+
body: name,
|
147
|
+
info: params.delete(:extra_information) { {} }
|
148
|
+
}
|
149
|
+
|
150
|
+
send_message_event(room_id, 'm.room.message', content, params)
|
151
|
+
end
|
152
|
+
|
153
|
+
def send_location(room_id, geo_uri, name, params = {})
|
154
|
+
content = {
|
155
|
+
geo_uri: geo_uri,
|
156
|
+
msgtype: 'm.location',
|
157
|
+
body: name
|
158
|
+
}
|
159
|
+
content[:thumbnail_url] = params.delete(:thumbnail_url) if params.key? :thumbnail_url
|
160
|
+
content[:thumbnail_info] = params.delete(:thumbnail_info) if params.key? :thumbnail_info
|
161
|
+
|
162
|
+
send_message_event(room_id, 'm.room.message', content, params)
|
163
|
+
end
|
164
|
+
|
165
|
+
def send_message(room_id, message, params = {})
|
166
|
+
content = {
|
167
|
+
msgtype: params.delete(:msg_type) { 'm.text' },
|
168
|
+
body: message
|
169
|
+
}
|
170
|
+
send_message_event(room_id, 'm.room.message', content, params)
|
171
|
+
end
|
172
|
+
|
173
|
+
def send_emote(room_id, emote, params = {})
|
174
|
+
content = {
|
175
|
+
msgtype: params.delete(:msg_type) { 'm.emote' },
|
176
|
+
body: emote
|
177
|
+
}
|
178
|
+
send_message_event(room_id, 'm.room.message', content, params)
|
179
|
+
end
|
180
|
+
|
181
|
+
def send_notice(room_id, notice, params = {})
|
182
|
+
content = {
|
183
|
+
msgtype: params.delete(:msg_type) { 'm.notice' },
|
184
|
+
body: notice
|
185
|
+
}
|
186
|
+
send_message_event(room_id, 'm.room.message', content, params)
|
187
|
+
end
|
188
|
+
|
189
|
+
def get_room_messages(room_id, token, direction, params = {})
|
190
|
+
query = {
|
191
|
+
roomId: room_id,
|
192
|
+
from: token,
|
193
|
+
dir: direction,
|
194
|
+
limit: params.fetch(:limit, 10)
|
195
|
+
}
|
196
|
+
query[:to] = params[:to] if params.key? :to
|
197
|
+
|
198
|
+
request(:get, :client_r0, "/rooms/#{room_id}/messages", query: query)
|
199
|
+
end
|
200
|
+
|
201
|
+
def get_room_name(room_id)
|
202
|
+
request(:get, :client_r0, "/rooms/#{room_id}/state/m.room.name")
|
203
|
+
end
|
204
|
+
|
205
|
+
def set_room_name(room_id, name, params = {})
|
206
|
+
content = {
|
207
|
+
name: name
|
208
|
+
}
|
209
|
+
send_state_event(room_id, 'm.room.name', content, params)
|
210
|
+
end
|
211
|
+
|
212
|
+
def get_room_topic(room_id)
|
213
|
+
request(:get, :client_r0, "/rooms/#{room_id}/state/m.room.topic")
|
214
|
+
end
|
215
|
+
|
216
|
+
def set_room_topic(room_id, topic, params = {})
|
217
|
+
content = {
|
218
|
+
topic: topic
|
219
|
+
}
|
220
|
+
send_state_event(room_id, 'm.room.topic', content, params)
|
221
|
+
end
|
222
|
+
|
223
|
+
def get_power_levels(room_id)
|
224
|
+
request(:get, :client_r0, "/rooms/#{room_id}/state/m.room.power_levels")
|
225
|
+
end
|
226
|
+
|
227
|
+
def set_power_levels(room_id, content)
|
228
|
+
content[:events] = {} unless content.key? :events
|
229
|
+
send_state_event(room_id, 'm.room.power_levels', content)
|
230
|
+
end
|
231
|
+
|
232
|
+
def leave_room(room_id)
|
233
|
+
request(:post, :client_r0, "/rooms/#{room_id}/leave")
|
234
|
+
end
|
235
|
+
|
236
|
+
def forget_room(room_id)
|
237
|
+
request(:post, :client_r0, "/rooms/#{room_id}/forget")
|
238
|
+
end
|
239
|
+
|
240
|
+
def invite_user(room_id, user_id)
|
241
|
+
content = {
|
242
|
+
user_id: user_id
|
243
|
+
}
|
244
|
+
request(:post, :client_r0, "/rooms/#{room_id}/invite", body: content)
|
245
|
+
end
|
246
|
+
|
247
|
+
def kick_user(room_id, user_id, params = {})
|
248
|
+
set_membership(room_id, user_id, 'leave', params)
|
249
|
+
end
|
250
|
+
|
251
|
+
def get_membership(room_id, user_id)
|
252
|
+
request(:get, :client_r0, "/rooms/#{room_id}/state/m.room.member/#{user_id}")
|
253
|
+
end
|
254
|
+
|
255
|
+
def set_membership(room_id, user_id, membership, params = {})
|
256
|
+
content = {
|
257
|
+
membership: membership,
|
258
|
+
reason: params.delete(:reason) { '' }
|
259
|
+
}
|
260
|
+
content[:displayname] = params.delete(:displayname) if params.key? :displayname
|
261
|
+
content[:avatar_url] = params.delete(:avatar_url) if params.key? :avatar_url
|
262
|
+
|
263
|
+
send_state_event(room_id, 'm.room.member', content, params.merge(state_key: user_id))
|
264
|
+
end
|
265
|
+
|
266
|
+
def ban_user(room_id, user_id, params = {})
|
267
|
+
content = {
|
268
|
+
user_id: user_id,
|
269
|
+
reason: params[:reason] || ''
|
270
|
+
}
|
271
|
+
request(:post, :client_r0, "/rooms/#{room_id}/ban", body: content)
|
272
|
+
end
|
273
|
+
|
274
|
+
def unban_user(room_id, user_id)
|
275
|
+
content = {
|
276
|
+
user_id: user_id
|
277
|
+
}
|
278
|
+
request(:post, :client_r0, "/rooms/#{room_id}/unban", body: content)
|
279
|
+
end
|
280
|
+
|
281
|
+
def get_user_tags(user_id, room_id)
|
282
|
+
request(:get, :client_r0, "/user/#{user_id}/rooms/#{room_id}/tags")
|
283
|
+
end
|
284
|
+
|
285
|
+
def remove_user_tag(user_id, room_id, tag)
|
286
|
+
request(:delete, :client_r0, "/user/#{user_id}/rooms/#{room_id}/tags/#{tag}")
|
287
|
+
end
|
288
|
+
|
289
|
+
def add_user_tag(user_id, room_id, tag, params = {})
|
290
|
+
if params[:body]
|
291
|
+
content = params[:body]
|
292
|
+
else
|
293
|
+
content = {}
|
294
|
+
content[:order] = params[:order] if params.key? :order
|
295
|
+
end
|
296
|
+
request(:put, :client_r0, "/user/#{user_id}/rooms/#{room_id}/tags/#{tag}", body: content)
|
297
|
+
end
|
298
|
+
|
299
|
+
def get_account_data(user_id, type)
|
300
|
+
request(:get, :client_r0, "/user/#{user_id}/account_data/#{type}")
|
301
|
+
end
|
302
|
+
|
303
|
+
def set_account_data(user_id, type, account_data)
|
304
|
+
request(:put, :client_r0, "/user/#{user_id}/account_data/#{type}", body: account_data)
|
305
|
+
end
|
306
|
+
|
307
|
+
def get_room_account_data(user_id, room_id, type)
|
308
|
+
request(:get, :client_r0, "/user/#{user_id}/rooms/#{room_id}/account_data/#{type}")
|
309
|
+
end
|
310
|
+
|
311
|
+
def set_room_account_data(user_id, room_id, type, account_data)
|
312
|
+
request(:put, :client_r0, "/user/#{user_id}/rooms/#{room_id}/account_data/#{type}", body: account_data)
|
313
|
+
end
|
314
|
+
|
315
|
+
def get_room_state(room_id)
|
316
|
+
request(:get, :client_r0, "/rooms/#{room_id}/state")
|
317
|
+
end
|
318
|
+
|
319
|
+
def get_filter(user_id, filter_id)
|
320
|
+
request(:get, :client_r0, "/user/#{user_id}/filter/#{filter_id}")
|
321
|
+
end
|
322
|
+
|
323
|
+
def create_filter(user_id, filter_params)
|
324
|
+
request(:post, :client_r0, "/user/#{user_id}/filter", body: filter_params)
|
325
|
+
end
|
326
|
+
|
327
|
+
def media_upload(content, content_type)
|
328
|
+
request(:post, :media_r0, '/upload', body: content, headers: { 'content-type' => content_type })
|
329
|
+
end
|
330
|
+
|
331
|
+
def get_display_name(user_id)
|
332
|
+
request(:get, :client_r0, "/profile/#{user_id}/displayname")
|
333
|
+
end
|
334
|
+
|
335
|
+
def set_display_name(user_id, display_name)
|
336
|
+
content = {
|
337
|
+
display_name: display_name
|
338
|
+
}
|
339
|
+
request(:put, :client_r0, "/profile/#{user_id}/displayname", body: content)
|
340
|
+
end
|
341
|
+
|
342
|
+
def get_avatar_url(user_id)
|
343
|
+
request(:get, :client_r0, "/profile/#{user_id}/avatar_url")
|
344
|
+
end
|
345
|
+
|
346
|
+
def set_avatar_url(user_id, url)
|
347
|
+
content = {
|
348
|
+
avatar_url: url
|
349
|
+
}
|
350
|
+
request(:put, :client_r0, "/profile/#{user_id}/avatar_url", body: content)
|
351
|
+
end
|
352
|
+
|
353
|
+
def get_download_url(mxcurl)
|
354
|
+
mxcurl = URI.parse(mxcurl.to_s) unless mxcurl.is_a? URI
|
355
|
+
raise 'Not a mxc:// URL' unless mxcurl.is_a? URI::MATRIX
|
356
|
+
|
357
|
+
homeserver.dup.tap do |u|
|
358
|
+
u.path = "/_matrix/media/r0/download/#{mxcurl.full_path}"
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
def get_room_id(room_alias)
|
363
|
+
request(:get, :client_r0, "/directory/room/#{room_alias}")
|
364
|
+
end
|
365
|
+
|
366
|
+
def set_room_alias(room_id, room_alias)
|
367
|
+
content = {
|
368
|
+
room_id: room_id
|
369
|
+
}
|
370
|
+
request(:put, :client_r0, "/directory/room/#{room_alias}", body: content)
|
371
|
+
end
|
372
|
+
|
373
|
+
def remove_room_alias(room_alias)
|
374
|
+
request(:delete, :client_r0, "/directory/room/#{room_alias}")
|
375
|
+
end
|
376
|
+
|
377
|
+
def get_room_members(room_id)
|
378
|
+
request(:get, :client_r0, "/rooms/#{room_id}/members")
|
379
|
+
end
|
380
|
+
|
381
|
+
def set_join_rule(room_id, join_rule)
|
382
|
+
content = {
|
383
|
+
join_rule: join_rule
|
384
|
+
}
|
385
|
+
send_state_event(room_id, 'm.room.join_rules', content)
|
386
|
+
end
|
387
|
+
|
388
|
+
def set_guest_access(room_id, guest_access)
|
389
|
+
# raise ArgumentError, '`guest_access` must be one of [:can_join, :forbidden]' unless %i[can_join forbidden].include? guest_access
|
390
|
+
content = {
|
391
|
+
guest_access: guest_access
|
392
|
+
}
|
393
|
+
send_state_event(room_id, 'm.room.guest_access', content)
|
66
394
|
end
|
67
395
|
|
68
396
|
def whoami?
|
@@ -72,42 +400,85 @@ module MatrixSdk
|
|
72
400
|
def request(method, api, path, options = {})
|
73
401
|
url = homeserver.dup.tap do |u|
|
74
402
|
u.path = api_to_path(api) + path
|
75
|
-
u.query = [u.query, options[:query]].reject(&:nil?).
|
403
|
+
u.query = [u.query, options[:query].map { |k, v| "#{k}#{"=#{v}" unless v.nil?}" }].flatten.reject(&:nil?).join('&') if options[:query]
|
404
|
+
u.query = nil if u.query.nil? || u.query.empty?
|
76
405
|
end
|
77
406
|
request = Net::HTTP.const_get(method.to_s.capitalize.to_sym).new url.request_uri
|
78
407
|
request.body = options[:body] if options.key? :body
|
79
|
-
request.body = request.body.to_json
|
408
|
+
request.body = request.body.to_json if options.key?(:body) && !request.body.is_a?(String)
|
80
409
|
request.body_stream = options[:body_stream] if options.key? :body_stream
|
81
410
|
|
82
411
|
request.content_type = 'application/json' if request.body || request.body_stream
|
83
412
|
|
84
413
|
request['authorization'] = "Bearer #{access_token}" if access_token
|
85
|
-
request['user-agent'] =
|
86
|
-
options
|
87
|
-
|
88
|
-
|
414
|
+
request['user-agent'] = user_agent
|
415
|
+
if options.key? :headers
|
416
|
+
options[:headers].each do |h, v|
|
417
|
+
request[h.to_s.downcase] = v
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
failures = 0
|
422
|
+
loop do
|
423
|
+
raise MatrixConnectionError, "Server still too busy to handle request after #{failures} attempts, try again later" if failures >= 10
|
89
424
|
|
90
|
-
|
91
|
-
|
425
|
+
print_http(request)
|
426
|
+
response = http.request request
|
427
|
+
print_http(response)
|
428
|
+
data = JSON.parse(response.body, symbolize_names: true) rescue nil
|
92
429
|
|
93
|
-
|
94
|
-
|
430
|
+
if response.is_a? Net::HTTPTooManyRequests
|
431
|
+
failures += 1
|
432
|
+
waittime = data[:retry_after_ms] || data[:error][:retry_after_ms] || @backoff_time
|
433
|
+
sleep(waittime.to_f / 1000.0)
|
434
|
+
next
|
435
|
+
end
|
436
|
+
|
437
|
+
return data if response.is_a? Net::HTTPSuccess
|
438
|
+
raise MatrixRequestError.new(data, response.code) if data
|
439
|
+
raise MatrixConnectionError, response
|
440
|
+
end
|
95
441
|
end
|
96
442
|
|
97
443
|
private
|
98
444
|
|
445
|
+
def print_http(http)
|
446
|
+
if http.is_a? Net::HTTPRequest
|
447
|
+
dir = '>'
|
448
|
+
logger.debug "#{dir} Sending a #{http.method} request to `#{http.path}`:"
|
449
|
+
else
|
450
|
+
dir = '<'
|
451
|
+
logger.debug "#{dir} Received a #{http.code} #{http.message} response:"
|
452
|
+
end
|
453
|
+
http.to_hash.map { |k, v| "#{k}: #{k == 'authorization' ? '[redacted]' : v.join(', ')}" }.each do |h|
|
454
|
+
logger.debug "#{dir} #{h}"
|
455
|
+
end
|
456
|
+
logger.debug dir
|
457
|
+
logger.debug "#{dir} #{http.body.length < 200 ? http.body : http.body.slice(0..200) + '... [truncated]'}" if http.body
|
458
|
+
end
|
459
|
+
|
460
|
+
def transaction_id
|
461
|
+
ret = @transaction_id ||= 0
|
462
|
+
@transaction_id = @transaction_id.succ
|
463
|
+
ret
|
464
|
+
end
|
465
|
+
|
99
466
|
def api_to_path(api)
|
100
467
|
# TODO: <api>_current / <api>_latest
|
101
468
|
"/_matrix/#{api.to_s.split('_').join('/')}"
|
102
469
|
end
|
103
470
|
|
104
471
|
def http
|
105
|
-
@http ||=
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
472
|
+
@http ||= Net::HTTP.new homeserver.host, homeserver.port
|
473
|
+
return @http if @http.active?
|
474
|
+
|
475
|
+
@http.use_ssl = homeserver.scheme == 'https'
|
476
|
+
@http.verify_mode = validate_certificate ? ::OpenSSL::SSL::VERIFY_NONE : nil
|
477
|
+
@http.start
|
478
|
+
end
|
479
|
+
|
480
|
+
def user_agent
|
481
|
+
"Ruby Matrix SDK v#{MatrixSdk::VERSION}"
|
111
482
|
end
|
112
483
|
end
|
113
484
|
end
|