sprsquish-blather 0.3.4 → 0.4.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/LICENSE +1 -1
- data/README.rdoc +41 -12
- data/examples/echo.rb +1 -1
- data/examples/execute.rb +0 -5
- data/examples/pubsub/cli.rb +64 -0
- data/examples/pubsub/ping_pong.rb +18 -0
- data/examples/rosterprint.rb +14 -0
- data/examples/xmpp4r/echo.rb +35 -0
- data/lib/blather/client/client.rb +19 -13
- data/lib/blather/client/dsl/pubsub.rb +133 -0
- data/lib/blather/client/dsl.rb +16 -0
- data/lib/blather/client.rb +1 -1
- data/lib/blather/core_ext/active_support/inheritable_attributes.rb +117 -0
- data/lib/blather/core_ext/active_support.rb +1 -117
- data/lib/blather/core_ext/nokogiri.rb +35 -0
- data/lib/blather/errors/sasl_error.rb +3 -1
- data/lib/blather/errors/stanza_error.rb +10 -17
- data/lib/blather/errors/stream_error.rb +11 -14
- data/lib/blather/errors.rb +3 -20
- data/lib/blather/jid.rb +1 -0
- data/lib/blather/roster.rb +9 -0
- data/lib/blather/roster_item.rb +6 -1
- data/lib/blather/stanza/disco/disco_info.rb +45 -33
- data/lib/blather/stanza/disco/disco_items.rb +32 -21
- data/lib/blather/stanza/disco.rb +7 -1
- data/lib/blather/stanza/iq/query.rb +16 -8
- data/lib/blather/stanza/iq/roster.rb +33 -22
- data/lib/blather/stanza/iq.rb +13 -8
- data/lib/blather/stanza/message.rb +20 -31
- data/lib/blather/stanza/presence/status.rb +13 -21
- data/lib/blather/stanza/presence/subscription.rb +11 -16
- data/lib/blather/stanza/presence.rb +3 -5
- data/lib/blather/stanza/pubsub/affiliations.rb +50 -0
- data/lib/blather/stanza/pubsub/create.rb +43 -0
- data/lib/blather/stanza/pubsub/errors.rb +9 -0
- data/lib/blather/stanza/pubsub/event.rb +77 -0
- data/lib/blather/stanza/pubsub/items.rb +63 -0
- data/lib/blather/stanza/pubsub/publish.rb +58 -0
- data/lib/blather/stanza/pubsub/retract.rb +53 -0
- data/lib/blather/stanza/pubsub/subscribe.rb +42 -0
- data/lib/blather/stanza/pubsub/subscription.rb +66 -0
- data/lib/blather/stanza/pubsub/subscriptions.rb +55 -0
- data/lib/blather/stanza/pubsub/unsubscribe.rb +42 -0
- data/lib/blather/stanza/pubsub.rb +63 -0
- data/lib/blather/stanza/pubsub_owner/delete.rb +34 -0
- data/lib/blather/stanza/pubsub_owner/purge.rb +34 -0
- data/lib/blather/stanza/pubsub_owner.rb +41 -0
- data/lib/blather/stanza.rb +35 -18
- data/lib/blather/stream/client.rb +1 -2
- data/lib/blather/stream/component.rb +9 -5
- data/lib/blather/stream/features/resource.rb +63 -0
- data/lib/blather/stream/{sasl.rb → features/sasl.rb} +53 -52
- data/lib/blather/stream/features/session.rb +44 -0
- data/lib/blather/stream/features/tls.rb +28 -0
- data/lib/blather/stream/features.rb +53 -0
- data/lib/blather/stream/parser.rb +70 -46
- data/lib/blather/stream.rb +76 -168
- data/lib/blather/xmpp_node.rb +113 -52
- data/lib/blather.rb +35 -12
- data/spec/blather/client/client_spec.rb +44 -58
- data/spec/blather/client/dsl/pubsub_spec.rb +465 -0
- data/spec/blather/client/dsl_spec.rb +19 -6
- data/spec/blather/core_ext/nokogiri_spec.rb +83 -0
- data/spec/blather/errors/sasl_error_spec.rb +8 -8
- data/spec/blather/errors/stanza_error_spec.rb +25 -33
- data/spec/blather/errors/stream_error_spec.rb +21 -16
- data/spec/blather/errors_spec.rb +4 -11
- data/spec/blather/jid_spec.rb +31 -30
- data/spec/blather/roster_item_spec.rb +34 -23
- data/spec/blather/roster_spec.rb +27 -12
- data/spec/blather/stanza/discos/disco_info_spec.rb +61 -42
- data/spec/blather/stanza/discos/disco_items_spec.rb +47 -35
- data/spec/blather/stanza/iq/query_spec.rb +34 -11
- data/spec/blather/stanza/iq/roster_spec.rb +47 -30
- data/spec/blather/stanza/iq_spec.rb +19 -14
- data/spec/blather/stanza/message_spec.rb +30 -17
- data/spec/blather/stanza/presence/status_spec.rb +43 -20
- data/spec/blather/stanza/presence/subscription_spec.rb +41 -21
- data/spec/blather/stanza/presence_spec.rb +34 -21
- data/spec/blather/stanza/pubsub/affiliations_spec.rb +57 -0
- data/spec/blather/stanza/pubsub/create_spec.rb +56 -0
- data/spec/blather/stanza/pubsub/event_spec.rb +84 -0
- data/spec/blather/stanza/pubsub/items_spec.rb +79 -0
- data/spec/blather/stanza/pubsub/publish_spec.rb +83 -0
- data/spec/blather/stanza/pubsub/retract_spec.rb +75 -0
- data/spec/blather/stanza/pubsub/subscribe_spec.rb +61 -0
- data/spec/blather/stanza/pubsub/subscription_spec.rb +97 -0
- data/spec/blather/stanza/pubsub/subscriptions_spec.rb +59 -0
- data/spec/blather/stanza/pubsub/unsubscribe_spec.rb +61 -0
- data/spec/blather/stanza/pubsub_owner/delete_spec.rb +50 -0
- data/spec/blather/stanza/pubsub_owner/purge_spec.rb +50 -0
- data/spec/blather/stanza/pubsub_owner_spec.rb +27 -0
- data/spec/blather/stanza/pubsub_spec.rb +62 -0
- data/spec/blather/stanza_spec.rb +53 -38
- data/spec/blather/stream/client_spec.rb +231 -88
- data/spec/blather/stream/component_spec.rb +14 -5
- data/spec/blather/stream/parser_spec.rb +145 -0
- data/spec/blather/xmpp_node_spec.rb +192 -96
- data/spec/fixtures/pubsub.rb +311 -0
- data/spec/spec_helper.rb +5 -4
- metadata +53 -17
- data/Rakefile +0 -139
- data/ext/extconf.rb +0 -65
- data/ext/push_parser.c +0 -209
- data/lib/blather/core_ext/libxml.rb +0 -28
- data/lib/blather/stream/resource.rb +0 -48
- data/lib/blather/stream/session.rb +0 -36
- data/lib/blather/stream/stream_handler.rb +0 -39
- data/lib/blather/stream/tls.rb +0 -33
- data/spec/blather/core_ext/libxml_spec.rb +0 -58
@@ -0,0 +1,53 @@
|
|
1
|
+
module Blather
|
2
|
+
class Stanza
|
3
|
+
class PubSub
|
4
|
+
|
5
|
+
class Retract < PubSub
|
6
|
+
register :pubsub_retract, :retract, self.registered_ns
|
7
|
+
|
8
|
+
include Enumerable
|
9
|
+
alias_method :find, :xpath
|
10
|
+
|
11
|
+
def self.new(host = nil, node = nil, type = :set, retractions = [])
|
12
|
+
new_node = super(type, host)
|
13
|
+
new_node.node = node
|
14
|
+
new_node.retractions = retractions
|
15
|
+
new_node
|
16
|
+
end
|
17
|
+
|
18
|
+
def node
|
19
|
+
retract[:node]
|
20
|
+
end
|
21
|
+
|
22
|
+
def node=(node)
|
23
|
+
retract[:node] = node
|
24
|
+
end
|
25
|
+
|
26
|
+
def retract
|
27
|
+
unless retract = pubsub.find_first('ns:retract', :ns => self.class.registered_ns)
|
28
|
+
self.pubsub << (retract = XMPPNode.new('retract', self.document))
|
29
|
+
retract.namespace = self.pubsub.namespace
|
30
|
+
end
|
31
|
+
retract
|
32
|
+
end
|
33
|
+
|
34
|
+
def retractions=(retractions = [])
|
35
|
+
[retractions].flatten.each { |id| self.retract << PubSubItem.new(id, nil, self.document) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def retractions
|
39
|
+
retract.find('ns:item', :ns => self.class.registered_ns).map { |i| i[:id] }
|
40
|
+
end
|
41
|
+
|
42
|
+
def each(&block)
|
43
|
+
retractions.each &block
|
44
|
+
end
|
45
|
+
|
46
|
+
def size
|
47
|
+
retractions.size
|
48
|
+
end
|
49
|
+
end #Retract
|
50
|
+
|
51
|
+
end #PubSub
|
52
|
+
end #Stanza
|
53
|
+
end #Blather
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Blather
|
2
|
+
class Stanza
|
3
|
+
class PubSub
|
4
|
+
|
5
|
+
class Subscribe < PubSub
|
6
|
+
register :pubsub_subscribe, :subscribe, self.registered_ns
|
7
|
+
|
8
|
+
def self.new(type = :set, host = nil, node = nil, jid = nil)
|
9
|
+
new_node = super(type, host)
|
10
|
+
new_node.node = node
|
11
|
+
new_node.jid = jid
|
12
|
+
new_node
|
13
|
+
end
|
14
|
+
|
15
|
+
def jid
|
16
|
+
JID.new(subscribe[:jid])
|
17
|
+
end
|
18
|
+
|
19
|
+
def jid=(jid)
|
20
|
+
subscribe[:jid] = jid
|
21
|
+
end
|
22
|
+
|
23
|
+
def node
|
24
|
+
subscribe[:node]
|
25
|
+
end
|
26
|
+
|
27
|
+
def node=(node)
|
28
|
+
subscribe[:node] = node
|
29
|
+
end
|
30
|
+
|
31
|
+
def subscribe
|
32
|
+
unless subscribe = pubsub.find_first('ns:subscribe', :ns => self.class.registered_ns)
|
33
|
+
self.pubsub << (subscribe = XMPPNode.new('subscribe', self.document))
|
34
|
+
subscribe.namespace = self.pubsub.namespace
|
35
|
+
end
|
36
|
+
subscribe
|
37
|
+
end
|
38
|
+
end #Subscribe
|
39
|
+
|
40
|
+
end #PubSub
|
41
|
+
end #Stanza
|
42
|
+
end #Blather
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Blather
|
2
|
+
class Stanza
|
3
|
+
class PubSub
|
4
|
+
|
5
|
+
class Subscription < PubSub
|
6
|
+
VALID_TYPES = [:none, :pending, :subscribed, :unconfigured]
|
7
|
+
|
8
|
+
register :pubsub_subscription, :subscription, self.registered_ns
|
9
|
+
|
10
|
+
def self.new(type = :result, host = nil, node = nil, jid = nil, subid = nil, subscription = nil)
|
11
|
+
new_node = super(type, host)
|
12
|
+
new_node.node = node
|
13
|
+
new_node.jid = jid
|
14
|
+
new_node.subid = subid
|
15
|
+
new_node.subscription = subscription
|
16
|
+
new_node
|
17
|
+
end
|
18
|
+
|
19
|
+
attribute_helpers_for :subscription, VALID_TYPES
|
20
|
+
|
21
|
+
def jid
|
22
|
+
JID.new(subscription_node[:jid])
|
23
|
+
end
|
24
|
+
|
25
|
+
def jid=(jid)
|
26
|
+
subscription_node[:jid] = jid
|
27
|
+
end
|
28
|
+
|
29
|
+
def node
|
30
|
+
subscription_node[:node]
|
31
|
+
end
|
32
|
+
|
33
|
+
def node=(node)
|
34
|
+
subscription_node[:node] = node
|
35
|
+
end
|
36
|
+
|
37
|
+
def subid
|
38
|
+
subscription_node[:subid]
|
39
|
+
end
|
40
|
+
|
41
|
+
def subid=(subid)
|
42
|
+
subscription_node[:subid] = subid
|
43
|
+
end
|
44
|
+
|
45
|
+
def subscription
|
46
|
+
s = subscription_node[:subscription]
|
47
|
+
s.to_sym if s
|
48
|
+
end
|
49
|
+
|
50
|
+
def subscription=(subscription)
|
51
|
+
raise ArgumentError, "Invalid Type (#{type}), use: #{VALID_TYPES*' '}" if subscription && !VALID_TYPES.include?(subscription.to_sym)
|
52
|
+
subscription_node[:subscription] = subscription
|
53
|
+
end
|
54
|
+
|
55
|
+
def subscription_node
|
56
|
+
unless subscription = pubsub.find_first('ns:subscription', :ns => self.class.registered_ns)
|
57
|
+
self.pubsub << (subscription = XMPPNode.new('subscription', self.document))
|
58
|
+
subscription.namespace = self.pubsub.namespace
|
59
|
+
end
|
60
|
+
subscription
|
61
|
+
end
|
62
|
+
end #Subscribe
|
63
|
+
|
64
|
+
end #PubSub
|
65
|
+
end #Stanza
|
66
|
+
end #Blather
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Blather
|
2
|
+
class Stanza
|
3
|
+
class PubSub
|
4
|
+
|
5
|
+
class Subscriptions < PubSub
|
6
|
+
register :pubsub_subscriptions, :subscriptions, self.registered_ns
|
7
|
+
|
8
|
+
include Enumerable
|
9
|
+
alias_method :find, :xpath
|
10
|
+
|
11
|
+
##
|
12
|
+
# Ensure the namespace is set to the query node
|
13
|
+
def self.new(type = nil, host = nil)
|
14
|
+
new_node = super type
|
15
|
+
new_node.to = host
|
16
|
+
new_node.subscriptions
|
17
|
+
new_node
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# Kill the pubsub node before running inherit
|
22
|
+
def inherit(node)
|
23
|
+
subscriptions.remove
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
def subscriptions
|
28
|
+
aff = pubsub.find_first('subscriptions', self.class.registered_ns)
|
29
|
+
(self.pubsub << (aff = XMPPNode.new('subscriptions', self.document))) unless aff
|
30
|
+
aff
|
31
|
+
end
|
32
|
+
|
33
|
+
def each(&block)
|
34
|
+
list.each &block
|
35
|
+
end
|
36
|
+
|
37
|
+
def size
|
38
|
+
list.size
|
39
|
+
end
|
40
|
+
|
41
|
+
def list
|
42
|
+
subscriptions.find('//ns:subscription', :ns => self.class.registered_ns).inject({}) do |hash, item|
|
43
|
+
hash[item[:subscription].to_sym] ||= []
|
44
|
+
hash[item[:subscription].to_sym] << {
|
45
|
+
:node => item[:node],
|
46
|
+
:jid => item[:jid]
|
47
|
+
}
|
48
|
+
hash
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end #Subscriptions
|
52
|
+
|
53
|
+
end #PubSub
|
54
|
+
end #Stanza
|
55
|
+
end #Blather
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Blather
|
2
|
+
class Stanza
|
3
|
+
class PubSub
|
4
|
+
|
5
|
+
class Unsubscribe < PubSub
|
6
|
+
register :pubsub_unsubscribe, :unsubscribe, self.registered_ns
|
7
|
+
|
8
|
+
def self.new(type = :set, host = nil, node = nil, jid = nil)
|
9
|
+
new_node = super(type, host)
|
10
|
+
new_node.node = node
|
11
|
+
new_node.jid = jid
|
12
|
+
new_node
|
13
|
+
end
|
14
|
+
|
15
|
+
def jid
|
16
|
+
JID.new(unsubscribe[:jid])
|
17
|
+
end
|
18
|
+
|
19
|
+
def jid=(jid)
|
20
|
+
unsubscribe[:jid] = jid
|
21
|
+
end
|
22
|
+
|
23
|
+
def node
|
24
|
+
unsubscribe[:node]
|
25
|
+
end
|
26
|
+
|
27
|
+
def node=(node)
|
28
|
+
unsubscribe[:node] = node
|
29
|
+
end
|
30
|
+
|
31
|
+
def unsubscribe
|
32
|
+
unless unsubscribe = pubsub.find_first('ns:unsubscribe', :ns => self.class.registered_ns)
|
33
|
+
self.pubsub << (unsubscribe = XMPPNode.new('unsubscribe', self.document))
|
34
|
+
unsubscribe.namespace = self.pubsub.namespace
|
35
|
+
end
|
36
|
+
unsubscribe
|
37
|
+
end
|
38
|
+
end #Unsubscribe
|
39
|
+
|
40
|
+
end #PubSub
|
41
|
+
end #Stanza
|
42
|
+
end #Blather
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Blather
|
2
|
+
class Stanza
|
3
|
+
|
4
|
+
class PubSub < Iq
|
5
|
+
register :pubsub_node, :pubsub, 'http://jabber.org/protocol/pubsub'
|
6
|
+
|
7
|
+
def self.import(node)
|
8
|
+
klass = nil
|
9
|
+
if pubsub = node.document.find_first('//ns:pubsub', :ns => self.registered_ns)
|
10
|
+
pubsub.children.each { |e| break if klass = class_from_registration(e.element_name, (e.namespace.href if e.namespace)) }
|
11
|
+
end
|
12
|
+
(klass || self).new(node[:type]).inherit(node)
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# Ensure the namespace is set to the query node
|
17
|
+
def self.new(type = nil, host = nil)
|
18
|
+
new_node = super type
|
19
|
+
new_node.to = host
|
20
|
+
new_node.pubsub
|
21
|
+
new_node
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# Kill the pubsub node before running inherit
|
26
|
+
def inherit(node)
|
27
|
+
remove_children :pubsub
|
28
|
+
super
|
29
|
+
end
|
30
|
+
|
31
|
+
def pubsub
|
32
|
+
p = find_first('ns:pubsub', :ns => self.class.registered_ns) ||
|
33
|
+
find_first('pubsub', :ns => self.class.registered_ns)
|
34
|
+
|
35
|
+
unless p
|
36
|
+
self << (p = XMPPNode.new('pubsub', self.document))
|
37
|
+
p.namespace = self.class.registered_ns
|
38
|
+
end
|
39
|
+
p
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class PubSubItem < XMPPNode
|
44
|
+
def self.new(id = nil, payload = nil, document = nil)
|
45
|
+
new_node = super 'item', document
|
46
|
+
new_node.id = id
|
47
|
+
new_node.payload = payload if payload
|
48
|
+
new_node
|
49
|
+
end
|
50
|
+
|
51
|
+
attribute_accessor :id
|
52
|
+
|
53
|
+
def payload=(payload = nil)
|
54
|
+
self.content = payload
|
55
|
+
end
|
56
|
+
|
57
|
+
def payload
|
58
|
+
content.empty? ? nil : content
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end #Stanza
|
63
|
+
end #Blather
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Blather
|
2
|
+
class Stanza
|
3
|
+
class PubSubOwner
|
4
|
+
|
5
|
+
class Delete < PubSubOwner
|
6
|
+
|
7
|
+
register :pubsub_delete, :delete, self.registered_ns
|
8
|
+
|
9
|
+
def self.new(type = :set, host = nil, node = nil)
|
10
|
+
new_node = super(type, host)
|
11
|
+
new_node.node = node
|
12
|
+
new_node
|
13
|
+
end
|
14
|
+
|
15
|
+
def node
|
16
|
+
delete_node[:node]
|
17
|
+
end
|
18
|
+
|
19
|
+
def node=(node)
|
20
|
+
delete_node[:node] = node
|
21
|
+
end
|
22
|
+
|
23
|
+
def delete_node
|
24
|
+
unless delete_node = pubsub.find_first('ns:delete', :ns => self.class.registered_ns)
|
25
|
+
self.pubsub << (delete_node = XMPPNode.new('delete', self.document))
|
26
|
+
delete_node.namespace = self.pubsub.namespace
|
27
|
+
end
|
28
|
+
delete_node
|
29
|
+
end
|
30
|
+
end #Retract
|
31
|
+
|
32
|
+
end #PubSub
|
33
|
+
end #Stanza
|
34
|
+
end #Blather
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Blather
|
2
|
+
class Stanza
|
3
|
+
class PubSubOwner
|
4
|
+
|
5
|
+
class Purge < PubSubOwner
|
6
|
+
|
7
|
+
register :pubsub_purge, :purge, self.registered_ns
|
8
|
+
|
9
|
+
def self.new(type = :set, host = nil, node = nil)
|
10
|
+
new_node = super(type, host)
|
11
|
+
new_node.node = node
|
12
|
+
new_node
|
13
|
+
end
|
14
|
+
|
15
|
+
def node
|
16
|
+
purge_node[:node]
|
17
|
+
end
|
18
|
+
|
19
|
+
def node=(node)
|
20
|
+
purge_node[:node] = node
|
21
|
+
end
|
22
|
+
|
23
|
+
def purge_node
|
24
|
+
unless purge_node = pubsub.find_first('ns:purge', :ns => self.class.registered_ns)
|
25
|
+
self.pubsub << (purge_node = XMPPNode.new('purge', self.document))
|
26
|
+
purge_node.namespace = self.pubsub.namespace
|
27
|
+
end
|
28
|
+
purge_node
|
29
|
+
end
|
30
|
+
end #Retract
|
31
|
+
|
32
|
+
end #PubSub
|
33
|
+
end #Stanza
|
34
|
+
end #Blather
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Blather
|
2
|
+
class Stanza
|
3
|
+
|
4
|
+
class PubSubOwner < Iq
|
5
|
+
register :pubsub_owner, :pubsub, 'http://jabber.org/protocol/pubsub#owner'
|
6
|
+
|
7
|
+
def self.import(node)
|
8
|
+
klass = nil
|
9
|
+
if pubsub = node.document.find_first('//ns:pubsub', :ns => self.registered_ns)
|
10
|
+
pubsub.children.each { |e| break if klass = class_from_registration(e.element_name, (e.namespace.href if e.namespace)) }
|
11
|
+
end
|
12
|
+
(klass || self).new(node[:type]).inherit(node)
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# Ensure the namespace is set to the query node
|
17
|
+
def self.new(type = nil, host = nil)
|
18
|
+
new_node = super type
|
19
|
+
new_node.to = host
|
20
|
+
new_node.pubsub
|
21
|
+
new_node
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# Kill the pubsub node before running inherit
|
26
|
+
def inherit(node)
|
27
|
+
remove_children :pubsub
|
28
|
+
super
|
29
|
+
end
|
30
|
+
|
31
|
+
def pubsub
|
32
|
+
unless p = find_first('ns:pubsub', :ns => self.class.registered_ns)
|
33
|
+
self << (p = XMPPNode.new('pubsub', self.document))
|
34
|
+
p.namespace = self.class.registered_ns
|
35
|
+
end
|
36
|
+
p
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end #Stanza
|
41
|
+
end #Blather
|
data/lib/blather/stanza.rb
CHANGED
@@ -14,12 +14,12 @@ module Blather
|
|
14
14
|
# that inherits Stanza can register a callback for itself
|
15
15
|
# which is added to a list and iterated over when looking for
|
16
16
|
# a callback to use
|
17
|
-
def self.register(
|
18
|
-
@@handler_list <<
|
17
|
+
def self.register(handler, name = nil, ns = nil)
|
18
|
+
@@handler_list << handler
|
19
19
|
self.handler_heirarchy ||= []
|
20
|
-
self.handler_heirarchy.unshift
|
20
|
+
self.handler_heirarchy.unshift handler
|
21
21
|
|
22
|
-
name = name || self.
|
22
|
+
name = name || self.registered_name || handler
|
23
23
|
super name, ns
|
24
24
|
end
|
25
25
|
|
@@ -44,24 +44,32 @@ module Blather
|
|
44
44
|
##
|
45
45
|
# Automatically set the stanza's ID
|
46
46
|
# and attach it to a document so XPath searching works
|
47
|
-
def
|
48
|
-
super
|
49
|
-
|
50
|
-
|
51
|
-
self.id = self.class.next_id
|
47
|
+
def self.new(name = nil)
|
48
|
+
node = super
|
49
|
+
node.name = name.to_s if name
|
50
|
+
node
|
52
51
|
end
|
53
52
|
|
54
53
|
##
|
55
|
-
# Helper method to
|
56
|
-
|
57
|
-
|
54
|
+
# Helper method to generate stanza guard methods
|
55
|
+
#
|
56
|
+
# attribute_helpers_for(:type, [:subscribe, :unsubscribe])
|
57
|
+
#
|
58
|
+
# This generates "subscribe?" and "unsubscribe?" methods that return
|
59
|
+
# true if self.type == :subscribe or :unsubscribe, respectively.
|
60
|
+
def self.attribute_helpers_for(attr, values)
|
61
|
+
[values].flatten.each do |v|
|
62
|
+
define_method("#{v}?") { __send__(attr) == v }
|
63
|
+
end
|
58
64
|
end
|
59
65
|
|
66
|
+
attribute_helpers_for(:type, :error)
|
67
|
+
|
60
68
|
##
|
61
69
|
# Copies itself then swaps from and to
|
62
70
|
# then returns the new stanza
|
63
71
|
def reply
|
64
|
-
self.
|
72
|
+
self.dup.reply!
|
65
73
|
end
|
66
74
|
|
67
75
|
##
|
@@ -71,23 +79,23 @@ module Blather
|
|
71
79
|
self
|
72
80
|
end
|
73
81
|
|
74
|
-
attribute_accessor :id
|
82
|
+
attribute_accessor :id
|
75
83
|
|
76
84
|
attribute_writer :to, :from
|
77
85
|
|
78
86
|
##
|
79
87
|
# returns:: JID created from the "to" value of the stanza
|
80
88
|
def to
|
81
|
-
JID.new(
|
89
|
+
JID.new(self[:to]) if self[:to]
|
82
90
|
end
|
83
91
|
|
84
92
|
##
|
85
93
|
# returns:: JID created from the "from" value of the stanza
|
86
94
|
def from
|
87
|
-
JID.new(
|
95
|
+
JID.new(self[:from]) if self[:from]
|
88
96
|
end
|
89
97
|
|
90
|
-
attribute_accessor :type
|
98
|
+
attribute_accessor :type, :call => :to_sym
|
91
99
|
|
92
100
|
##
|
93
101
|
# Transform the stanza into a stanza error
|
@@ -96,5 +104,14 @@ module Blather
|
|
96
104
|
def as_error(name, type, text = nil, extras = [])
|
97
105
|
StanzaError.new self, name, type, text, extras
|
98
106
|
end
|
107
|
+
|
108
|
+
protected
|
109
|
+
def reply_if_needed!
|
110
|
+
unless @reversed_endpoints
|
111
|
+
reply!
|
112
|
+
@reversed_endpoints = true
|
113
|
+
end
|
114
|
+
self
|
115
|
+
end
|
99
116
|
end
|
100
|
-
end
|
117
|
+
end
|
@@ -6,14 +6,13 @@ class Stream
|
|
6
6
|
VERSION = '1.0'
|
7
7
|
NAMESPACE = 'jabber:client'
|
8
8
|
|
9
|
-
protected
|
10
9
|
def start
|
11
10
|
@parser = Parser.new self
|
12
11
|
start_stream = <<-STREAM
|
13
12
|
<stream:stream
|
14
13
|
to='#{@to}'
|
15
14
|
xmlns='#{NAMESPACE}'
|
16
|
-
xmlns:stream='
|
15
|
+
xmlns:stream='#{STREAM_NS}'
|
17
16
|
version='#{VERSION}'
|
18
17
|
xml:lang='#{LANG}'
|
19
18
|
>
|
@@ -6,24 +6,28 @@ class Stream
|
|
6
6
|
|
7
7
|
def receive(node) # :nodoc:
|
8
8
|
if node.element_name == 'handshake'
|
9
|
-
|
9
|
+
ready!
|
10
10
|
else
|
11
11
|
super
|
12
12
|
end
|
13
13
|
|
14
|
-
if node.
|
15
|
-
send("<handshake>#{Digest::SHA1.hexdigest(@node['id']+@
|
14
|
+
if node.document.find_first('/stream:stream[not(stream:error)]', :xmlns => NAMESPACE, :stream => STREAM_NS)
|
15
|
+
send("<handshake>#{Digest::SHA1.hexdigest(@node['id']+@password)}</handshake>")
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
|
19
|
+
def send(stanza)
|
20
|
+
stanza.from ||= self.jid if stanza.respond_to?(:from) && stanza.respond_to?(:from=)
|
21
|
+
super stanza
|
22
|
+
end
|
23
|
+
|
20
24
|
def start
|
21
25
|
@parser = Parser.new self
|
22
26
|
start_stream = <<-STREAM
|
23
27
|
<stream:stream
|
24
28
|
to='#{@jid}'
|
25
29
|
xmlns='#{NAMESPACE}'
|
26
|
-
xmlns:stream='
|
30
|
+
xmlns:stream='#{STREAM_NS}'
|
27
31
|
>
|
28
32
|
STREAM
|
29
33
|
send start_stream.gsub(/\s+/, ' ')
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Blather # :nodoc:
|
2
|
+
class Stream # :nodoc:
|
3
|
+
|
4
|
+
class Resource < Features # :nodoc:
|
5
|
+
BIND_NS = 'urn:ietf:params:xml:ns:xmpp-bind'.freeze
|
6
|
+
register BIND_NS
|
7
|
+
|
8
|
+
def initialize(stream, succeed, fail)
|
9
|
+
super
|
10
|
+
@jid = stream.jid
|
11
|
+
end
|
12
|
+
|
13
|
+
def receive_data(stanza)
|
14
|
+
@node = stanza
|
15
|
+
case stanza.element_name
|
16
|
+
when 'bind' then bind
|
17
|
+
when 'iq' then result
|
18
|
+
else fail!(UnknownResponse.new(@node))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
##
|
24
|
+
# Respond to the bind request
|
25
|
+
# If @jid has a resource set already request it from the server
|
26
|
+
def bind
|
27
|
+
response = Stanza::Iq.new :set
|
28
|
+
@id = response.id
|
29
|
+
|
30
|
+
response << (binder = XMPPNode.new('bind', response.document))
|
31
|
+
binder.namespace = BIND_NS
|
32
|
+
|
33
|
+
if @jid.resource
|
34
|
+
binder << (resource = XMPPNode.new('resource', binder.document))
|
35
|
+
resource.content = @jid.resource
|
36
|
+
end
|
37
|
+
|
38
|
+
@stream.send response
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Process the result from the server
|
43
|
+
# Sets the sends the JID (now bound to a resource)
|
44
|
+
# back to the stream
|
45
|
+
def result
|
46
|
+
if @node[:type] == 'error'
|
47
|
+
fail! StanzaError.import(@node)
|
48
|
+
return
|
49
|
+
end
|
50
|
+
|
51
|
+
Blather.logger.debug "RESOURCE NODE #{@node}"
|
52
|
+
# ensure this is a response to our original request
|
53
|
+
if @id == @node['id']
|
54
|
+
@stream.jid = JID.new @node.find_first('//bind/bind_ns:jid', :bind_ns => BIND_NS).content
|
55
|
+
succeed!
|
56
|
+
else
|
57
|
+
fail!("BIND result ID mismatch. Expected: #{@id}. Received: #{@node['id']}")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end #Resource
|
61
|
+
|
62
|
+
end #Stream
|
63
|
+
end #Blather
|