xmpp4r 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
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