xmpp4r 0.3 → 0.3.1
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 +10 -0
- data/README +12 -4
- data/Rakefile +1 -1
- data/data/doc/xmpp4r/examples/advanced/fileserve.rb +2 -0
- data/data/doc/xmpp4r/examples/advanced/recvfile.rb +2 -0
- data/data/doc/xmpp4r/examples/basic/client.rb +2 -2
- data/data/doc/xmpp4r/examples/basic/mass_sender.rb +1 -0
- data/data/doc/xmpp4r/examples/buggy/miniedgarr_cgi.rb +1 -1
- data/lib/xmpp4r/bytestreams.rb +4 -0
- data/lib/xmpp4r/bytestreams/helper/filetransfer.rb +10 -4
- data/lib/xmpp4r/bytestreams/helper/ibb/base.rb +4 -0
- data/lib/xmpp4r/bytestreams/helper/ibb/initiator.rb +5 -1
- data/lib/xmpp4r/bytestreams/helper/ibb/target.rb +5 -1
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/base.rb +5 -1
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/initiator.rb +4 -0
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb +20 -6
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/socks5.rb +4 -0
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/target.rb +4 -0
- data/lib/xmpp4r/bytestreams/iq/si.rb +4 -0
- data/lib/xmpp4r/component.rb +1 -1
- data/lib/xmpp4r/dataforms.rb +4 -0
- data/lib/xmpp4r/delay.rb +4 -0
- data/lib/xmpp4r/discovery.rb +4 -0
- data/lib/xmpp4r/feature_negotiation.rb +4 -0
- data/lib/xmpp4r/feature_negotiation/iq/feature.rb +4 -0
- data/lib/xmpp4r/iq.rb +1 -1
- data/lib/xmpp4r/message.rb +10 -3
- data/lib/xmpp4r/muc.rb +4 -0
- data/lib/xmpp4r/muc/helper/simplemucclient.rb +4 -0
- data/lib/xmpp4r/presence.rb +9 -5
- data/lib/xmpp4r/rexmladdons.rb +65 -3
- data/lib/xmpp4r/roster.rb +4 -0
- data/lib/xmpp4r/roster/helper/roster.rb +18 -3
- data/lib/xmpp4r/sasl.rb +59 -10
- data/lib/xmpp4r/stream.rb +22 -2
- data/lib/xmpp4r/vcard.rb +4 -0
- data/lib/xmpp4r/vcard/helper/vcard.rb +4 -4
- data/lib/xmpp4r/version.rb +4 -0
- data/lib/xmpp4r/xmpp4r.rb +1 -1
- data/setup.rb +800 -575
- data/test/bytestreams/tc_socks5bytestreams.rb +46 -0
- data/test/tc_iq.rb +1 -1
- data/test/tc_rexml.rb +60 -0
- data/test/ts_xmpp4r.rb +2 -1
- data/test/vcard/tc_helper.rb +49 -0
- metadata +96 -94
- data/test/roster/.tc_helper.rb.swp +0 -0
data/ChangeLog
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
XMPP4R 0.3.1 (23/04/2007)
|
2
|
+
=========================
|
3
|
+
* SASL fixes
|
4
|
+
* Message#x and Presence#x support element selection by namespace
|
5
|
+
* Proper XML entity escaping for REXML text nodes
|
6
|
+
* Improvements to FileTransfer::Helper and SOCKS5BytestreamsServer
|
7
|
+
* Vcard::Helper fixes
|
8
|
+
* Update Digest module usage to reflect recent Ruby versions
|
9
|
+
* More documentation
|
10
|
+
|
1
11
|
XMPP4R 0.3 (20/07/2006)
|
2
12
|
=======================
|
3
13
|
* SRV lookup capability in Client#connect
|
data/README
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
XMPP4R
|
2
2
|
----------
|
3
|
-
by
|
4
|
-
|
5
|
-
|
3
|
+
by:
|
4
|
+
Lucas Nussbaum <lucas@lucas-nussbaum.net>
|
5
|
+
Stephan Maka <stephan@spaceboyz.net>
|
6
|
+
Kirill A. Shutemov <k.shutemov@gmail.com>
|
7
|
+
Yuki Mitsui
|
8
|
+
Peter Schrammel
|
9
|
+
Olli
|
10
|
+
Vojtech Vobr
|
11
|
+
Andreas Wiese
|
6
12
|
|
7
13
|
Currently, all the information is provided on
|
8
14
|
|
@@ -13,7 +19,9 @@ The integrated HTML documentation can be built with
|
|
13
19
|
rake rdoc
|
14
20
|
|
15
21
|
If you need to ask questions, feel free to ask them on the
|
16
|
-
xmpp4r-devel@gna.org mailing list.
|
22
|
+
xmpp4r-devel@gna.org mailing list. When reporting problems,
|
23
|
+
please include a protocol dump which can be enabled with:
|
24
|
+
Jabber::debug = true
|
17
25
|
|
18
26
|
XMPP4R is released under the Ruby license (see the LICENSE file), which is
|
19
27
|
compatible with the GNU GPL (see the COPYING file) via an explicit
|
data/Rakefile
CHANGED
@@ -22,7 +22,7 @@ class BasicClient
|
|
22
22
|
quit = true if line.nil?
|
23
23
|
if not quit
|
24
24
|
command, args = line.split(' ', 2)
|
25
|
-
args.chomp
|
25
|
+
args = args.to_s.chomp
|
26
26
|
# main case
|
27
27
|
case command
|
28
28
|
when 'exit'
|
@@ -52,7 +52,7 @@ class BasicClient
|
|
52
52
|
##
|
53
53
|
# connect <jid> <password>
|
54
54
|
def do_connect(args)
|
55
|
-
@jid, @password = args.split(' ',
|
55
|
+
@jid, @password = args.split(' ', 2)
|
56
56
|
@jid = JID::new(@jid)
|
57
57
|
@cl = Client::new(@jid)
|
58
58
|
@cl.connect
|
@@ -34,7 +34,7 @@ doc.root.each_element { |e|
|
|
34
34
|
elsif e.name == 'presence'
|
35
35
|
pres = Jabber::Presence.new.import(e)
|
36
36
|
|
37
|
-
if (pres.from.strip == jid) || (Digest::MD5.
|
37
|
+
if (pres.from.strip == jid) || (Digest::MD5.hexdigest(pres.from.strip.to_s) == jidhash)
|
38
38
|
if (jid == '') && !jidhash.nil?
|
39
39
|
jid = pres.from.strip
|
40
40
|
end
|
data/lib/xmpp4r/bytestreams.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
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
|
+
|
1
5
|
require 'xmpp4r/bytestreams/iq/si.rb'
|
2
6
|
require 'xmpp4r/bytestreams/iq/bytestreams.rb'
|
3
7
|
require 'xmpp4r/bytestreams/helper/ibb/base.rb'
|
@@ -1,3 +1,7 @@
|
|
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
|
+
|
1
5
|
require 'callbacks'
|
2
6
|
|
3
7
|
require 'xmpp4r/bytestreams/iq/si'
|
@@ -242,8 +246,10 @@ module Jabber
|
|
242
246
|
# jid:: [JID] to send the file to
|
243
247
|
# source:: File-transfer source, implementing the FileSource interface
|
244
248
|
# desc:: [String] or [nil] Optional file description
|
249
|
+
# from:: [String] or [nil] Optional jid for components
|
245
250
|
# result:: [Bytestreams::SOCKS5BytestreamsInitiator] or [Bytestreams::IBBInitiator] or [nil]
|
246
|
-
def offer(jid, source, desc=nil)
|
251
|
+
def offer(jid, source, desc=nil, from=nil)
|
252
|
+
from = from || @my_jid || @stream.jid
|
247
253
|
session_id = Jabber::IdGenerator.instance.generate_id
|
248
254
|
|
249
255
|
offered_methods = {}
|
@@ -255,7 +261,7 @@ module Jabber
|
|
255
261
|
end
|
256
262
|
|
257
263
|
iq = Iq::new(:set, jid)
|
258
|
-
iq.from =
|
264
|
+
iq.from = from
|
259
265
|
si = iq.add(Bytestreams::IqSi.new(session_id, Bytestreams::IqSi::PROFILE_FILETRANSFER, source.mime))
|
260
266
|
|
261
267
|
file = si.add(Bytestreams::IqSiFile.new(source.filename, source.size))
|
@@ -299,9 +305,9 @@ module Jabber
|
|
299
305
|
end
|
300
306
|
|
301
307
|
if stream_method == Bytestreams::IqQueryBytestreams::NS_BYTESTREAMS and @allow_bytestreams
|
302
|
-
Bytestreams::SOCKS5BytestreamsInitiator.new(@stream, session_id,
|
308
|
+
Bytestreams::SOCKS5BytestreamsInitiator.new(@stream, session_id, from, jid)
|
303
309
|
elsif stream_method == Bytestreams::IBB::NS_IBB and @allow_ibb
|
304
|
-
Bytestreams::IBBInitiator.new(@stream, session_id,
|
310
|
+
Bytestreams::IBBInitiator.new(@stream, session_id, from, jid)
|
305
311
|
else # Target responded with a stream_method we didn't offer
|
306
312
|
eanswer = response.answer
|
307
313
|
eanswer.type = :error
|
@@ -1,3 +1,7 @@
|
|
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
|
+
|
1
5
|
module Jabber
|
2
6
|
module Bytestreams
|
3
7
|
##
|
@@ -5,7 +9,7 @@ module Jabber
|
|
5
9
|
class IBBInitiator < IBB
|
6
10
|
# You may set the block-size before open
|
7
11
|
attr_accessor :block_size
|
8
|
-
|
12
|
+
|
9
13
|
##
|
10
14
|
# Open the stream to the peer,
|
11
15
|
# waits for successful result
|
@@ -1,3 +1,7 @@
|
|
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
|
+
|
1
5
|
module Jabber
|
2
6
|
module Bytestreams
|
3
7
|
##
|
@@ -28,7 +32,7 @@ module Jabber
|
|
28
32
|
reply = iq.answer(false)
|
29
33
|
reply.type = :result
|
30
34
|
@stream.send(reply)
|
31
|
-
|
35
|
+
|
32
36
|
connect_lock.unlock
|
33
37
|
true
|
34
38
|
else
|
@@ -1,3 +1,7 @@
|
|
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
|
+
|
1
5
|
require 'socket'
|
2
6
|
require 'thread'
|
3
7
|
require 'timeout'
|
@@ -122,7 +126,7 @@ module Jabber
|
|
122
126
|
# initiator_jid and target_jid.
|
123
127
|
# result:: [String] SHA1 hash
|
124
128
|
def stream_address
|
125
|
-
Digest::SHA1.
|
129
|
+
Digest::SHA1.hexdigest("#{@session_id}#{@initiator_jid}#{@target_jid}")
|
126
130
|
end
|
127
131
|
|
128
132
|
##
|
@@ -1,3 +1,7 @@
|
|
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
|
+
|
1
5
|
module Jabber
|
2
6
|
module Bytestreams
|
3
7
|
##
|
@@ -19,12 +23,17 @@ module Jabber
|
|
19
23
|
# Will start to listen on the given TCP port and
|
20
24
|
# accept new peers
|
21
25
|
# port:: [Fixnum] TCP port to listen on
|
22
|
-
|
26
|
+
# listen_on:: [String] Optional address for the server socket to listen on (i.e. '0.0.0.0' or '::')
|
27
|
+
def initialize(port, listen_on=nil)
|
23
28
|
@port = port
|
24
29
|
@addresses = []
|
25
30
|
@peers = []
|
26
31
|
@peers_lock = Mutex.new
|
27
|
-
|
32
|
+
if listen_on
|
33
|
+
socket = TCPServer.new(listen_on, port)
|
34
|
+
else
|
35
|
+
socket = TCPServer.new(port)
|
36
|
+
end
|
28
37
|
|
29
38
|
Thread.new {
|
30
39
|
loop {
|
@@ -45,6 +54,9 @@ module Jabber
|
|
45
54
|
|
46
55
|
##
|
47
56
|
# Find the socket a peer is associated to
|
57
|
+
#
|
58
|
+
# This method also performs some housekeeping, ie. removing
|
59
|
+
# peers with closed sockets.
|
48
60
|
# addr:: [String] Address like SOCKS5Bytestreams#stream_address
|
49
61
|
# result:: [TCPSocker] or [nil]
|
50
62
|
def peer_sock(addr)
|
@@ -58,11 +70,13 @@ module Jabber
|
|
58
70
|
removes << peer
|
59
71
|
elsif peer.address == addr and res.nil?
|
60
72
|
res = peer.socket
|
61
|
-
else
|
62
|
-
# If we sent multiple addresses of our own, clients may
|
63
|
-
# connect multiple times. Close these connections here.
|
64
|
-
removes << peer
|
65
73
|
end
|
74
|
+
|
75
|
+
# If we sent multiple addresses of our own, clients may
|
76
|
+
# connect multiple times. DO NOT close any other connections
|
77
|
+
# here. These may belong to other concurrent bytestreams,
|
78
|
+
# believe that the peer will close any unneeded sockets
|
79
|
+
# which will then be picked up by the next call to peer_sock.
|
66
80
|
}
|
67
81
|
|
68
82
|
# If we sent multiple addresses of our own, clients may
|
data/lib/xmpp4r/component.rb
CHANGED
@@ -83,7 +83,7 @@ module Jabber
|
|
83
83
|
# Throws AuthenticationFailure
|
84
84
|
# secret:: [String] the shared secret
|
85
85
|
def auth(secret)
|
86
|
-
hash = Digest::SHA1::
|
86
|
+
hash = Digest::SHA1::hexdigest(@streamid.to_s + secret)
|
87
87
|
authenticated = false
|
88
88
|
send("<handshake>#{hash}</handshake>") { |r|
|
89
89
|
if r.prefix == 'stream' and r.name == 'error'
|
data/lib/xmpp4r/dataforms.rb
CHANGED
data/lib/xmpp4r/delay.rb
CHANGED
data/lib/xmpp4r/discovery.rb
CHANGED
data/lib/xmpp4r/iq.rb
CHANGED
@@ -156,7 +156,7 @@ module Jabber
|
|
156
156
|
query = IqQuery::new
|
157
157
|
query.add_namespace('jabber:iq:auth')
|
158
158
|
query.add(REXML::Element::new('username').add_text(jid.node))
|
159
|
-
query.add(REXML::Element::new('digest').add_text(Digest::SHA1.
|
159
|
+
query.add(REXML::Element::new('digest').add_text(Digest::SHA1.hexdigest(session_id + password)))
|
160
160
|
query.add(REXML::Element::new('resource').add_text(jid.resource)) if not jid.resource.nil?
|
161
161
|
iq.add(query)
|
162
162
|
iq
|
data/lib/xmpp4r/message.rb
CHANGED
@@ -82,9 +82,16 @@ module Jabber
|
|
82
82
|
end
|
83
83
|
|
84
84
|
##
|
85
|
-
# Get the first <x/> element
|
86
|
-
|
87
|
-
|
85
|
+
# Get the first <x/> element in this stanza, or nil if none found.
|
86
|
+
# namespace:: [String] Optional, find the first <x/> element having this xmlns
|
87
|
+
# result:: [REXML::Element] or nil
|
88
|
+
def x(namespace=nil)
|
89
|
+
each_element('x') { |x|
|
90
|
+
if namespace.nil? or namespace == x.namespace
|
91
|
+
return x
|
92
|
+
end
|
93
|
+
}
|
94
|
+
nil
|
88
95
|
end
|
89
96
|
|
90
97
|
##
|
data/lib/xmpp4r/muc.rb
CHANGED
data/lib/xmpp4r/presence.rb
CHANGED
@@ -94,12 +94,16 @@ module Jabber
|
|
94
94
|
end
|
95
95
|
|
96
96
|
##
|
97
|
-
# Get the first <x/> element
|
97
|
+
# Get the first <x/> element in this stanza, or nil if none found.
|
98
|
+
# namespace:: [String] Optional, find the first <x/> element having this xmlns
|
98
99
|
# result:: [REXML::Element] or nil
|
99
|
-
def x
|
100
|
-
|
101
|
-
|
102
|
-
|
100
|
+
def x(namespace=nil)
|
101
|
+
each_element('x') { |x|
|
102
|
+
if namespace.nil? or namespace == x.namespace
|
103
|
+
return x
|
104
|
+
end
|
105
|
+
}
|
106
|
+
nil
|
103
107
|
end
|
104
108
|
|
105
109
|
##
|
data/lib/xmpp4r/rexmladdons.rb
CHANGED
@@ -10,8 +10,23 @@ require 'rexml/source'
|
|
10
10
|
oldverbose = $VERBOSE
|
11
11
|
$VERBOSE = false
|
12
12
|
|
13
|
-
# REXML module. This file only adds
|
14
|
-
# ease the coding
|
13
|
+
# REXML module. This file only adds the following methods to the REXML module, to
|
14
|
+
# ease the coding:
|
15
|
+
# * replace_element_text
|
16
|
+
# * first_element
|
17
|
+
# * first_element_text
|
18
|
+
# * typed_add
|
19
|
+
# * import
|
20
|
+
# * self.import
|
21
|
+
# * delete_elements
|
22
|
+
#
|
23
|
+
# Further definitions are just copied from REXML out of Ruby-1.8.4 to solve issues
|
24
|
+
# with REXML in Ruby-1.8.2.
|
25
|
+
#
|
26
|
+
# The redefinitions of Text::normalize and Attribute#initialize address an issue
|
27
|
+
# where entities in element texts and attributes were not escaped. This modifies
|
28
|
+
# the behavious of REXML a bit but Sean Russell intends a similar behaviour for
|
29
|
+
# the future of REXML.
|
15
30
|
module REXML
|
16
31
|
# this class adds a few helper methods to REXML::Element
|
17
32
|
class Element
|
@@ -116,7 +131,8 @@ module REXML
|
|
116
131
|
@variables = {}
|
117
132
|
end
|
118
133
|
|
119
|
-
def namespaces=( namespaces
|
134
|
+
def namespaces=( namespaces )
|
135
|
+
namespaces ||= {}
|
120
136
|
Functions::namespace_context = namespaces
|
121
137
|
@namespaces = namespaces
|
122
138
|
end
|
@@ -819,6 +835,52 @@ module REXML
|
|
819
835
|
|
820
836
|
|
821
837
|
############################################################################
|
838
|
+
|
839
|
+
class Text
|
840
|
+
# Escapes all possible entities
|
841
|
+
def Text::normalize( input, doctype=nil, entity_filter=nil )
|
842
|
+
copy = input
|
843
|
+
# Doing it like this rather than in a loop improves the speed
|
844
|
+
if doctype
|
845
|
+
# Replace all ampersands that aren't part of an entity
|
846
|
+
copy = copy.gsub( EREFERENCE, '&' )
|
847
|
+
doctype.entities.each_value do |entity|
|
848
|
+
copy = copy.gsub( entity.value,
|
849
|
+
"&#{entity.name};" ) if entity.value and
|
850
|
+
not( entity_filter and entity_filter.include?(entity) )
|
851
|
+
end
|
852
|
+
else
|
853
|
+
# Replace all ampersands
|
854
|
+
copy = copy.gsub( '&', '&' )
|
855
|
+
DocType::DEFAULT_ENTITIES.each_value do |entity|
|
856
|
+
copy = copy.gsub(entity.value, "&#{entity.name};" )
|
857
|
+
end
|
858
|
+
end
|
859
|
+
copy
|
860
|
+
end
|
861
|
+
end
|
862
|
+
|
863
|
+
class Attribute
|
864
|
+
def initialize( first, second=nil, parent=nil )
|
865
|
+
@normalized = @unnormalized = @element = nil
|
866
|
+
if first.kind_of? Attribute
|
867
|
+
self.name = first.expanded_name
|
868
|
+
@value = first.value
|
869
|
+
if second.kind_of? Element
|
870
|
+
@element = second
|
871
|
+
else
|
872
|
+
@element = first.element
|
873
|
+
end
|
874
|
+
elsif first.kind_of? String
|
875
|
+
@element = parent if parent.kind_of? Element
|
876
|
+
self.name = first
|
877
|
+
@value = Text::normalize(second.to_s)
|
878
|
+
else
|
879
|
+
raise "illegal argument #{first.class.name} to Attribute constructor"
|
880
|
+
end
|
881
|
+
end
|
882
|
+
end
|
883
|
+
|
822
884
|
end
|
823
885
|
|
824
886
|
# Restore the old $VERBOSE setting
|