blather 0.4.16 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|