xmpp4r 0.3.1 → 0.3.2

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 (103) hide show
  1. data/ChangeLog +12 -0
  2. data/Rakefile +2 -4
  3. data/data/doc/xmpp4r/examples/advanced/adventure/adventuremuc.rb +6 -6
  4. data/data/doc/xmpp4r/examples/advanced/adventure/world.rb +3 -3
  5. data/data/doc/xmpp4r/examples/advanced/minimuc.rb +5 -5
  6. data/data/doc/xmpp4r/examples/advanced/xmpping.rb +17 -4
  7. data/data/doc/xmpp4r/examples/advanced/xmppingrc.sample +5 -0
  8. data/data/doc/xmpp4r/examples/basic/echo_threaded.rb +6 -2
  9. data/data/doc/xmpp4r/examples/basic/muc_owner_config.rb +13 -0
  10. data/lib/xmpp4r.rb +0 -6
  11. data/lib/xmpp4r/bytestreams/helper/filetransfer.rb +6 -7
  12. data/lib/xmpp4r/bytestreams/helper/ibb/base.rb +5 -6
  13. data/lib/xmpp4r/bytestreams/helper/ibb/target.rb +3 -5
  14. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/base.rb +1 -1
  15. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb +10 -8
  16. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/target.rb +3 -5
  17. data/lib/xmpp4r/bytestreams/iq/bytestreams.rb +11 -17
  18. data/lib/xmpp4r/bytestreams/iq/si.rb +13 -32
  19. data/lib/xmpp4r/callbacks.rb +124 -0
  20. data/lib/xmpp4r/client.rb +2 -5
  21. data/lib/xmpp4r/command/helper/responder.rb +53 -0
  22. data/lib/xmpp4r/command/iq/command.rb +154 -0
  23. data/lib/xmpp4r/connection.rb +49 -12
  24. data/lib/xmpp4r/dataforms/x/data.rb +66 -29
  25. data/lib/xmpp4r/delay/x/delay.rb +2 -3
  26. data/lib/xmpp4r/discovery/iq/discoinfo.rb +20 -33
  27. data/lib/xmpp4r/discovery/iq/discoitems.rb +5 -28
  28. data/lib/xmpp4r/error.rb +5 -10
  29. data/lib/xmpp4r/feature_negotiation/iq/feature.rb +2 -20
  30. data/lib/xmpp4r/httpbinding.rb +5 -0
  31. data/lib/xmpp4r/httpbinding/client.rb +285 -0
  32. data/lib/xmpp4r/iq.rb +22 -41
  33. data/lib/xmpp4r/message.rb +8 -38
  34. data/lib/xmpp4r/muc.rb +2 -0
  35. data/lib/xmpp4r/muc/helper/mucclient.rb +50 -1
  36. data/lib/xmpp4r/muc/helper/simplemucclient.rb +2 -2
  37. data/lib/xmpp4r/muc/iq/mucowner.rb +11 -0
  38. data/lib/xmpp4r/muc/x/muc.rb +2 -30
  39. data/lib/xmpp4r/muc/x/mucuserinvite.rb +4 -2
  40. data/lib/xmpp4r/muc/x/mucuseritem.rb +4 -2
  41. data/lib/xmpp4r/presence.rb +7 -35
  42. data/lib/xmpp4r/pubsub.rb +1 -0
  43. data/lib/xmpp4r/pubsub/helper/nodebrowser.rb +174 -0
  44. data/lib/xmpp4r/pubsub/helper/nodehelper.rb +153 -0
  45. data/lib/xmpp4r/pubsub/helper/servicehelper.rb +326 -0
  46. data/lib/xmpp4r/pubsub/iq/pubsub.rb +19 -0
  47. data/lib/xmpp4r/pubsub/stanzas/event.rb +49 -0
  48. data/lib/xmpp4r/pubsub/stanzas/item.rb +27 -0
  49. data/lib/xmpp4r/pubsub/stanzas/items.rb +35 -0
  50. data/lib/xmpp4r/pubsub/stanzas/subscription.rb +58 -0
  51. data/lib/xmpp4r/query.rb +4 -32
  52. data/lib/xmpp4r/rexmladdons.rb +7 -772
  53. data/lib/xmpp4r/roster/helper/roster.rb +29 -50
  54. data/lib/xmpp4r/roster/iq/roster.rb +6 -35
  55. data/lib/xmpp4r/roster/x/roster.rb +13 -30
  56. data/lib/xmpp4r/rpc.rb +2 -0
  57. data/lib/xmpp4r/rpc/helper/client.rb +114 -0
  58. data/lib/xmpp4r/rpc/helper/server.rb +75 -0
  59. data/lib/xmpp4r/rpc/helper/xmlrpcaddons.rb +57 -0
  60. data/lib/xmpp4r/rpc/iq/rpc.rb +24 -0
  61. data/lib/xmpp4r/sasl.rb +1 -1
  62. data/lib/xmpp4r/semaphore.rb +38 -0
  63. data/lib/xmpp4r/stream.rb +104 -165
  64. data/lib/xmpp4r/streamparser.rb +2 -2
  65. data/lib/xmpp4r/vcard/iq/vcard.rb +5 -12
  66. data/lib/xmpp4r/version/helper/responder.rb +2 -1
  67. data/lib/xmpp4r/version/iq/version.rb +6 -18
  68. data/lib/xmpp4r/x.rb +20 -26
  69. data/lib/xmpp4r/xmpp4r.rb +1 -1
  70. data/lib/xmpp4r/xmppelement.rb +152 -0
  71. data/lib/xmpp4r/{xmlstanza.rb → xmppstanza.rb} +17 -29
  72. data/setup.rb +1 -0
  73. data/test/bytestreams/tc_ibb.rb +8 -8
  74. data/test/dataforms/tc_data.rb +81 -0
  75. data/test/lib/clienttester.rb +20 -17
  76. data/test/muc/tc_muc_mucclient.rb +48 -23
  77. data/test/muc/tc_muc_simplemucclient.rb +7 -4
  78. data/test/muc/tc_mucowner.rb +50 -0
  79. data/test/pubsub/tc_helper.rb +227 -0
  80. data/test/roster/tc_helper.rb +181 -55
  81. data/test/roster/tc_iqqueryroster.rb +33 -0
  82. data/test/roster/tc_xroster.rb +6 -3
  83. data/test/rpc/tc_helper.rb +84 -0
  84. data/test/tc_callbacks.rb +2 -1
  85. data/test/tc_class_names.rb +9 -1
  86. data/test/tc_error.rb +1 -0
  87. data/test/tc_iq.rb +13 -12
  88. data/test/tc_message.rb +1 -0
  89. data/test/tc_presence.rb +1 -0
  90. data/test/tc_rexml.rb +1 -1
  91. data/test/tc_stream.rb +147 -102
  92. data/test/tc_streamComponent.rb +94 -0
  93. data/test/tc_streamError.rb +67 -29
  94. data/test/tc_streamSend.rb +1 -1
  95. data/test/tc_xmppstanza.rb +125 -0
  96. data/test/ts_xmpp4r.rb +37 -28
  97. data/test/version/tc_helper.rb +14 -0
  98. data/test/version/tc_iqqueryversion.rb +4 -3
  99. metadata +163 -123
  100. data/data/doc/xmpp4r/examples/basic/echo_nonthreaded.rb +0 -32
  101. data/lib/callbacks.rb +0 -122
  102. data/test/tc_streamThreaded.rb +0 -168
  103. data/test/tc_xmlstanza.rb +0 -76
data/ChangeLog CHANGED
@@ -1,3 +1,15 @@
1
+ XMPP4R 0.3.2 (15/10/2007)
2
+ =========================
3
+ * Serious bug involving Ruby threading fixed (caused exceptions with
4
+ ruby 1.8.6)
5
+ * vCard helper fixes
6
+ * Jabber RPC (JEP0009) support
7
+ * HTTP Binding (JEP0124) support
8
+ * Publish-Subscribe support
9
+ * XMPPElement: a framework for classes representing XML elements
10
+ * Ad-hoc commands support
11
+ * Improvements to Dataforms: XData, XDataTitle and XDataInstructions
12
+
1
13
  XMPP4R 0.3.1 (23/04/2007)
2
14
  =========================
3
15
  * SASL fixes
data/Rakefile CHANGED
@@ -16,7 +16,7 @@ end
16
16
  # Globals
17
17
 
18
18
  PKG_NAME = 'xmpp4r'
19
- PKG_VERSION = '0.3.1'
19
+ PKG_VERSION = '0.3.2'
20
20
 
21
21
  PKG_FILES = ['ChangeLog', 'README', 'COPYING', 'LICENSE', 'setup.rb', 'Rakefile', 'UPDATING']
22
22
  Find.find('lib/', 'data/', 'test/', 'tools/') do |f|
@@ -34,7 +34,7 @@ task :default => [:package]
34
34
 
35
35
  Rake::TestTask.new do |t|
36
36
  t.libs << "test"
37
- t.test_files = FileList['test/tc_*.rb']
37
+ t.test_files = ['test/ts_xmpp4r.rb']
38
38
  end
39
39
 
40
40
  Rake::RDocTask.new do |rd|
@@ -69,12 +69,10 @@ end
69
69
  Rake::PackageTask.new(PKG_NAME, PKG_VERSION) do |p|
70
70
  p.need_tar = true
71
71
  p.package_files = PKG_FILES
72
- p p.package_files
73
72
  end
74
73
 
75
74
  if RCOV
76
75
  Rcov::RcovTask.new do |t|
77
- #t.test_files = FileList['test/tc_*.rb'] + FileList['test/*/tc_*.rb'] - ['test/tc_streamError.rb']
78
76
  t.test_files = ['test/ts_xmpp4r.rb']
79
77
  end
80
78
  end
@@ -57,13 +57,13 @@ class AdventureMUC
57
57
 
58
58
  def handle_disco_info(iq)
59
59
  if iq.type != :get
60
- answer = Jabber::XMLStanza.answer(iq)
60
+ answer = iq.answer
61
61
  answer.type = :error
62
62
  answer.add(Jabber::Error.new('bad-request'))
63
63
  @component.send(answer) if iq.type != :error
64
64
  return
65
65
  end
66
- answer = Jabber::XMLStanza.answer(iq)
66
+ answer = iq.answer
67
67
  answer.type = :result
68
68
  if iq.to.node == nil
69
69
  answer.query.add(Jabber::Discovery::Identity.new('conference', 'Adventure component', 'text'))
@@ -87,12 +87,12 @@ class AdventureMUC
87
87
 
88
88
  def handle_disco_items(iq)
89
89
  if iq.type != :get
90
- answer = Jabber::XMLStanza.answer(iq)
90
+ answer = iq.answer
91
91
  answer.add(Jabber::Error.new('bad-request'))
92
92
  @component.send(answer)
93
93
  return
94
94
  end
95
- answer = Jabber::XMLStanza.answer(iq)
95
+ answer = iq.answer
96
96
  answer.type = :result
97
97
  if iq.to.node == nil
98
98
  @worlds.each { |node,world|
@@ -107,7 +107,7 @@ class AdventureMUC
107
107
 
108
108
  world = @worlds[pres.to.node]
109
109
  if world.nil?
110
- answer = Jabber::XMLStanza.answer(pres)
110
+ answer = pres.answer
111
111
  answer.type = :error
112
112
  answer.add(Jabber::Error.new('item-not-found', 'The world you are trying to reach is currently unavailable.'))
113
113
  @component.send(answer)
@@ -123,7 +123,7 @@ class AdventureMUC
123
123
 
124
124
  world = @worlds[msg.to.node]
125
125
  if world.nil?
126
- answer = Jabber::XMLStanza.answer(msg)
126
+ answer = msg.answer
127
127
  answer.type = :error
128
128
  answer.add(Jabber::Error.new('item-not-found', 'The world you are trying to reach is currently unavailable.'))
129
129
  @component.send(answer)
@@ -133,7 +133,7 @@ class World < REXML::Element
133
133
 
134
134
  # Disallow nick changes
135
135
  if thing.kind_of?(Player) && (pres.from == thing.jid) && (player != thing)
136
- answer = Jabber::XMLStanza.answer(pres, false)
136
+ answer = pres.answer(false)
137
137
  answer.type = :error
138
138
  answer.add(Jabber::Error.new('not-acceptable', 'Nickchange not allowed'))
139
139
  send(thing.iname, answer)
@@ -143,7 +143,7 @@ class World < REXML::Element
143
143
 
144
144
  # Either nick-collission or empty nick
145
145
  unless (player.nil? || pres.from == player.jid) && (pres.to.resource.to_s.size > 1)
146
- answer = Jabber::XMLStanza.answer(pres)
146
+ answer = pres.answer
147
147
  answer.type = :error
148
148
  if (pres.to.resource.to_s.size > 1)
149
149
  answer.add(Jabber::Error::new('conflict', 'Nickname already used'))
@@ -188,7 +188,7 @@ class World < REXML::Element
188
188
  }
189
189
 
190
190
  if player.nil?
191
- answer = Jabber::XMLStanza.answer(msg)
191
+ answer = msg.answer
192
192
  answer.type = :error
193
193
  answer.add(Jabber::Error::new('forbidden'))
194
194
  send(msg.to.resource, answer)
@@ -68,7 +68,7 @@ class Room
68
68
  # Push user-list
69
69
  userinfo = Jabber::Presence.import(pres)
70
70
  userinfo.to = pres.from
71
- userinfo.add(Jabber::XMucUser.new).add(Jabber::XMucUserItem.new(:none, :participant))
71
+ userinfo.add(Jabber::XMUCUser.new).add(Jabber::XMUCUserItem.new(:none, :participant))
72
72
  print "Sending all users for #{pres.to} to #{pres.from}:"
73
73
  @users.each { |nick,jid|
74
74
  userinfo.from = Jabber::JID::new(@name.node, @name.domain, nick)
@@ -100,9 +100,9 @@ class Room
100
100
 
101
101
  # Advertise users presence to all
102
102
  puts "Advertising user to all"
103
- x = Jabber::XMucUserItem.new(:none, :participant, pres.from)
103
+ x = Jabber::XMUCUserItem.new(:none, :participant, pres.from)
104
104
  x.reason = reason
105
- pres.add(Jabber::XMucUser.new).add(x)
105
+ pres.add(Jabber::XMUCUser.new).add(x)
106
106
  pres.from = pres.to
107
107
  broadcast(pres)
108
108
  end
@@ -217,8 +217,8 @@ class MUC
217
217
  end
218
218
  [Jabber::IqQueryDiscoInfo.new.namespace,
219
219
  Jabber::IqQueryDiscoItems.new.namespace,
220
- Jabber::XMuc.new.namespace,
221
- Jabber::XMucUser.new.namespace].each { |ns|
220
+ Jabber::XMUC.new.namespace,
221
+ Jabber::XMUCUser.new.namespace].each { |ns|
222
222
  iq.query.add(Jabber::DiscoFeature.new(ns))
223
223
  }
224
224
  else
@@ -1,4 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # =XMPP4R - XMPP Library for Ruby
3
+ # License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
4
+ # Website::http://home.gna.org/xmpp4r/
5
+
2
6
 
3
7
  # This is PING for Jabber
4
8
  #
@@ -6,6 +10,7 @@
6
10
 
7
11
 
8
12
  require 'xmpp4r'
13
+ require 'xmpp4r/httpbinding'
9
14
  require 'xmpp4r/version/iq/version'
10
15
  require 'xmpp4r/discovery/iq/discoinfo'
11
16
  require 'optparse'
@@ -69,8 +74,13 @@ end
69
74
  # Connection
70
75
  ##
71
76
 
72
- cl = Jabber::Client.new(Jabber::JID.new(account['jid']))
73
- cl.connect(account['host'], (account['port'] ? account['port'].to_i : 5222))
77
+ if account['http bind']
78
+ cl = Jabber::HTTPBinding::Client.new(Jabber::JID.new(account['jid']))
79
+ cl.connect(account['http bind'])
80
+ else
81
+ cl = Jabber::Client.new(Jabber::JID.new(account['jid']))
82
+ cl.connect(account['host'], (account['port'] ? account['port'].to_i : 5222))
83
+ end
74
84
  cl.auth(account['password'])
75
85
 
76
86
  ##
@@ -79,7 +89,7 @@ cl.auth(account['password'])
79
89
 
80
90
  def print_reply(iq, roundtrip)
81
91
  roundtrip_s = ((roundtrip * 100).round / 100.0).to_s + " sec"
82
- output = "Received a #{iq.query.namespace} #{iq.type} from #{iq.from} (#{roundtrip_s}): "
92
+ output = "Received a #{iq.query.namespace} #{iq.type} (id: #{iq.id}) from #{iq.from} (#{roundtrip_s}): "
83
93
 
84
94
  if iq.query.kind_of?(Jabber::Version::IqQueryVersion)
85
95
  output += "#{iq.query.iname}-#{iq.query.version} #{iq.query.os}"
@@ -102,6 +112,9 @@ end
102
112
  ##
103
113
  # Main loop
104
114
  ##
115
+
116
+ require 'mprofiler'
117
+ MemoryProfiler.start(:string_debug=>true)
105
118
 
106
119
  puts "XMPPING #{cl.jid} -> #{jid}"
107
120
  query_methods = ['jabber:iq:version', 'jabber:iq:time', 'http://jabber.org/protocol/disco#info']
@@ -128,7 +141,7 @@ loop {
128
141
  if query_method >= query_methods.size
129
142
  query_method = 0
130
143
  end
131
-
144
+
132
145
  sleep(interval)
133
146
  }
134
147
 
@@ -7,3 +7,8 @@ other_account:
7
7
  password: xxx
8
8
  host: 127.0.0.1
9
9
  port: 65222
10
+
11
+ web_account:
12
+ jid: me@domain/ping
13
+ password: xxx
14
+ http bind: http://domain/http-bind/
@@ -21,9 +21,13 @@ puts "Connected ! send messages to #{myJID.strip.to_s}."
21
21
  mainthread = Thread.current
22
22
  cl.add_message_callback do |m|
23
23
  if m.type != :error
24
- cl.send(Message::new(m.from, "You sent: #{m.body}"))
24
+ m2 = Message::new(m.from, "You sent: #{m.body}")
25
+ m2.type = m.type
26
+ cl.send(m2)
25
27
  if m.body == 'exit'
26
- cl.send(Message::new(m.from, "Exiting ..."))
28
+ m2 = Message::new(m.from, "Exiting ...")
29
+ m2.type = m.type
30
+ cl.send(m2)
27
31
  mainthread.wakeup
28
32
  end
29
33
  end
@@ -0,0 +1,13 @@
1
+ require 'xmpp4r'
2
+ require 'xmpp4r/muc'
3
+
4
+ client = Jabber::Client.new('admin@myserver.co.uk/ruby')
5
+ muc = Jabber::MUC::MUCClient.new(client)
6
+ client.connect
7
+ client.auth('admin')
8
+ muc.join('room@conference.myserver.co.uk/admin')
9
+ muc.configure(
10
+ 'muc#roomconfig_roomname' => 'roomname',
11
+ 'muc#roomconfig_persistentroom' => 1
12
+ )
13
+
@@ -59,12 +59,6 @@
59
59
  # But instead check for the query's class:
60
60
  # <tt>iq.query.kind_of?(Jabber::IqQueryDiscoInfo)</tt>
61
61
  #
62
- # ==Threaded and non-threaded modes
63
- #
64
- # From the user's point of view, the library can be used either in threaded mode,
65
- # or in non-threaded mode, using a call to <tt>Jabber::Stream#process</tt> to
66
- # receive pending messages.
67
- #
68
62
  # ==Where to begin?
69
63
  #
70
64
  # Because it is built in an extensible way, it might be hard for newcomers to
@@ -2,8 +2,7 @@
2
2
  # License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
3
3
  # Website::http://home.gna.org/xmpp4r/
4
4
 
5
- require 'callbacks'
6
-
5
+ require 'xmpp4r/callbacks'
7
6
  require 'xmpp4r/bytestreams/iq/si'
8
7
  require 'xmpp4r/dataforms/x/data'
9
8
  require 'xmpp4r/bytestreams/helper/ibb/base'
@@ -199,8 +198,8 @@ module Jabber
199
198
  si.feature.x.type = :submit
200
199
  stream_method = si.feature.x.field('stream-method')
201
200
 
202
- if stream_method.options.keys.include?(Bytestreams::IqQueryBytestreams::NS_BYTESTREAMS) and @allow_bytestreams
203
- stream_method.values = [Bytestreams::IqQueryBytestreams::NS_BYTESTREAMS]
201
+ if stream_method.options.keys.include?(Bytestreams::NS_BYTESTREAMS) and @allow_bytestreams
202
+ stream_method.values = [Bytestreams::NS_BYTESTREAMS]
204
203
  stream_method.options = []
205
204
  @stream.send(answer)
206
205
 
@@ -254,7 +253,7 @@ module Jabber
254
253
 
255
254
  offered_methods = {}
256
255
  if @allow_bytestreams
257
- offered_methods[Bytestreams::IqQueryBytestreams::NS_BYTESTREAMS] = nil
256
+ offered_methods[Bytestreams::NS_BYTESTREAMS] = nil
258
257
  end
259
258
  if @allow_ibb
260
259
  offered_methods[Bytestreams::IBB::NS_IBB] = nil
@@ -262,7 +261,7 @@ module Jabber
262
261
 
263
262
  iq = Iq::new(:set, jid)
264
263
  iq.from = from
265
- si = iq.add(Bytestreams::IqSi.new(session_id, Bytestreams::IqSi::PROFILE_FILETRANSFER, source.mime))
264
+ si = iq.add(Bytestreams::IqSi.new(session_id, Bytestreams::PROFILE_FILETRANSFER, source.mime))
266
265
 
267
266
  file = si.add(Bytestreams::IqSiFile.new(source.filename, source.size))
268
267
  file.hash = source.md5
@@ -304,7 +303,7 @@ module Jabber
304
303
  end
305
304
  end
306
305
 
307
- if stream_method == Bytestreams::IqQueryBytestreams::NS_BYTESTREAMS and @allow_bytestreams
306
+ if stream_method == Bytestreams::NS_BYTESTREAMS and @allow_bytestreams
308
307
  Bytestreams::SOCKS5BytestreamsInitiator.new(@stream, session_id, from, jid)
309
308
  elsif stream_method == Bytestreams::IBB::NS_IBB and @allow_ibb
310
309
  Bytestreams::IBBInitiator.new(@stream, session_id, from, jid)
@@ -38,8 +38,7 @@ module Jabber
38
38
  @seq_recv = 0
39
39
  @queue = []
40
40
  @queue_lock = Mutex.new
41
- @pending = Mutex.new
42
- @pending.lock
41
+ @pending = Semaphore.new
43
42
  @sendbuf = ''
44
43
  @sendbuf_lock = Mutex.new
45
44
 
@@ -105,7 +104,7 @@ module Jabber
105
104
  }
106
105
 
107
106
  # No data? Wait for next to arrive...
108
- @pending.lock unless res
107
+ @pending.wait unless res
109
108
  end
110
109
 
111
110
  if res.type == :data
@@ -188,12 +187,12 @@ module Jabber
188
187
  if msg.type == nil
189
188
  @queue_lock.synchronize {
190
189
  @queue.push IBBQueueItem.new(:data, data.attributes['seq'], data.text.to_s)
191
- @pending.unlock
190
+ @pending.run
192
191
  }
193
192
  elsif msg.type == :error
194
193
  @queue_lock.synchronize {
195
194
  @queue << IBBQueueItem.new(:close)
196
- @pending.unlock
195
+ @pending.run
197
196
  }
198
197
  end
199
198
  true
@@ -211,7 +210,7 @@ module Jabber
211
210
 
212
211
  @queue_lock.synchronize {
213
212
  @queue << IBBQueueItem.new(:close)
214
- @pending.unlock
213
+ @pending.run
215
214
  }
216
215
  true
217
216
  else
@@ -19,8 +19,7 @@ module Jabber
19
19
  # Wait for the initiator side to start
20
20
  # the stream.
21
21
  def accept
22
- connect_lock = Mutex.new
23
- connect_lock.lock
22
+ connect_sem = Semaphore.new
24
23
 
25
24
  @stream.add_iq_callback(200, self) { |iq|
26
25
  open = iq.first_element('open')
@@ -33,15 +32,14 @@ module Jabber
33
32
  reply.type = :result
34
33
  @stream.send(reply)
35
34
 
36
- connect_lock.unlock
35
+ connect_sem.run
37
36
  true
38
37
  else
39
38
  false
40
39
  end
41
40
  }
42
41
 
43
- connect_lock.lock
44
- connect_lock.unlock
42
+ connect_sem.wait
45
43
  true
46
44
  end
47
45
  end
@@ -7,7 +7,7 @@ require 'thread'
7
7
  require 'timeout'
8
8
  require 'digest/sha1'
9
9
 
10
- require 'callbacks'
10
+ require 'xmpp4r/callbacks'
11
11
 
12
12
  module Jabber
13
13
  module Bytestreams
@@ -35,21 +35,23 @@ module Jabber
35
35
  socket = TCPServer.new(port)
36
36
  end
37
37
 
38
- Thread.new {
39
- loop {
38
+ Thread.new do
39
+ Thread.current.abort_on_exception = true
40
+ loop do
40
41
  peer = SOCKS5BytestreamsPeer.new(socket.accept)
41
- Thread.new {
42
+ Thread.new do
43
+ Thread.current.abort_on_exception = true
42
44
  begin
43
45
  peer.start
44
46
  rescue
45
47
  Jabber::debuglog("SOCKS5 BytestreamsServer: Error accepting peer: #{$!}")
46
48
  end
47
- }
48
- @peers_lock.synchronize {
49
+ end
50
+ @peers_lock.synchronize do
49
51
  @peers << peer
50
- }
51
- }
52
- }
52
+ end
53
+ end
54
+ end
53
55
  end
54
56
 
55
57
  ##
@@ -13,8 +13,7 @@ module Jabber
13
13
  # May raise various exceptions
14
14
  def accept
15
15
  error = nil
16
- connect_lock = Mutex.new
17
- connect_lock.lock
16
+ connect_sem = Semaphore.new
18
17
 
19
18
  @stream.add_iq_callback(200, self) { |iq|
20
19
  if iq.type == :set and iq.from == @initiator_jid and iq.to == @target_jid and iq.query.kind_of?(IqQueryBytestreams)
@@ -47,15 +46,14 @@ module Jabber
47
46
  error = e
48
47
  end
49
48
 
50
- connect_lock.unlock
49
+ connect_sem.run
51
50
  true
52
51
  else
53
52
  false
54
53
  end
55
54
  }
56
55
 
57
- connect_lock.lock
58
- connect_lock.unlock
56
+ connect_sem.wait
59
57
  raise error if error
60
58
  (@socks != nil)
61
59
  end