sprsquish-blather 0.1 → 0.2.3

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.
Files changed (73) hide show
  1. data/LICENSE +2 -0
  2. data/README.rdoc +100 -0
  3. data/Rakefile +110 -0
  4. data/examples/drb_client.rb +5 -0
  5. data/examples/echo.rb +18 -0
  6. data/ext/extconf.rb +65 -0
  7. data/ext/push_parser.c +231 -0
  8. data/lib/blather/client.rb +219 -44
  9. data/lib/blather/{core/sugar.rb → core_ext/active_support.rb} +25 -13
  10. data/lib/blather/core_ext/libxml.rb +28 -0
  11. data/lib/blather/errors/sasl_error.rb +87 -0
  12. data/lib/blather/errors/stanza_error.rb +262 -0
  13. data/lib/blather/errors/stream_error.rb +253 -0
  14. data/lib/blather/errors.rb +48 -0
  15. data/lib/blather/{core/jid.rb → jid.rb} +15 -26
  16. data/lib/blather/{core/roster.rb → roster.rb} +22 -0
  17. data/lib/blather/{core/roster_item.rb → roster_item.rb} +39 -8
  18. data/lib/blather/stanza/iq/disco.rb +11 -0
  19. data/lib/blather/stanza/iq/discos/disco_info.rb +86 -0
  20. data/lib/blather/stanza/iq/discos/disco_items.rb +61 -0
  21. data/lib/blather/stanza/iq/query.rb +51 -0
  22. data/lib/blather/stanza/iq/roster.rb +90 -0
  23. data/lib/blather/stanza/iq.rb +38 -0
  24. data/lib/blather/stanza/message.rb +58 -0
  25. data/lib/blather/stanza/presence/status.rb +78 -0
  26. data/lib/blather/stanza/presence/subscription.rb +72 -0
  27. data/lib/blather/stanza/presence.rb +45 -0
  28. data/lib/blather/stanza.rb +101 -0
  29. data/lib/blather/stream/client.rb +26 -0
  30. data/lib/blather/stream/component.rb +34 -0
  31. data/lib/blather/stream/parser.rb +70 -0
  32. data/lib/blather/stream/resource.rb +48 -0
  33. data/lib/blather/stream/sasl.rb +173 -0
  34. data/lib/blather/stream/session.rb +36 -0
  35. data/lib/blather/stream/stream_handler.rb +39 -0
  36. data/lib/blather/stream/tls.rb +33 -0
  37. data/lib/blather/stream.rb +249 -0
  38. data/lib/blather/xmpp_node.rb +199 -0
  39. data/lib/blather.rb +40 -41
  40. data/spec/blather/core_ext/libxml_spec.rb +58 -0
  41. data/spec/blather/errors/sasl_error_spec.rb +56 -0
  42. data/spec/blather/errors/stanza_error_spec.rb +148 -0
  43. data/spec/blather/errors/stream_error_spec.rb +114 -0
  44. data/spec/blather/errors_spec.rb +40 -0
  45. data/spec/blather/{core/jid_spec.rb → jid_spec.rb} +9 -1
  46. data/spec/blather/{core/roster_item_spec.rb → roster_item_spec.rb} +6 -1
  47. data/spec/blather/{core/roster_spec.rb → roster_spec.rb} +16 -6
  48. data/spec/blather/stanza/iq/discos/disco_info_spec.rb +207 -0
  49. data/spec/blather/stanza/iq/discos/disco_items_spec.rb +136 -0
  50. data/spec/blather/stanza/iq/query_spec.rb +34 -0
  51. data/spec/blather/stanza/iq/roster_spec.rb +123 -0
  52. data/spec/blather/stanza/iq_spec.rb +40 -0
  53. data/spec/blather/stanza/message_spec.rb +52 -0
  54. data/spec/blather/stanza/presence/status_spec.rb +102 -0
  55. data/spec/blather/stanza/presence/subscription_spec.rb +85 -0
  56. data/spec/blather/stanza/presence_spec.rb +53 -0
  57. data/spec/blather/{core/stanza_spec.rb → stanza_spec.rb} +14 -2
  58. data/spec/blather/stream/client_spec.rb +787 -0
  59. data/spec/blather/stream/component_spec.rb +86 -0
  60. data/spec/blather/{core/xmpp_node_spec.rb → xmpp_node_spec.rb} +76 -23
  61. data/spec/build_safe.rb +20 -0
  62. data/spec/spec_helper.rb +7 -17
  63. metadata +79 -59
  64. data/CHANGELOG +0 -1
  65. data/blather.gemspec +0 -73
  66. data/lib/blather/callback.rb +0 -24
  67. data/lib/blather/core/errors.rb +0 -24
  68. data/lib/blather/core/stanza.rb +0 -90
  69. data/lib/blather/core/stream.rb +0 -179
  70. data/lib/blather/core/xmpp_node.rb +0 -95
  71. data/lib/blather/extensions/last_activity.rb +0 -57
  72. data/lib/blather/extensions/version.rb +0 -85
  73. data/spec/blather/core/stream_spec.rb +0 -263
@@ -1,90 +0,0 @@
1
- module Blather
2
- class Stanza < XMPPNode
3
- @@registered_callbacks = []
4
-
5
- def self.registered_callbacks
6
- @@registered_callbacks
7
- end
8
-
9
- class_inheritable_array :callback_heirarchy
10
-
11
- def self.register(callback_type, name = nil, xmlns = nil)
12
- @@registered_callbacks << callback_type
13
-
14
- self.callback_heirarchy ||= []
15
- self.callback_heirarchy.unshift callback_type
16
-
17
- name = name || self.name || callback_type
18
- super name, xmlns
19
- end
20
-
21
- def self.next_id
22
- @@last_id ||= 0
23
- @@last_id += 1
24
- 'blather%04x' % @@last_id
25
- end
26
-
27
- def self.import(node)
28
- self.new(node.element_name).inherit(node)
29
- end
30
-
31
- def self.new(elem_name = nil)
32
- elem = super
33
- elem.id = next_id
34
- XML::Document.new.root = elem
35
- elem
36
- end
37
-
38
- def error?
39
- self.type == :error
40
- end
41
-
42
- def reply
43
- elem = self.copy(true)
44
- elem.to, elem.from = self.from, self.to
45
- elem
46
- end
47
-
48
- def reply!
49
- self.to, self.from = self.from, self.to
50
- self
51
- end
52
-
53
- def id=(id)
54
- attributes.remove :id
55
- self['id'] = id if id
56
- end
57
-
58
- def id
59
- self['id']
60
- end
61
-
62
- def to=(to)
63
- attributes.remove :to
64
- self['to'] = to.to_s if to
65
- end
66
-
67
- def to
68
- JID.new(self['to']) if self['to']
69
- end
70
-
71
- def from=(from)
72
- attributes.remove :from
73
- self['from'] = from.to_s if from
74
- end
75
-
76
- def from
77
- JID.new(self['from']) if self['from']
78
- end
79
-
80
- def type=(type)
81
- attributes.remove :type
82
- self['type'] = type.to_s
83
- end
84
-
85
- def type
86
- self['type'].to_sym if self['type']
87
- end
88
-
89
- end
90
- end
@@ -1,179 +0,0 @@
1
- module Blather
2
-
3
- module Stream
4
-
5
- # Connect to the server
6
- def self.start(client, jid, pass, host = nil, port = 5222)
7
- jid = JID.new jid
8
- host ||= jid.domain
9
-
10
- EM.connect host, port, self, client, jid, pass
11
- end
12
-
13
- def initialize(client, jid, pass)
14
- super()
15
-
16
- @client = client
17
-
18
- self.jid = jid
19
- @pass = pass
20
-
21
- @to = @jid.domain
22
- @id = nil
23
- @lang = 'en'
24
- @version = '1.0'
25
- @namespace = 'jabber:client'
26
-
27
- @parser = Parser.new self
28
- end
29
-
30
- def connection_completed
31
- # @keepalive = EM::Timer.new(60) { send_data ' ' }
32
- @state = :stopped
33
- dispatch
34
- end
35
-
36
- def receive_data(data)
37
- @parser.parse data
38
-
39
- rescue => e
40
- @client.respond_to?(:rescue) ? @client.rescue(e) : raise(e)
41
- end
42
-
43
- def unbind
44
- # @keepalive.cancel
45
- @state == :stopped
46
- end
47
-
48
- def receive(node)
49
- LOG.debug "\n"+('-'*30)+"\n"
50
- LOG.debug "RECEIVING (#{node.element_name}) #{node}"
51
- @node = node
52
-
53
- case @node.element_name
54
- when 'stream:stream'
55
- @state = :ready if @state == :stopped
56
-
57
- when 'stream:end'
58
- @state = :stopped
59
-
60
- when 'stream:features'
61
- @features = @node.children
62
- @state = :features
63
- dispatch
64
-
65
- when 'stream:error'
66
- raise StreamError.new(@node)
67
-
68
- else
69
- dispatch
70
-
71
- end
72
- end
73
-
74
- def send(stanza)
75
- #TODO Queue if not ready
76
- LOG.debug "SENDING: (#{caller[1]}) #{stanza}"
77
- send_data stanza.to_s
78
- end
79
-
80
- def stopped?
81
- @state == :stopped
82
- end
83
-
84
- def ready?
85
- @state == :ready
86
- end
87
-
88
- def jid=(new_jid)
89
- LOG.debug "NEW JID: #{new_jid}"
90
- new_jid = JID.new new_jid
91
- @client.jid = new_jid
92
- @jid = new_jid
93
- end
94
-
95
- private
96
- def dispatch
97
- __send__ @state
98
- end
99
-
100
- def start
101
- send <<-STREAM
102
- <stream:stream
103
- to='#{@to}'
104
- xmlns='#{@namespace}'
105
- xmlns:stream='http://etherx.jabber.org/streams'
106
- version='#{@version}'
107
- xml:lang='#{@lang}'
108
- >
109
- STREAM
110
- end
111
-
112
- def stop
113
- send '</stream:stream>'
114
- end
115
-
116
- def stopped
117
- start
118
- end
119
-
120
- def ready
121
- @client.call @node.to_stanza
122
- end
123
-
124
- def features
125
- feature = @features.first
126
- LOG.debug "FEATURE: #{feature}"
127
- @state = case feature ? feature['xmlns'] : nil
128
- when 'urn:ietf:params:xml:ns:xmpp-tls' then :establish_tls
129
- when 'urn:ietf:params:xml:ns:xmpp-sasl' then :authenticate_sasl
130
- when 'urn:ietf:params:xml:ns:xmpp-bind' then :bind_resource
131
- when 'urn:ietf:params:xml:ns:xmpp-session' then :establish_session
132
- else :ready
133
- end
134
-
135
- dispatch unless ready?
136
- end
137
-
138
- def establish_tls
139
- unless @tls
140
- @tls = TLS.new self
141
- @tls.success { LOG.debug "TLS: SUCCESS"; @tls = nil; start }
142
- @tls.failure { LOG.debug "TLS: FAILURE"; stop }
143
- @node = @features.shift
144
- end
145
- @tls.receive @node
146
- end
147
-
148
- def authenticate_sasl
149
- unless @sasl
150
- @sasl = SASL.new(self, @jid, @pass)
151
- @sasl.success { LOG.debug "SASL SUCCESS"; @sasl = nil; start }
152
- @sasl.failure { LOG.debug "SASL FAIL"; stop }
153
- @node = @features.shift
154
- end
155
- @sasl.receive @node
156
- end
157
-
158
- def bind_resource
159
- unless @resource
160
- @resource = Resource.new self, @jid
161
- @resource.success { |jid| LOG.debug "RESOURCE: SUCCESS"; @resource = nil; self.jid = jid; @state = :features; dispatch }
162
- @resource.failure { LOG.debug "RESOURCE: FAILURE"; stop }
163
- @node = @features.shift
164
- end
165
- @resource.receive @node
166
- end
167
-
168
- def establish_session
169
- unless @session
170
- @session = Session.new self, @to
171
- @session.success { LOG.debug "SESSION: SUCCESS"; @session = nil; @client.stream_started(self); @state = :features; dispatch }
172
- @session.failure { LOG.debug "SESSION: FAILURE"; stop }
173
- @node = @features.shift
174
- end
175
- @session.receive @node
176
- end
177
- end
178
-
179
- end
@@ -1,95 +0,0 @@
1
- module Blather
2
-
3
- class XMPPNode < XML::Node
4
- @@registrations = {}
5
-
6
- alias_method :element_name, :name
7
-
8
- class_inheritable_accessor :xmlns,
9
- :name
10
-
11
- def self.new(name = nil, content = nil)
12
- name ||= self.name
13
-
14
- args = []
15
- args << name.to_s if name
16
- args << content if content
17
-
18
- elem = super *args
19
- elem.xmlns = xmlns
20
- elem
21
- end
22
-
23
- def self.register(name, xmlns = nil)
24
- self.name = name.to_s
25
- self.xmlns = xmlns
26
- @@registrations[[name, xmlns]] = self
27
- end
28
-
29
- def self.class_from_registration(name, xmlns)
30
- name = name.to_s
31
- @@registrations[[name, xmlns]] || @@registrations[[name, nil]]
32
- end
33
-
34
- def self.import(node)
35
- klass = class_from_registration(node.element_name, node.xmlns)
36
- if klass && klass != self
37
- klass.import(node)
38
- else
39
- new(node.element_name).inherit(node)
40
- end
41
- end
42
-
43
- def to_stanza
44
- self.class.import self
45
- end
46
-
47
- def xmlns=(ns)
48
- attributes.remove :xmlns
49
- self['xmlns'] = ns if ns
50
- end
51
-
52
- def xmlns
53
- self['xmlns']
54
- end
55
-
56
- def remove_child(name, ns = nil)
57
- name = name.to_s
58
- self.each { |n| n.remove! if n.element_name == name && (!ns || n.xmlns == ns) }
59
- end
60
-
61
- def remove_children(name)
62
- name = name.to_s
63
- self.find(name).each { |n| n.remove! }
64
- end
65
-
66
- def content_from(name)
67
- name = name.to_s
68
- (child = self.detect { |n| n.element_name == name }) ? child.content : nil
69
- end
70
-
71
- def copy(deep = true)
72
- self.class.new(self.element_name).inherit(self)
73
- end
74
-
75
- def inherit(stanza)
76
- inherit_attrs stanza.attributes
77
- stanza.children.each { |c| self << c.copy(true) }
78
- self
79
- end
80
-
81
- def inherit_attrs(attrs)
82
- attrs.each { |a| self[a.name] = a.value }
83
- self
84
- end
85
-
86
- def to_s
87
- super.gsub(">\n<", '><')
88
- end
89
-
90
- def find(what, nslist = nil)
91
- (self.doc ? super(what, nslist) : select { |i| i.element_name == what})
92
- end
93
- end #XMPPNode
94
-
95
- end
@@ -1,57 +0,0 @@
1
- module Blather
2
- module Extensions
3
-
4
- module LastActivity
5
- def self.included(base)
6
- base.class_eval do
7
- @@last_activity = Time.now
8
-
9
- alias_method :send_data_without_activity, :send_data
10
- def send_data(data)
11
- @@last_activity = Time.now
12
- send_data_without_activity data
13
- end
14
- end
15
- end
16
-
17
- def last_activity
18
- (Time.now - @@last_activity).to_i
19
- end
20
-
21
- def receive_last_activity(stanza)
22
- send_data stanza.reply!(last_activity) if stanza.type == 'get'
23
- end
24
- end #LastActivity
25
-
26
- class LastActivityStanza < Query
27
- register :last_activity, nil, 'jabber:iq:last'
28
-
29
- def self.new(type = :get, seconds = nil)
30
- elem = super type
31
- elem.seconds = seconds
32
- elem
33
- end
34
-
35
- def seconds=(seconds)
36
- query.attributes.remove :seconds
37
- query['seconds'] = seconds.to_i.to_s if seconds
38
- end
39
-
40
- def seconds
41
- (query['seconds'] || 0).to_i
42
- end
43
-
44
- def reply(seconds)
45
- elem = super()
46
- elem.last_activity = seconds
47
- end
48
-
49
- def reply!(seconds)
50
- self.last_activity = seconds
51
- super()
52
- end
53
- end #LastActivityStanza
54
- end
55
- end
56
-
57
- Blather::Client.__send__ :include, Blather::Extensions::LastActivity
@@ -1,85 +0,0 @@
1
- module Blather
2
- module Extensions
3
-
4
- module Version
5
- def self.included(base)
6
- base.class_eval do
7
- @@version = {}
8
-
9
- def self.version(name, ver, os = nil)
10
- @@version = {:name => name, :version => ver, :os => os}
11
- end
12
-
13
- add_callback(:iq, 100) do |c, s|
14
- if s.detect { |n| n['xmlns'] == 'jabber:iq:version' }
15
- ver = VersionStanza.new('result', c.version)
16
- ver.id = s.id
17
- ver.from = c.jid
18
- ver.to = s.from
19
- c.send_data ver
20
- end
21
- end
22
- end
23
- end
24
-
25
- def version
26
- @@version
27
- end
28
- end #Version
29
-
30
- class VersionStanza < Iq
31
- def self.new(type = 'result', ver = {})
32
- elem = super(type)
33
-
34
- query = XML::Node.new('query')
35
- query.xmlns = 'jabber:iq:version'
36
- elem << query
37
-
38
- elem.name = ver[:name] if ver[:name]
39
- elem.version = ver[:version] if ver[:version]
40
- elem.os = ver[:os] if ver[:os]
41
-
42
- elem
43
- end
44
-
45
- def query
46
- @query ||= self.detect { |n| n.name == 'query' }
47
- end
48
-
49
- def name=(name)
50
- query.each { |n| n.remove! or break if n.name == 'name' }
51
- query << XML::Node.new('name', name)
52
- end
53
-
54
- def name
55
- if name = query.detect { |n| n.name == 'name' }
56
- name.content
57
- end
58
- end
59
-
60
- def version=(version)
61
- query.each { |n| n.remove! or break if n.name == 'version' }
62
- query << XML::Node.new('version', version)
63
- end
64
-
65
- def version
66
- if version = query.detect { |n| n.version == 'version' }
67
- version.content
68
- end
69
- end
70
-
71
- def os=(os)
72
- query.each { |n| n.remove! or break if n.name == 'os' }
73
- query << XML::Node.new('os', os)
74
- end
75
-
76
- def os
77
- if os = query.detect { |n| n.os == 'os' }
78
- os.content
79
- end
80
- end
81
- end #VersionStanza
82
- end
83
- end
84
-
85
- Blather::Client.__send__ :include, Blather::Extensions::Version