blather 0.4.16 → 0.5.0
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.
- data/.gemtest +0 -0
- data/CHANGELOG +12 -5
- data/README.md +1 -1
- data/Rakefile +1 -3
- data/blather.gemspec +11 -24
- data/examples/echo.rb +1 -0
- data/examples/execute.rb +1 -0
- data/examples/ping_pong.rb +1 -0
- data/examples/print_hierarchy.rb +1 -0
- data/examples/rosterprint.rb +1 -0
- data/examples/stream_only.rb +1 -0
- data/examples/xmpp4r/echo.rb +1 -0
- data/lib/blather.rb +5 -1
- data/lib/blather/client/client.rb +29 -154
- data/lib/blather/client/dsl.rb +9 -3
- data/lib/blather/client/dsl/pubsub.rb +2 -0
- data/lib/blather/core_ext/eventmachine.rb +4 -1
- data/lib/blather/core_ext/ipaddr.rb +2 -1
- data/lib/blather/core_ext/nokogiri.rb +3 -1
- data/lib/blather/errors/sasl_error.rb +1 -0
- data/lib/blather/errors/stanza_error.rb +3 -1
- data/lib/blather/errors/stream_error.rb +1 -0
- data/lib/blather/file_transfer.rb +4 -1
- data/lib/blather/file_transfer/s5b.rb +3 -4
- data/lib/blather/jid.rb +2 -0
- data/lib/blather/roster_item.rb +13 -3
- data/lib/blather/stanza.rb +11 -3
- data/lib/blather/stanza/disco/capabilities.rb +161 -0
- data/lib/blather/stanza/disco/disco_info.rb +3 -1
- data/lib/blather/stanza/disco/disco_items.rb +0 -1
- data/lib/blather/stanza/iq.rb +8 -2
- data/lib/blather/stanza/iq/command.rb +18 -3
- data/lib/blather/stanza/iq/ibb.rb +6 -3
- data/lib/blather/stanza/iq/s5b.rb +6 -3
- data/lib/blather/stanza/iq/si.rb +6 -1
- data/lib/blather/stanza/iq/vcard.rb +3 -1
- data/lib/blather/stanza/message.rb +5 -0
- data/lib/blather/stanza/presence.rb +1 -0
- data/lib/blather/stanza/presence/c.rb +1 -0
- data/lib/blather/stanza/presence/status.rb +1 -0
- data/lib/blather/stanza/pubsub/event.rb +2 -4
- data/lib/blather/stanza/pubsub/subscription.rb +1 -0
- data/lib/blather/stanza/x.rb +8 -0
- data/lib/blather/stream.rb +2 -0
- data/lib/blather/stream/client.rb +1 -0
- data/lib/blather/stream/component.rb +1 -0
- data/lib/blather/stream/features.rb +4 -3
- data/lib/blather/stream/features/resource.rb +4 -3
- data/lib/blather/stream/features/sasl.rb +9 -6
- data/lib/blather/stream/features/session.rb +5 -4
- data/lib/blather/stream/features/tls.rb +4 -3
- data/lib/blather/stream/parser.rb +4 -5
- data/lib/blather/version.rb +2 -1
- data/lib/blather/xmpp_node.rb +9 -0
- data/spec/blather/client/client_spec.rb +14 -1
- data/spec/blather/stanza/iq_spec.rb +16 -0
- data/spec/blather/stanza/presence_spec.rb +1 -1
- data/spec/blather/stanza_spec.rb +18 -0
- data/spec/blather/stream/client_spec.rb +2 -2
- metadata +52 -35
- data/lib/blather/core_ext/active_support.rb +0 -45
- data/lib/blather/core_ext/active_support/inheritable_attributes.rb +0 -117
data/.gemtest
ADDED
File without changes
|
data/CHANGELOG
CHANGED
@@ -1,9 +1,16 @@
|
|
1
|
+
v0.5.0
|
2
|
+
Feature(radsaq): Add a #connected? method on Blather::Client
|
3
|
+
Feature(benlangfeld)[API change]: Allow the removal of child nodes from an IQ reply
|
4
|
+
Bugfix(zlu): Use rubygems properly in examples
|
5
|
+
Bugfix(benlangfeld): Remove code borrowed from ActiveSupport and instead depend on it to avoid version conflicts
|
6
|
+
Documentation(sprsquish)
|
7
|
+
|
1
8
|
v0.4.16
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
9
|
+
Feature(benlangfeld): switch from jeweler to bundler
|
10
|
+
Feature(benlangfeld): add cap support (XEP-0115)
|
11
|
+
Bugfix(sprsquish): Better equality checking
|
12
|
+
Bugfix(sprsquish): Fix #to_proc
|
13
|
+
Bugfix(mironov): Skip private IPs by default
|
7
14
|
|
8
15
|
v0.4.15
|
9
16
|
Feature(mironov): Implement XEP-0054: vcard-temp
|
data/README.md
CHANGED
data/Rakefile
CHANGED
@@ -23,10 +23,8 @@ require 'yard'
|
|
23
23
|
YARD::Tags::Library.define_tag 'Blather handler', :handler, :with_name
|
24
24
|
YARD::Templates::Engine.register_template_path 'yard/templates'
|
25
25
|
|
26
|
-
YARD::Rake::YardocTask.new do |t|
|
26
|
+
YARD::Rake::YardocTask.new(:doc) do |t|
|
27
27
|
t.options = ['--no-private', '-m', 'markdown', '-o', './doc/public/yard']
|
28
28
|
end
|
29
29
|
|
30
|
-
desc 'Generate documentation'
|
31
|
-
task :doc => :yard
|
32
30
|
task :default => :test
|
data/blather.gemspec
CHANGED
@@ -21,29 +21,16 @@ Gem::Specification.new do |s|
|
|
21
21
|
s.rdoc_options = %w{--charset=UTF-8}
|
22
22
|
s.extra_rdoc_files = %w{LICENSE README.md}
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
s.add_dependency("eventmachine", ["~> 0.12.6"])
|
25
|
+
s.add_dependency("nokogiri", [">= 1.4.0"])
|
26
|
+
s.add_dependency("minitest", [">= 1.7.1"])
|
27
|
+
s.add_dependency("activesupport", [">= 3.0.7"])
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
s.add_development_dependency(%q<rcov>, ["~> 0.9.9"])
|
36
|
-
s.add_development_dependency(%q<yard>, ["~> 0.6.1"])
|
37
|
-
s.add_development_dependency(%q<bluecloth>, ["~> 2.1.0"])
|
38
|
-
s.add_development_dependency(%q<rake>)
|
39
|
-
else
|
40
|
-
s.add_dependency(%q<eventmachine>, [">= 0.12.6"])
|
41
|
-
s.add_dependency(%q<nokogiri>, [">= 1.4.0"])
|
42
|
-
s.add_dependency(%q<minitest>, [">= 1.7.1"])
|
43
|
-
end
|
44
|
-
else
|
45
|
-
s.add_dependency(%q<eventmachine>, [">= 0.12.6"])
|
46
|
-
s.add_dependency(%q<nokogiri>, [">= 1.4.0"])
|
47
|
-
s.add_dependency(%q<minitest>, [">= 1.7.1"])
|
48
|
-
end
|
29
|
+
s.add_development_dependency("minitest", ["~> 1.7.1"])
|
30
|
+
s.add_development_dependency("mocha", ["~> 0.9.12"])
|
31
|
+
s.add_development_dependency("bundler", ["~> 1.0.0"])
|
32
|
+
s.add_development_dependency("rcov", ["~> 0.9.9"])
|
33
|
+
s.add_development_dependency("yard", ["~> 0.6.1"])
|
34
|
+
s.add_development_dependency("bluecloth", ["~> 2.1.0"])
|
35
|
+
s.add_development_dependency("rake")
|
49
36
|
end
|
data/examples/echo.rb
CHANGED
data/examples/execute.rb
CHANGED
data/examples/ping_pong.rb
CHANGED
data/examples/print_hierarchy.rb
CHANGED
data/examples/rosterprint.rb
CHANGED
data/examples/stream_only.rb
CHANGED
data/examples/xmpp4r/echo.rb
CHANGED
data/lib/blather.rb
CHANGED
@@ -8,7 +8,9 @@
|
|
8
8
|
digest/sha1
|
9
9
|
logger
|
10
10
|
|
11
|
-
|
11
|
+
active_support/core_ext/class/inheritable_attributes
|
12
|
+
active_support/core_ext/object/blank
|
13
|
+
|
12
14
|
blather/core_ext/eventmachine
|
13
15
|
blather/core_ext/ipaddr
|
14
16
|
blather/core_ext/nokogiri
|
@@ -37,6 +39,7 @@
|
|
37
39
|
blather/stanza/disco
|
38
40
|
blather/stanza/disco/disco_info
|
39
41
|
blather/stanza/disco/disco_items
|
42
|
+
blather/stanza/disco/capabilities
|
40
43
|
blather/stanza/message
|
41
44
|
blather/stanza/presence
|
42
45
|
blather/stanza/presence/c
|
@@ -72,6 +75,7 @@
|
|
72
75
|
blather/stream/features/tls
|
73
76
|
].each { |r| require r }
|
74
77
|
|
78
|
+
# The core Blather namespace
|
75
79
|
module Blather
|
76
80
|
# @private
|
77
81
|
@@logger = nil
|
@@ -57,11 +57,16 @@ module Blather
|
|
57
57
|
@tmp_handlers = {}
|
58
58
|
@filters = {:before => [], :after => []}
|
59
59
|
@roster = Roster.new self
|
60
|
-
@caps =
|
60
|
+
@caps = Stanza::Capabilities.new
|
61
61
|
|
62
62
|
setup_initial_handlers
|
63
63
|
end
|
64
64
|
|
65
|
+
# Check whether the client is currently connected.
|
66
|
+
def connected?
|
67
|
+
setup? && !@stream.stopped?
|
68
|
+
end
|
69
|
+
|
65
70
|
# Get the current status. Taken from the `state` attribute of Status
|
66
71
|
def status
|
67
72
|
@status.state
|
@@ -162,17 +167,20 @@ module Blather
|
|
162
167
|
self.stream.close_connection_after_writing
|
163
168
|
end
|
164
169
|
|
165
|
-
|
170
|
+
# @private
|
171
|
+
def post_init(stream, jid = nil)
|
166
172
|
@stream = stream
|
167
173
|
@jid = JID.new(jid) if jid
|
168
174
|
self.jid.node ? client_post_init : ready!
|
169
175
|
end
|
170
176
|
|
171
|
-
|
177
|
+
# @private
|
178
|
+
def unbind
|
172
179
|
call_handler_for(:disconnected, nil) || (EM.reactor_running? && EM.stop)
|
173
180
|
end
|
174
181
|
|
175
|
-
|
182
|
+
# @private
|
183
|
+
def receive_data(stanza)
|
176
184
|
catch(:halt) do
|
177
185
|
run_filters :before, stanza
|
178
186
|
handle_stanza stanza
|
@@ -180,11 +188,13 @@ module Blather
|
|
180
188
|
end
|
181
189
|
end
|
182
190
|
|
183
|
-
|
191
|
+
# @private
|
192
|
+
def setup?
|
184
193
|
@setup.is_a? Array
|
185
194
|
end
|
186
195
|
|
187
|
-
|
196
|
+
# @private
|
197
|
+
def setup(jid, password, host = nil, port = nil)
|
188
198
|
@jid = JID.new(jid)
|
189
199
|
@setup = [@jid, password]
|
190
200
|
@setup << host if host
|
@@ -192,21 +202,22 @@ module Blather
|
|
192
202
|
self
|
193
203
|
end
|
194
204
|
|
195
|
-
|
196
|
-
|
205
|
+
protected
|
206
|
+
|
207
|
+
def stream
|
197
208
|
@stream || raise('Stream not ready!')
|
198
209
|
end
|
199
210
|
|
200
|
-
def check_handler(type, guards)
|
211
|
+
def check_handler(type, guards)
|
201
212
|
Blather.logger.warn "Handler for type \"#{type}\" will never be called as it's not a registered type" unless current_handlers.include?(type)
|
202
213
|
check_guards guards
|
203
214
|
end
|
204
215
|
|
205
|
-
def current_handlers
|
216
|
+
def current_handlers
|
206
217
|
[:ready, :disconnected] + Stanza.handler_list + BlatherError.handler_list
|
207
218
|
end
|
208
219
|
|
209
|
-
def setup_initial_handlers
|
220
|
+
def setup_initial_handlers
|
210
221
|
register_handler :error do |err|
|
211
222
|
raise err
|
212
223
|
end
|
@@ -225,12 +236,12 @@ module Blather
|
|
225
236
|
end
|
226
237
|
end
|
227
238
|
|
228
|
-
def ready!
|
239
|
+
def ready!
|
229
240
|
@state = :ready
|
230
241
|
call_handler_for :ready, nil
|
231
242
|
end
|
232
243
|
|
233
|
-
def client_post_init
|
244
|
+
def client_post_init
|
234
245
|
write_with_handler Stanza::Iq::Roster.new do |node|
|
235
246
|
roster.process node
|
236
247
|
write @status
|
@@ -238,14 +249,14 @@ module Blather
|
|
238
249
|
end
|
239
250
|
end
|
240
251
|
|
241
|
-
def run_filters(type, stanza)
|
252
|
+
def run_filters(type, stanza)
|
242
253
|
@filters[type].each do |guards, handler, filter|
|
243
254
|
next if handler && !stanza.handler_hierarchy.include?(handler)
|
244
255
|
catch(:pass) { call_handler filter, guards, stanza }
|
245
256
|
end
|
246
257
|
end
|
247
258
|
|
248
|
-
def handle_stanza(stanza)
|
259
|
+
def handle_stanza(stanza)
|
249
260
|
if handler = @tmp_handlers.delete(stanza.id)
|
250
261
|
handler.call stanza
|
251
262
|
else
|
@@ -255,14 +266,14 @@ module Blather
|
|
255
266
|
end
|
256
267
|
end
|
257
268
|
|
258
|
-
def call_handler_for(type, stanza)
|
269
|
+
def call_handler_for(type, stanza)
|
259
270
|
return unless handler = @handlers[type]
|
260
271
|
handler.find do |guards, handler|
|
261
272
|
catch(:pass) { call_handler handler, guards, stanza }
|
262
273
|
end
|
263
274
|
end
|
264
275
|
|
265
|
-
def call_handler(handler, guards, stanza)
|
276
|
+
def call_handler(handler, guards, stanza)
|
266
277
|
if guards.first.respond_to?(:to_str)
|
267
278
|
result = stanza.find(*guards)
|
268
279
|
handler.call(stanza, result) unless result.empty?
|
@@ -303,7 +314,7 @@ module Blather
|
|
303
314
|
end
|
304
315
|
end
|
305
316
|
|
306
|
-
def check_guards(guards)
|
317
|
+
def check_guards(guards)
|
307
318
|
guards.each do |guard|
|
308
319
|
case guard
|
309
320
|
when Array
|
@@ -315,142 +326,6 @@ module Blather
|
|
315
326
|
end
|
316
327
|
end
|
317
328
|
end
|
318
|
-
|
319
|
-
class Caps < Blather::Stanza::DiscoInfo
|
320
|
-
def self.new
|
321
|
-
super :result
|
322
|
-
end
|
323
|
-
|
324
|
-
def ver
|
325
|
-
generate_ver identities, features
|
326
|
-
end
|
327
|
-
|
328
|
-
def node=(node)
|
329
|
-
@bare_node = node
|
330
|
-
super "#{node}##{ver}"
|
331
|
-
end
|
332
|
-
|
333
|
-
def identities=(identities)
|
334
|
-
super identities
|
335
|
-
regenerate_full_node
|
336
|
-
end
|
337
|
-
|
338
|
-
def features=(features)
|
339
|
-
super features
|
340
|
-
regenerate_full_node
|
341
|
-
end
|
342
|
-
|
343
|
-
def c
|
344
|
-
Blather::Stanza::Presence::C.new @bare_node, ver
|
345
|
-
end
|
346
|
-
|
347
|
-
private
|
348
|
-
|
349
|
-
def regenerate_full_node
|
350
|
-
self.node = @bare_node
|
351
|
-
end
|
352
|
-
|
353
|
-
def generate_ver_str(identities, features, forms = [])
|
354
|
-
# 1. Initialize an empty string S.
|
355
|
-
s = ''
|
356
|
-
|
357
|
-
# 2. Sort the service discovery identities by category and
|
358
|
-
# then by type (if it exists) and then by xml:lang (if it
|
359
|
-
# exists), formatted as CATEGORY '/' [TYPE] '/' [LANG] '/'
|
360
|
-
# [NAME]. Note that each slash is included even if the TYPE,
|
361
|
-
# LANG, or NAME is not included.
|
362
|
-
identities.sort! do |identity1, identity2|
|
363
|
-
cmp_result = nil
|
364
|
-
[:category, :type, :xml_lang, :name].each do |field|
|
365
|
-
value1 = identity1.send(field)
|
366
|
-
value2 = identity2.send(field)
|
367
|
-
|
368
|
-
if value1 != value2
|
369
|
-
cmp_result = value1 <=> value2
|
370
|
-
break
|
371
|
-
end
|
372
|
-
end
|
373
|
-
cmp_result
|
374
|
-
end
|
375
|
-
|
376
|
-
# 3. For each identity, append the 'category/type/lang/name' to
|
377
|
-
# S, followed by the '<' character.
|
378
|
-
s += identities.collect do |identity|
|
379
|
-
[:category, :type, :xml_lang, :name].collect do |field|
|
380
|
-
identity.send(field).to_s
|
381
|
-
end.join('/') + '<'
|
382
|
-
end.join
|
383
|
-
|
384
|
-
# 4. Sort the supported service discovery features.
|
385
|
-
features.sort! { |feature1, feature2| feature1.var <=> feature2.var }
|
386
|
-
|
387
|
-
# 5. For each feature, append the feature to S, followed by the
|
388
|
-
# '<' character.
|
389
|
-
s += features.collect { |feature| feature.var.to_s + '<' }.join
|
390
|
-
|
391
|
-
# 6. If the service discovery information response includes
|
392
|
-
# XEP-0128 data forms, sort the forms by the FORM_TYPE (i.e., by
|
393
|
-
# the XML character data of the <value/> element).
|
394
|
-
forms.sort! do |form1, form2|
|
395
|
-
fform_type1 = form1.field 'FORM_TYPE'
|
396
|
-
fform_type2 = form2.field 'FORM_TYPE'
|
397
|
-
form_type1 = fform_type1 ? fform_type1.values.to_s : nil
|
398
|
-
form_type2 = fform_type2 ? fform_type2.values.to_s : nil
|
399
|
-
form_type1 <=> form_type2
|
400
|
-
end
|
401
|
-
|
402
|
-
# 7. For each extended service discovery information form:
|
403
|
-
forms.each do |form|
|
404
|
-
# 7.1. Append the XML character data of the FORM_TYPE field's
|
405
|
-
# <value/> element, followed by the '<' character.
|
406
|
-
fform_type = form.field 'FORM_TYPE'
|
407
|
-
form_type = fform_type ? fform_type.values.to_s : nil
|
408
|
-
s += "#{form_type}<"
|
409
|
-
|
410
|
-
# 7.2. Sort the fields by the value of the "var" attribute
|
411
|
-
fields = form.fields.sort { |field1, field2| field1.var <=> field2.var }
|
412
|
-
|
413
|
-
# 7.3. For each field:
|
414
|
-
fields.each do |field|
|
415
|
-
# 7.3.1. Append the value of the "var" attribute, followed by
|
416
|
-
# the '<' character.
|
417
|
-
s += "#{field.var}<"
|
418
|
-
|
419
|
-
# 7.3.2. Sort values by the XML character data of the <value/> element
|
420
|
-
# values = field.values.sort { |value1, value2| value1 <=> value2 }
|
421
|
-
|
422
|
-
# 7.3.3. For each <value/> element, append the XML character
|
423
|
-
# data, followed by the '<' character.
|
424
|
-
# s += values.collect { |value| "#{value}<" }.join
|
425
|
-
s += "#{field.value}<"
|
426
|
-
end
|
427
|
-
end
|
428
|
-
s
|
429
|
-
end
|
430
|
-
|
431
|
-
def generate_ver(identities, features, forms = [], hash = 'sha-1')
|
432
|
-
s = generate_ver_str identities, features, forms
|
433
|
-
|
434
|
-
# 9. Compute the verification string by hashing S using the
|
435
|
-
# algorithm specified in the 'hash' attribute (e.g., SHA-1 as
|
436
|
-
# defined in RFC 3174). The hashed data MUST be generated
|
437
|
-
# with binary output and encoded using Base64 as specified in
|
438
|
-
# Section 4 of RFC 4648 (note: the Base64 output MUST NOT
|
439
|
-
# include whitespace and MUST set padding bits to zero).
|
440
|
-
|
441
|
-
# See http://www.iana.org/assignments/hash-function-text-names
|
442
|
-
hash_klass = case hash
|
443
|
-
when 'md2' then nil
|
444
|
-
when 'md5' then Digest::MD5
|
445
|
-
when 'sha-1' then Digest::SHA1
|
446
|
-
when 'sha-224' then nil
|
447
|
-
when 'sha-256' then Digest::SHA256
|
448
|
-
when 'sha-384' then Digest::SHA384
|
449
|
-
when 'sha-512' then Digest::SHA512
|
450
|
-
end
|
451
|
-
hash_klass ? [hash_klass::digest(s)].pack('m').strip : nil
|
452
|
-
end
|
453
|
-
end # Caps
|
454
329
|
end # Client
|
455
330
|
|
456
331
|
end # Blather
|