ln-xmpp4r 0.5
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/CHANGELOG +91 -0
- data/COPYING +340 -0
- data/LICENSE +59 -0
- data/README.rdoc +113 -0
- data/README_ruby19.txt +43 -0
- data/Rakefile +252 -0
- data/data/doc/xmpp4r/examples/advanced/adventure/README +56 -0
- data/data/doc/xmpp4r/examples/advanced/adventure/adventure.rb +23 -0
- data/data/doc/xmpp4r/examples/advanced/adventure/adventuremuc.rb +136 -0
- data/data/doc/xmpp4r/examples/advanced/adventure/cube.xml +15 -0
- data/data/doc/xmpp4r/examples/advanced/adventure/tower.xml +69 -0
- data/data/doc/xmpp4r/examples/advanced/adventure/world.rb +424 -0
- data/data/doc/xmpp4r/examples/advanced/fileserve.conf +11 -0
- data/data/doc/xmpp4r/examples/advanced/fileserve.rb +346 -0
- data/data/doc/xmpp4r/examples/advanced/getonline.rb +56 -0
- data/data/doc/xmpp4r/examples/advanced/gtkmucclient.rb +315 -0
- data/data/doc/xmpp4r/examples/advanced/migrate.rb +88 -0
- data/data/doc/xmpp4r/examples/advanced/minimuc.rb +266 -0
- data/data/doc/xmpp4r/examples/advanced/pep-aggregator/index.xsl +235 -0
- data/data/doc/xmpp4r/examples/advanced/pep-aggregator/pep-aggregator.rb +147 -0
- data/data/doc/xmpp4r/examples/advanced/recvfile.rb +84 -0
- data/data/doc/xmpp4r/examples/advanced/rosterdiscovery.rb +129 -0
- data/data/doc/xmpp4r/examples/advanced/sendfile.conf +10 -0
- data/data/doc/xmpp4r/examples/advanced/sendfile.rb +72 -0
- data/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr.rb +51 -0
- data/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr_jabber.rb +43 -0
- data/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr_test.rb +10 -0
- data/data/doc/xmpp4r/examples/advanced/versionpoll.rb +109 -0
- data/data/doc/xmpp4r/examples/advanced/xmpping.rb +146 -0
- data/data/doc/xmpp4r/examples/advanced/xmppingrc.sample +14 -0
- data/data/doc/xmpp4r/examples/basic/change_password.rb +41 -0
- data/data/doc/xmpp4r/examples/basic/client.rb +70 -0
- data/data/doc/xmpp4r/examples/basic/component.rb +11 -0
- data/data/doc/xmpp4r/examples/basic/echo.rb +37 -0
- data/data/doc/xmpp4r/examples/basic/jabbersend.rb +41 -0
- data/data/doc/xmpp4r/examples/basic/mass_sender.rb +68 -0
- data/data/doc/xmpp4r/examples/basic/muc_owner_config.rb +12 -0
- data/data/doc/xmpp4r/examples/basic/mucinfo.rb +41 -0
- data/data/doc/xmpp4r/examples/basic/mucsimplebot.rb +82 -0
- data/data/doc/xmpp4r/examples/basic/register.rb +42 -0
- data/data/doc/xmpp4r/examples/basic/remove_registration.rb +18 -0
- data/data/doc/xmpp4r/examples/basic/roster.rb +44 -0
- data/data/doc/xmpp4r/examples/basic/rosterprint.rb +50 -0
- data/data/doc/xmpp4r/examples/basic/rosterrename.rb +34 -0
- data/data/doc/xmpp4r/examples/basic/rosterwatch.rb +171 -0
- data/data/doc/xmpp4r/examples/basic/send_vcard.rb +67 -0
- data/data/doc/xmpp4r/examples/basic/tune_client.rb +56 -0
- data/data/doc/xmpp4r/examples/basic/tune_server.rb +58 -0
- data/data/doc/xmpp4r/examples/basic/versionbot.rb +75 -0
- data/lib/xmpp4r.rb +116 -0
- data/lib/xmpp4r/base64.rb +32 -0
- data/lib/xmpp4r/bytestreams.rb +15 -0
- data/lib/xmpp4r/bytestreams/helper/filetransfer.rb +319 -0
- data/lib/xmpp4r/bytestreams/helper/ibb/base.rb +257 -0
- data/lib/xmpp4r/bytestreams/helper/ibb/initiator.rb +31 -0
- data/lib/xmpp4r/bytestreams/helper/ibb/target.rb +54 -0
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/base.rb +152 -0
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/initiator.rb +86 -0
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb +198 -0
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/socks5.rb +65 -0
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/target.rb +79 -0
- data/lib/xmpp4r/bytestreams/iq/bytestreams.rb +170 -0
- data/lib/xmpp4r/bytestreams/iq/si.rb +206 -0
- data/lib/xmpp4r/callbacks.rb +133 -0
- data/lib/xmpp4r/caps.rb +1 -0
- data/lib/xmpp4r/caps/c.rb +67 -0
- data/lib/xmpp4r/caps/helper/generator.rb +160 -0
- data/lib/xmpp4r/caps/helper/helper.rb +84 -0
- data/lib/xmpp4r/client.rb +344 -0
- data/lib/xmpp4r/command/helper/responder.rb +53 -0
- data/lib/xmpp4r/command/iq/command.rb +154 -0
- data/lib/xmpp4r/component.rb +103 -0
- data/lib/xmpp4r/connection.rb +223 -0
- data/lib/xmpp4r/dataforms.rb +5 -0
- data/lib/xmpp4r/dataforms/x/data.rb +297 -0
- data/lib/xmpp4r/debuglog.rb +63 -0
- data/lib/xmpp4r/delay.rb +5 -0
- data/lib/xmpp4r/delay/x/delay.rb +99 -0
- data/lib/xmpp4r/discovery.rb +8 -0
- data/lib/xmpp4r/discovery/helper/helper.rb +58 -0
- data/lib/xmpp4r/discovery/helper/responder.rb +165 -0
- data/lib/xmpp4r/discovery/iq/discoinfo.rb +211 -0
- data/lib/xmpp4r/discovery/iq/discoitems.rb +147 -0
- data/lib/xmpp4r/errors.rb +284 -0
- data/lib/xmpp4r/feature_negotiation.rb +5 -0
- data/lib/xmpp4r/feature_negotiation/iq/feature.rb +28 -0
- data/lib/xmpp4r/framework/base.rb +55 -0
- data/lib/xmpp4r/framework/bot.rb +148 -0
- data/lib/xmpp4r/httpbinding.rb +5 -0
- data/lib/xmpp4r/httpbinding/client.rb +275 -0
- data/lib/xmpp4r/idgenerator.rb +37 -0
- data/lib/xmpp4r/iq.rb +221 -0
- data/lib/xmpp4r/jid.rb +167 -0
- data/lib/xmpp4r/last.rb +2 -0
- data/lib/xmpp4r/last/helper/helper.rb +37 -0
- data/lib/xmpp4r/last/iq/last.rb +67 -0
- data/lib/xmpp4r/location.rb +2 -0
- data/lib/xmpp4r/location/helper/helper.rb +56 -0
- data/lib/xmpp4r/location/location.rb +179 -0
- data/lib/xmpp4r/message.rb +180 -0
- data/lib/xmpp4r/muc.rb +14 -0
- data/lib/xmpp4r/muc/helper/mucbrowser.rb +92 -0
- data/lib/xmpp4r/muc/helper/mucclient.rb +462 -0
- data/lib/xmpp4r/muc/helper/simplemucclient.rb +332 -0
- data/lib/xmpp4r/muc/iq/mucadmin.rb +23 -0
- data/lib/xmpp4r/muc/iq/mucadminitem.rb +20 -0
- data/lib/xmpp4r/muc/iq/mucowner.rb +15 -0
- data/lib/xmpp4r/muc/item.rb +143 -0
- data/lib/xmpp4r/muc/x/muc.rb +70 -0
- data/lib/xmpp4r/muc/x/mucuserinvite.rb +60 -0
- data/lib/xmpp4r/muc/x/mucuseritem.rb +36 -0
- data/lib/xmpp4r/presence.rb +232 -0
- data/lib/xmpp4r/pubsub.rb +8 -0
- data/lib/xmpp4r/pubsub/children/configuration.rb +86 -0
- data/lib/xmpp4r/pubsub/children/event.rb +49 -0
- data/lib/xmpp4r/pubsub/children/item.rb +35 -0
- data/lib/xmpp4r/pubsub/children/items.rb +53 -0
- data/lib/xmpp4r/pubsub/children/node_config.rb +48 -0
- data/lib/xmpp4r/pubsub/children/publish.rb +38 -0
- data/lib/xmpp4r/pubsub/children/retract.rb +41 -0
- data/lib/xmpp4r/pubsub/children/subscription.rb +62 -0
- data/lib/xmpp4r/pubsub/children/subscription_config.rb +67 -0
- data/lib/xmpp4r/pubsub/children/unsubscribe.rb +48 -0
- data/lib/xmpp4r/pubsub/helper/nodebrowser.rb +129 -0
- data/lib/xmpp4r/pubsub/helper/nodehelper.rb +156 -0
- data/lib/xmpp4r/pubsub/helper/oauth_service_helper.rb +90 -0
- data/lib/xmpp4r/pubsub/helper/servicehelper.rb +456 -0
- data/lib/xmpp4r/pubsub/iq/pubsub.rb +19 -0
- data/lib/xmpp4r/query.rb +15 -0
- data/lib/xmpp4r/reliable.rb +168 -0
- data/lib/xmpp4r/rexmladdons.rb +157 -0
- data/lib/xmpp4r/roster.rb +7 -0
- data/lib/xmpp4r/roster/helper/roster.rb +522 -0
- data/lib/xmpp4r/roster/iq/roster.rb +215 -0
- data/lib/xmpp4r/roster/x/roster.rb +138 -0
- data/lib/xmpp4r/rpc.rb +2 -0
- data/lib/xmpp4r/rpc/helper/client.rb +123 -0
- data/lib/xmpp4r/rpc/helper/server.rb +74 -0
- data/lib/xmpp4r/rpc/helper/xmlrpcaddons.rb +67 -0
- data/lib/xmpp4r/rpc/iq/rpc.rb +23 -0
- data/lib/xmpp4r/sasl.rb +248 -0
- data/lib/xmpp4r/semaphore.rb +38 -0
- data/lib/xmpp4r/stream.rb +599 -0
- data/lib/xmpp4r/streamparser.rb +85 -0
- data/lib/xmpp4r/test/listener_mocker.rb +118 -0
- data/lib/xmpp4r/tune.rb +2 -0
- data/lib/xmpp4r/tune/helper/helper.rb +58 -0
- data/lib/xmpp4r/tune/tune.rb +113 -0
- data/lib/xmpp4r/vcard.rb +6 -0
- data/lib/xmpp4r/vcard/helper/vcard.rb +84 -0
- data/lib/xmpp4r/vcard/iq/vcard.rb +109 -0
- data/lib/xmpp4r/version.rb +7 -0
- data/lib/xmpp4r/version/helper/responder.rb +72 -0
- data/lib/xmpp4r/version/helper/simpleresponder.rb +44 -0
- data/lib/xmpp4r/version/iq/version.rb +105 -0
- data/lib/xmpp4r/x.rb +37 -0
- data/lib/xmpp4r/xhtml.rb +1 -0
- data/lib/xmpp4r/xhtml/html.rb +115 -0
- data/lib/xmpp4r/xmpp4r.rb +20 -0
- data/lib/xmpp4r/xmppelement.rb +168 -0
- data/lib/xmpp4r/xmppstanza.rb +162 -0
- data/setup.rb +1586 -0
- data/test/bytestreams/tc_ibb.rb +188 -0
- data/test/bytestreams/tc_socks5bytestreams.rb +114 -0
- data/test/caps/tc_helper.rb +158 -0
- data/test/dataforms/tc_data.rb +81 -0
- data/test/delay/tc_xdelay.rb +51 -0
- data/test/discovery/tc_responder.rb +91 -0
- data/test/last/tc_helper.rb +75 -0
- data/test/lib/assert_equal_xml.rb +14 -0
- data/test/lib/clienttester.rb +149 -0
- data/test/muc/tc_muc_mucclient.rb +834 -0
- data/test/muc/tc_muc_simplemucclient.rb +114 -0
- data/test/muc/tc_mucowner.rb +50 -0
- data/test/pubsub/tc_helper.rb +785 -0
- data/test/pubsub/tc_nodeconfig.rb +61 -0
- data/test/pubsub/tc_subscriptionconfig.rb +41 -0
- data/test/reliable/tc_disconnect_cleanup.rb +334 -0
- data/test/reliable/tc_disconnect_exception.rb +37 -0
- data/test/reliable/tc_listener_mocked_test.rb +68 -0
- data/test/reliable/tc_reliable_connection.rb +31 -0
- data/test/roster/tc_helper.rb +524 -0
- data/test/roster/tc_iqqueryroster.rb +173 -0
- data/test/roster/tc_xroster.rb +73 -0
- data/test/rpc/tc_helper.rb +96 -0
- data/test/tc_callbacks.rb +129 -0
- data/test/tc_class_names.rb +146 -0
- data/test/tc_client.rb +30 -0
- data/test/tc_errors.rb +146 -0
- data/test/tc_idgenerator.rb +30 -0
- data/test/tc_iq.rb +113 -0
- data/test/tc_iqquery.rb +31 -0
- data/test/tc_jid.rb +204 -0
- data/test/tc_message.rb +131 -0
- data/test/tc_presence.rb +150 -0
- data/test/tc_rexml.rb +139 -0
- data/test/tc_stream.rb +167 -0
- data/test/tc_streamComponent.rb +95 -0
- data/test/tc_streamError.rb +129 -0
- data/test/tc_streamSend.rb +59 -0
- data/test/tc_streamparser.rb +125 -0
- data/test/tc_xmppstanza.rb +135 -0
- data/test/ts_xmpp4r.rb +44 -0
- data/test/tune/tc_helper_recv.rb +82 -0
- data/test/tune/tc_helper_send.rb +74 -0
- data/test/tune/tc_tune.rb +79 -0
- data/test/vcard/tc_helper.rb +49 -0
- data/test/vcard/tc_iqvcard.rb +62 -0
- data/test/version/tc_helper.rb +60 -0
- data/test/version/tc_iqqueryversion.rb +97 -0
- data/test/xhtml/tc_html.rb +41 -0
- data/tools/gen_requires.bash +31 -0
- data/tools/xmpp4r-gemspec-test.rb +11 -0
- data/xmpp4r.gemspec +238 -0
- metadata +280 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# =XMPP4R - XMPP Library for Ruby
|
|
2
|
+
# License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
|
|
3
|
+
# Website::http://home.gna.org/xmpp4r/
|
|
4
|
+
|
|
5
|
+
require 'time' # For Time#xmlschema
|
|
6
|
+
|
|
7
|
+
require 'xmpp4r/feature_negotiation/iq/feature'
|
|
8
|
+
|
|
9
|
+
module Jabber
|
|
10
|
+
module Bytestreams
|
|
11
|
+
PROFILE_FILETRANSFER = 'http://jabber.org/protocol/si/profile/file-transfer'
|
|
12
|
+
|
|
13
|
+
##
|
|
14
|
+
# Iq child 'si' for Stream-Initiation
|
|
15
|
+
class IqSi < XMPPElement
|
|
16
|
+
name_xmlns 'si', 'http://jabber.org/protocol/si'
|
|
17
|
+
force_xmlns true
|
|
18
|
+
|
|
19
|
+
def initialize(id=nil, profile=nil, mime_type=nil)
|
|
20
|
+
super()
|
|
21
|
+
|
|
22
|
+
self.id = id
|
|
23
|
+
self.profile = profile
|
|
24
|
+
self.mime_type = mime_type
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
##
|
|
28
|
+
# Session ID of this stream
|
|
29
|
+
def id
|
|
30
|
+
attributes['id']
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
##
|
|
34
|
+
# Set Session ID of this stream
|
|
35
|
+
def id=(s)
|
|
36
|
+
attributes['id'] = s
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
##
|
|
40
|
+
# MIME type of this stream
|
|
41
|
+
def mime_type
|
|
42
|
+
attributes['mime-type']
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
##
|
|
46
|
+
# Set MIME type of this stream
|
|
47
|
+
def mime_type=(s)
|
|
48
|
+
attributes['mime-type'] = s
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
##
|
|
52
|
+
# Stream profile, can indicate file-transfer
|
|
53
|
+
def profile
|
|
54
|
+
attributes['profile']
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
##
|
|
58
|
+
# Set stream profile
|
|
59
|
+
def profile=(s)
|
|
60
|
+
attributes['profile'] = s
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
##
|
|
64
|
+
# <file/> child
|
|
65
|
+
# result:: [IqSiFile]
|
|
66
|
+
def file
|
|
67
|
+
first_element('file')
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
##
|
|
71
|
+
# <feature/> child
|
|
72
|
+
# result:: [IqFeature]
|
|
73
|
+
def feature
|
|
74
|
+
first_element('feature')
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
##
|
|
80
|
+
# File-transfer meta-information,
|
|
81
|
+
# may appear as <file/> in IqSi
|
|
82
|
+
class IqSiFile < XMPPElement
|
|
83
|
+
name_xmlns 'file', PROFILE_FILETRANSFER
|
|
84
|
+
|
|
85
|
+
def initialize(fname=nil, size=nil)
|
|
86
|
+
super()
|
|
87
|
+
self.fname = fname
|
|
88
|
+
self.size = size
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
##
|
|
92
|
+
# Get filename (attribute 'name')
|
|
93
|
+
def fname
|
|
94
|
+
attributes['name']
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
##
|
|
98
|
+
# Set filename (attribute 'name')
|
|
99
|
+
def fname=(s)
|
|
100
|
+
attributes['name'] = s
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
##
|
|
104
|
+
# Get MD5 hash
|
|
105
|
+
def hash
|
|
106
|
+
attributes['hash']
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
##
|
|
110
|
+
# Set MD5 hash
|
|
111
|
+
def hash=(s)
|
|
112
|
+
attributes['hash'] = s
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
##
|
|
116
|
+
# Get file date
|
|
117
|
+
# result:: [Time] or nil
|
|
118
|
+
def date
|
|
119
|
+
begin
|
|
120
|
+
Time.xmlschema(attributes['date'])
|
|
121
|
+
rescue ArgumentError
|
|
122
|
+
nil
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
##
|
|
127
|
+
# Set file date
|
|
128
|
+
# d:: [Time] or nil
|
|
129
|
+
def date=(d)
|
|
130
|
+
attributes['date'] = (d ? d.xmlschema : nil)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
##
|
|
134
|
+
# File size in bytes
|
|
135
|
+
# result:: [Fixnum]
|
|
136
|
+
def size
|
|
137
|
+
(attributes['size'] =~ /^\d+$/) ? attributes['size'].to_i : nil
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
##
|
|
141
|
+
# Set file size
|
|
142
|
+
def size=(s)
|
|
143
|
+
attributes['size'] = s ? s.to_s : nil
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
##
|
|
147
|
+
# File description
|
|
148
|
+
def description
|
|
149
|
+
first_element_text('desc')
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
##
|
|
153
|
+
# Set file description
|
|
154
|
+
def description=(s)
|
|
155
|
+
replace_element_text('desc', s)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
##
|
|
159
|
+
# <range/> child
|
|
160
|
+
#
|
|
161
|
+
# A file-transfer offer may contain this with
|
|
162
|
+
# no attributes set, indicating the ability to
|
|
163
|
+
# do ranged transfers.
|
|
164
|
+
# result:: [IqSiFileRange]
|
|
165
|
+
def range
|
|
166
|
+
first_element('range')
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
##
|
|
171
|
+
# Information for ranged transfers
|
|
172
|
+
class IqSiFileRange < XMPPElement
|
|
173
|
+
name_xmlns 'range', PROFILE_FILETRANSFER
|
|
174
|
+
def initialize(offset=nil, length=nil)
|
|
175
|
+
super()
|
|
176
|
+
|
|
177
|
+
self.offset = offset
|
|
178
|
+
self.length = length
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
##
|
|
182
|
+
# File offset (for continuing an interrupted transfer)
|
|
183
|
+
def offset
|
|
184
|
+
(attributes['offset'] =~ /^\d+$/) ? attributes['offset'].to_i : nil
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
##
|
|
188
|
+
# Set file offset
|
|
189
|
+
def offset=(o)
|
|
190
|
+
attributes['offset'] = (o ? o.to_s : nil)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
##
|
|
194
|
+
# File length (if not to transfer whole file)
|
|
195
|
+
def length
|
|
196
|
+
(attributes['length'] =~ /^\d+$/) ? attributes['length'].to_i : nil
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
##
|
|
200
|
+
# Set file length
|
|
201
|
+
def length=(o)
|
|
202
|
+
attributes['length'] = (o ? o.to_s : nil)
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# =XMPP4R - XMPP Library for Ruby
|
|
2
|
+
# License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
|
|
3
|
+
# Website::http://home.gna.org/xmpp4r/
|
|
4
|
+
|
|
5
|
+
module Jabber
|
|
6
|
+
##
|
|
7
|
+
# This class manages a list of callbacks.
|
|
8
|
+
#
|
|
9
|
+
# ==Callbacks management and priority
|
|
10
|
+
#
|
|
11
|
+
# Callbacks are managed by the class CallbackList. When they are added, a
|
|
12
|
+
# priority (just a number or anything Comparable with other priorities) is
|
|
13
|
+
# specified. The biggest the priority is, the earliest the callback will be
|
|
14
|
+
# considered.
|
|
15
|
+
#
|
|
16
|
+
# Callbacks are processed for a given set of objects as long as they return
|
|
17
|
+
# false. If you want to stop processing, you must return true. Example :
|
|
18
|
+
# cbl = CallbackList.new
|
|
19
|
+
# c1 = false
|
|
20
|
+
# c2 = false
|
|
21
|
+
# c3 = false
|
|
22
|
+
# cbl.add(10) { c1 = true; 1 }
|
|
23
|
+
# cbl.add(5) { c2 = true; true }
|
|
24
|
+
# cbl.add(0) { c3 = true }
|
|
25
|
+
# cbl.process('aa')
|
|
26
|
+
# puts "#{c1} #{c2} #{c3}"
|
|
27
|
+
# This example would display "true true false" as callbacks processing was
|
|
28
|
+
# stopped after the second callback returned true.
|
|
29
|
+
#
|
|
30
|
+
# In XMPP4R, callbacks' priorities are quite normalized since we want to be
|
|
31
|
+
# able to "cascade" callbacks in a clean way. Here are values your code should
|
|
32
|
+
# take into account :
|
|
33
|
+
#
|
|
34
|
+
# >= 200:: logging & debugging callbacks. Those callbacks should not consume
|
|
35
|
+
# elements.
|
|
36
|
+
# 100-199:: Where Helpers register their callbacks. The normal value is 100,
|
|
37
|
+
# and Helpers shouldn't register something else unless there's a
|
|
38
|
+
# very good reason to.
|
|
39
|
+
# < 100:: all those numbers are normally available for your application.
|
|
40
|
+
# That's enough, don't you think ?
|
|
41
|
+
class CallbackList
|
|
42
|
+
include Enumerable
|
|
43
|
+
|
|
44
|
+
# Create a new list of callbacks
|
|
45
|
+
def initialize
|
|
46
|
+
@list = []
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
##
|
|
50
|
+
# Add a callback to the list
|
|
51
|
+
#
|
|
52
|
+
# List will be sorted afterwards
|
|
53
|
+
#
|
|
54
|
+
# prio:: [Integer] the callback's priority, the higher, the sooner.
|
|
55
|
+
# ref:: [String] the callback's reference
|
|
56
|
+
# block:: [Block] a block to execute
|
|
57
|
+
# return:: [Jabber::CallbackList] The list, for chaining
|
|
58
|
+
def add(prio = 0, ref = nil, proc = nil, &block)
|
|
59
|
+
block = proc if proc
|
|
60
|
+
@list.push(Callback.new(prio, ref, block))
|
|
61
|
+
@list.sort! { |a, b| b.priority <=> a.priority }
|
|
62
|
+
self
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
##
|
|
66
|
+
# Delete a callback by reference
|
|
67
|
+
# ref:: [String] the reference of the callback to delete
|
|
68
|
+
# return:: [CallBackList] The list, for chaining
|
|
69
|
+
def delete(ref)
|
|
70
|
+
@list.delete_if { |item| item.ref == ref }
|
|
71
|
+
self
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def each(&block)
|
|
75
|
+
@list.each(&block)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
##
|
|
79
|
+
# Number of elements in the list
|
|
80
|
+
# return:: [Integer] The number of elements
|
|
81
|
+
def length
|
|
82
|
+
@list.length
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
##
|
|
86
|
+
# Process an element through all my callbacks. returns e.consumed?
|
|
87
|
+
# e:: [Object] The elements to pass to the callback. You can pass
|
|
88
|
+
# several, but of course, you block must know how to handle them.
|
|
89
|
+
# return:: [Boolean] true if the element has been consumed
|
|
90
|
+
def process(*e)
|
|
91
|
+
# If somebody adds a new callback the list will get modified
|
|
92
|
+
# and sorted(!) while still iterating through it. So we use a
|
|
93
|
+
# local copy of @list. Any freshly added callback will receive
|
|
94
|
+
# the next stanzas, not the current.
|
|
95
|
+
list = @list.dup
|
|
96
|
+
|
|
97
|
+
# process through callbacks
|
|
98
|
+
list.each do |item|
|
|
99
|
+
return true if item.block.call(*e) == true
|
|
100
|
+
end
|
|
101
|
+
false
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# This class is used to store callbacks inside CallbackList. See the
|
|
106
|
+
# CallbackList class for more detailed explanations.
|
|
107
|
+
class Callback
|
|
108
|
+
|
|
109
|
+
# The Callback's priority
|
|
110
|
+
attr_reader :priority
|
|
111
|
+
|
|
112
|
+
# The Callback's reference, using for deleting purposes
|
|
113
|
+
attr_reader :ref
|
|
114
|
+
|
|
115
|
+
# The Callback's block to execute
|
|
116
|
+
attr_reader :block
|
|
117
|
+
|
|
118
|
+
##
|
|
119
|
+
# Create a new callback
|
|
120
|
+
# priority:: [Integer] the callback's priority. The higher, the sooner it
|
|
121
|
+
# will be executed
|
|
122
|
+
# ref:: [String] The callback's reference
|
|
123
|
+
def initialize(priority = 0, ref = nil, block = Proc.new {})
|
|
124
|
+
@priority = priority
|
|
125
|
+
@ref = ref
|
|
126
|
+
@block = block
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def to_s
|
|
130
|
+
"#<#{[self.class, priority, ref].compact * " "}>"
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
data/lib/xmpp4r/caps.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'xmpp4r/caps/helper/helper'
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# =XMPP4R - XMPP Library for Ruby
|
|
2
|
+
# License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
|
|
3
|
+
# Website::http://home.gna.org/xmpp4r/
|
|
4
|
+
|
|
5
|
+
require 'xmpp4r/xmppelement'
|
|
6
|
+
|
|
7
|
+
module Jabber
|
|
8
|
+
module Caps
|
|
9
|
+
NS_CAPS='http://jabber.org/protocol/caps'
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
# The <c/> XMPP element, used to advertise entity capabilities.
|
|
13
|
+
#
|
|
14
|
+
# See http://www.xmpp.org/extensions/xep-0115.html#protocol.
|
|
15
|
+
#
|
|
16
|
+
# You should not need to construct this element directly, see
|
|
17
|
+
# Jabber::Caps::Helper.
|
|
18
|
+
class C < XMPPElement
|
|
19
|
+
name_xmlns 'c', NS_CAPS
|
|
20
|
+
force_xmlns true
|
|
21
|
+
|
|
22
|
+
def initialize(node = nil, ver = nil)
|
|
23
|
+
super()
|
|
24
|
+
add_attribute('node', node) if node
|
|
25
|
+
if ver
|
|
26
|
+
add_attribute('ver', ver)
|
|
27
|
+
add_attribute('hash', 'sha-1')
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
##
|
|
32
|
+
# Get the value of this element's 'ver' attribute,
|
|
33
|
+
# an opaque hash representing this entity's capabilities.
|
|
34
|
+
def ver
|
|
35
|
+
attributes['ver']
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
##
|
|
39
|
+
# Get the value of this element's 'node' attribute,
|
|
40
|
+
# a 'unique identifier for the software underlying the entity'
|
|
41
|
+
def node
|
|
42
|
+
attributes['node']
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
##
|
|
46
|
+
# Get the value of this element's 'hash' attribute,
|
|
47
|
+
# the algorithm used in generating the 'ver' attribute
|
|
48
|
+
def hash
|
|
49
|
+
attributes['hash']
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
##
|
|
53
|
+
# Get the value of this element's 'ext' attribute,
|
|
54
|
+
# the list of extensions for legacy clients.
|
|
55
|
+
def ext
|
|
56
|
+
attributes['ext']
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
##
|
|
60
|
+
# Is this a legacy caps response, as defined by version 1.3 of
|
|
61
|
+
# the XEP-0115 specification?
|
|
62
|
+
def legacy?
|
|
63
|
+
hash.nil? || hash.empty?
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# =XMPP4R - XMPP Library for Ruby
|
|
2
|
+
# License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
|
|
3
|
+
# Website::http://home.gna.org/xmpp4r/
|
|
4
|
+
|
|
5
|
+
require 'xmpp4r'
|
|
6
|
+
require 'xmpp4r/discovery'
|
|
7
|
+
require 'xmpp4r/dataforms'
|
|
8
|
+
require 'xmpp4r/caps/c'
|
|
9
|
+
require 'digest'
|
|
10
|
+
require 'xmpp4r/base64'
|
|
11
|
+
|
|
12
|
+
module Jabber
|
|
13
|
+
module Caps
|
|
14
|
+
def self.generate_ver_str(identities, features, forms=[])
|
|
15
|
+
# 1. Initialize an empty string S.
|
|
16
|
+
s = ''
|
|
17
|
+
|
|
18
|
+
# 2. Sort the service discovery identities [14] by category and
|
|
19
|
+
# then by type (if it exists) and then by xml:lang (if it
|
|
20
|
+
# exists), formatted as CATEGORY '/' [TYPE] '/' [LANG] '/'
|
|
21
|
+
# [NAME]. Note that each slash is included even if the TYPE,
|
|
22
|
+
# LANG, or NAME is not included.
|
|
23
|
+
identities.sort! do |identity1,identity2|
|
|
24
|
+
cmp_result = nil
|
|
25
|
+
[:category, :type, :xml_lang, :iname].each do |field|
|
|
26
|
+
value1 = identity1.send(field)
|
|
27
|
+
value2 = identity2.send(field)
|
|
28
|
+
|
|
29
|
+
if value1 != value2
|
|
30
|
+
cmp_result = value1 <=> value2
|
|
31
|
+
break
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
cmp_result
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# 3. For each identity, append the 'category/type/lang/name' to
|
|
40
|
+
# S, followed by the '<' character.
|
|
41
|
+
s += identities.collect do |identity|
|
|
42
|
+
[:category, :type, :xml_lang, :iname].collect do |field|
|
|
43
|
+
identity.send(field).to_s
|
|
44
|
+
end.join('/') + '<'
|
|
45
|
+
end.join
|
|
46
|
+
|
|
47
|
+
# 4. Sort the supported service discovery features. [15]
|
|
48
|
+
features.sort! do |feature1,feature2|
|
|
49
|
+
feature1.var <=> feature2.var
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# 5. For each feature, append the feature to S, followed by the
|
|
53
|
+
# '<' character.
|
|
54
|
+
s += features.collect do |feature|
|
|
55
|
+
feature.var.to_s + '<'
|
|
56
|
+
end.join
|
|
57
|
+
|
|
58
|
+
# 6. If the service discovery information response includes
|
|
59
|
+
# XEP-0128 data forms, sort the forms by the FORM_TYPE (i.e., by
|
|
60
|
+
# the XML character data of the <value/> element).
|
|
61
|
+
forms.sort! do |form1,form2|
|
|
62
|
+
fform_type1 = form1.field('FORM_TYPE')
|
|
63
|
+
fform_type2 = form2.field('FORM_TYPE')
|
|
64
|
+
form_type1 = fform_type1 ? fform_type1.values.to_s : nil
|
|
65
|
+
form_type2 = fform_type2 ? fform_type2.values.to_s : nil
|
|
66
|
+
form_type1 <=> form_type2
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# 7. For each extended service discovery information form:
|
|
70
|
+
forms.each do |form|
|
|
71
|
+
# 7.1. Append the XML character data of the FORM_TYPE field's
|
|
72
|
+
# <value/> element, followed by the '<' character.
|
|
73
|
+
fform_type = form.field('FORM_TYPE')
|
|
74
|
+
form_type = fform_type ? fform_type.values.to_s : nil
|
|
75
|
+
s += "#{form_type}<"
|
|
76
|
+
|
|
77
|
+
# 7.2. Sort the fields by the value of the "var" attribute.
|
|
78
|
+
fields = form.fields(false).sort do |field1,field2|
|
|
79
|
+
field1.var <=> field2.var
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# 7.3. For each field:
|
|
83
|
+
|
|
84
|
+
fields.each do |field|
|
|
85
|
+
# 7.3.1. Append the value of the "var" attribute, followed by
|
|
86
|
+
# the '<' character.
|
|
87
|
+
s += "#{field.var}<"
|
|
88
|
+
|
|
89
|
+
# 7.3.2. Sort values by the XML character data of the <value/>
|
|
90
|
+
# element.
|
|
91
|
+
values = field.values.sort do |value1,value2|
|
|
92
|
+
value1 <=> value2
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# 7.3.3. For each <value/> element, append the XML character
|
|
96
|
+
# data, followed by the '<' character.
|
|
97
|
+
s += values.collect do |value|
|
|
98
|
+
"#{value}<"
|
|
99
|
+
end.join
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# 8. Ensure that S is encoded according to the UTF-8 encoding
|
|
104
|
+
# (RFC 3269 [16]).
|
|
105
|
+
|
|
106
|
+
# (given in XMPP4R)
|
|
107
|
+
|
|
108
|
+
s
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
##
|
|
112
|
+
# Implementation of the algorithm defined at:
|
|
113
|
+
# http://www.xmpp.org/extensions/xep-0115.html#ver-gen
|
|
114
|
+
def self.generate_ver(identities, features, forms=[], hash='sha-1')
|
|
115
|
+
s = generate_ver_str(identities, features, forms)
|
|
116
|
+
|
|
117
|
+
# 9. Compute the verification string by hashing S using the
|
|
118
|
+
# algorithm specified in the 'hash' attribute (e.g., SHA-1 as
|
|
119
|
+
# defined in RFC 3174 [17]). The hashed data MUST be generated
|
|
120
|
+
# with binary output and encoded using Base64 as specified in
|
|
121
|
+
# Section 4 of RFC 4648 [18] (note: the Base64 output MUST NOT
|
|
122
|
+
# include whitespace and MUST set padding bits to zero). [19]
|
|
123
|
+
|
|
124
|
+
# See http://www.iana.org/assignments/hash-function-text-names
|
|
125
|
+
hash_klass = case hash
|
|
126
|
+
when 'md2' then nil
|
|
127
|
+
when 'md5' then Digest::MD5
|
|
128
|
+
when 'sha-1' then Digest::SHA1
|
|
129
|
+
when 'sha-224' then nil
|
|
130
|
+
when 'sha-256' then Digest::SHA256
|
|
131
|
+
when 'sha-384' then Digest::SHA384
|
|
132
|
+
when 'sha-512' then Digest::SHA512
|
|
133
|
+
end
|
|
134
|
+
if hash_klass
|
|
135
|
+
Base64::encode64(hash_klass::digest(s)).strip
|
|
136
|
+
else
|
|
137
|
+
nil
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
##
|
|
142
|
+
# Generate a ver hash from a Jabber::Discovery::IqQueryDiscoInfo result
|
|
143
|
+
# query:: [Jabber::Discovery::IqQueryDiscoInfo]
|
|
144
|
+
def self.generate_ver_from_discoinfo(query, hash='sha-1')
|
|
145
|
+
identities = []
|
|
146
|
+
features = []
|
|
147
|
+
forms = []
|
|
148
|
+
query.each_element do |element|
|
|
149
|
+
if element.kind_of? Discovery::Identity
|
|
150
|
+
identities << element
|
|
151
|
+
elsif element.kind_of? Discovery::Feature
|
|
152
|
+
features << element
|
|
153
|
+
elsif element.kind_of? Dataforms::XData
|
|
154
|
+
forms << element
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
generate_ver(identities, features, forms, hash)
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|