em-xmpp 0.0.11 → 0.0.12

Sign up to get free protection for your applications and to get access to all the features.
data/bin/xmig CHANGED
@@ -1,5 +1,5 @@
1
1
  $LOAD_PATH.unshift './lib'
2
- require 'em-xmpp'
2
+ require 'em-xmpp/connection'
3
3
  require 'em-xmpp/helpers'
4
4
  require 'em-xmpp/conversation'
5
5
 
@@ -46,7 +46,7 @@ module Command extend self
46
46
  end
47
47
 
48
48
  def print_context_dataforms(ctx)
49
- df = ctx.bit!(:dataforms)
49
+ df = ctx.bit(:dataforms)
50
50
  df.x_forms.each do |form|
51
51
  print_dataform form
52
52
  end
@@ -116,7 +116,7 @@ module Command extend self
116
116
  lambda do |client|
117
117
  puts "=== PubSub Subscriptions on #{jid} (#{node}) ==="
118
118
  ctx = client.entity(jid).pubsub(node).service_subscriptions
119
- ctx.bit!(:pubsub).subscriptions.each do |s|
119
+ ctx.bit(:pubsub).subscriptions.each do |s|
120
120
  puts "#{s.node} -- #{s.subscription} (#{s.sub_id})"
121
121
  end
122
122
  end
@@ -125,7 +125,7 @@ module Command extend self
125
125
  lambda do |client|
126
126
  puts "=== PubSub Affiliations on #{jid} (#{node}) ==="
127
127
  ctx = client.entity(jid).pubsub(node).service_affiliations
128
- ctx.bit!(:pubsub).affiliations.each do |s|
128
+ ctx.bit(:pubsub).affiliations.each do |s|
129
129
  puts "#{s.node} (#{s.affiliation})"
130
130
  end
131
131
  end
@@ -182,7 +182,7 @@ module Command extend self
182
182
  lambda do |client|
183
183
  puts "publishing #{payload.size} bytes to #{jid} (#{node})"
184
184
  ctx = client.entity(jid).pubsub(node).publish(payload)
185
- ctx.bit!(:pubsub).items.each do |item|
185
+ ctx.bit(:pubsub).items.each do |item|
186
186
  puts "published: #{item.item_id} at #{item.node}"
187
187
  end
188
188
  end
@@ -215,7 +215,7 @@ module Command extend self
215
215
  lambda do |client|
216
216
  puts "=== PubSub Subscriptions on #{jid} ==="
217
217
  ctx = client.entity(jid).pubsub(node).subscriptions
218
- ctx.bit!(:pubsubowner).subscriptions.each do |s|
218
+ ctx.bit(:pubsubowner).subscriptions.each do |s|
219
219
  puts "#{s.jid} -- #{s.subscription} (#{s.sub_id})"
220
220
  end
221
221
  end
@@ -224,7 +224,7 @@ module Command extend self
224
224
  lambda do |client|
225
225
  puts "=== PubSub Affiliations on #{jid} ==="
226
226
  ctx = client.entity(jid).pubsub(node).affiliations
227
- ctx.bit!(:pubsubowner).affiliations.each do |s|
227
+ ctx.bit(:pubsubowner).affiliations.each do |s|
228
228
  puts "#{s.jid} (#{s.affiliation})"
229
229
  end
230
230
  end
@@ -366,13 +366,15 @@ module Command extend self
366
366
 
367
367
  client.entity(dst).say("",'chat', xmlproc)
368
368
  client.on_iq do |ctx|
369
- bob = ctx.bit(:bob)
370
- if bob and (bob.cid == item.cid)
371
- puts "sending bob"
372
- iq = bob.reply(item)
373
- client.send_stanza iq
374
- ctx.delete_xpath_handler!
375
- ctx.done!
369
+ if ctx.bit?(:bob)
370
+ bob = ctx.bit(:bob)
371
+ if (bob.cid == item.cid)
372
+ puts "sending bob"
373
+ iq = bob.reply(item)
374
+ client.send_stanza iq
375
+ ctx.delete_xpath_handler!
376
+ ctx.done!
377
+ end
376
378
  end
377
379
  ctx
378
380
  end
@@ -484,11 +486,11 @@ module Command extend self
484
486
  disco = client.entity(dst).discover_infos(node)
485
487
 
486
488
  puts "=== Identities ==="
487
- disco.bit!(:discoinfos).identities.each do |i|
489
+ disco.bit(:discoinfos).identities.each do |i|
488
490
  puts "#{i.category}/#{i.type}: #{i.name || "_"}"
489
491
  end
490
492
  puts "=== Features ==="
491
- disco.bit!(:discoinfos).features.each do |f|
493
+ disco.bit(:discoinfos).features.each do |f|
492
494
  puts "#{f.var}"
493
495
  end
494
496
  end
@@ -500,7 +502,7 @@ module Command extend self
500
502
  disco = client.entity(dst).discover_items(node)
501
503
 
502
504
  puts "=== Items ==="
503
- disco.bit!(:discoitems).items.each do |i|
505
+ disco.bit(:discoitems).items.each do |i|
504
506
  puts "#{i.entity} (#{i.node}) -- #{i.name || i.entity}"
505
507
  end
506
508
  end
@@ -594,6 +596,8 @@ module RosterClient
594
596
  attr_reader :queue
595
597
 
596
598
  def ready
599
+ @handler.enable_default_stack_decorators!
600
+
597
601
  @show_xml = false
598
602
  puts "***** #{@jid} ready"
599
603
  user_data.each{|c| handle_command c}
@@ -607,7 +611,7 @@ module RosterClient
607
611
 
608
612
  # Signal presence subscriptions
609
613
  on_presence do |ctx|
610
- pre = ctx.bit!(:presence)
614
+ pre = ctx.bit(:presence)
611
615
  if pre.subscription_request?
612
616
  puts "=== Presence subscription request from: #{pre.from.bare}"
613
617
  ctx.done!
@@ -617,15 +621,15 @@ module RosterClient
617
621
 
618
622
  # Signal people arriving and leaving
619
623
  on_presence do |ctx|
620
- pre = ctx.bit!(:presence)
624
+ pre = ctx.bit(:presence)
621
625
  puts "=== Presence #{pre.from}: #{pre.type}"
622
626
  ctx.done!
623
627
  end
624
628
 
625
629
  # Acknowledge roster change
626
630
  on_iq do |ctx|
627
- roster = ctx.bit(:roster)
628
- if roster
631
+ if ctx.bit?(:roster)
632
+ roster = ctx.bit(:roster)
629
633
  if roster.type == 'set'
630
634
  puts "=== Roster change ==="
631
635
  roster.items.each do |item|
@@ -640,8 +644,8 @@ module RosterClient
640
644
 
641
645
  # Replies to item queries
642
646
  on_iq do |ctx|
643
- query = ctx.bit(:discoitems)
644
- if query
647
+ if ctx.bit?(:discoitems)
648
+ query = ctx.bit(:discoitems)
645
649
  list = items(query.to,query.node)
646
650
  puts "==== #{query.from} discovers #{list.size} items at node #{query.node} ==="
647
651
  reply = query.reply do |iq|
@@ -661,9 +665,8 @@ module RosterClient
661
665
 
662
666
  # Replies to command queries
663
667
  on_iq do |ctx|
664
- query = ctx.bit(:command)
665
-
666
- if query
668
+ if ctx.bit?(:command)
669
+ query = ctx.bit(:command)
667
670
  if query.sessionid
668
671
  key = "command:#{query.from}:#{query.node}:#{query.sessionid}"
669
672
  conv = conversation(key)
@@ -720,10 +723,10 @@ module RosterClient
720
723
 
721
724
  # Prints Pubsub event
722
725
  on_message do |ctx|
723
- event = ctx.bit(:pubsubevent)
724
- delay = ctx.bit(:delay)
725
- stamp = delay.stamp if delay
726
- if event
726
+ if ctx.bit?(:pubsubevent)
727
+ event = ctx.bit(:pubsubevent)
728
+ delay = ctx.bit(:delay)
729
+ stamp = delay.stamp
727
730
  puts "=== PubSub event #{event.service} #{stamp} ==="
728
731
  if event.items_node #oddly enough, retractions fall in items_node
729
732
  items = event.items
@@ -763,8 +766,8 @@ module RosterClient
763
766
  ctx.done!
764
767
  end
765
768
 
766
- event = ctx.bit(:pubsub)
767
- if event
769
+ if ctx.bit?(:pubsub)
770
+ event = ctx.bit(:pubsub)
768
771
  puts "=== PubSub #{event.service} ==="
769
772
  event.subscriptions.each do |sub|
770
773
  puts "subscription of #{sub.jid} (#{sub.sub_id}) status is now #{sub.subscription} for #{sub.node}"
@@ -776,8 +779,8 @@ module RosterClient
776
779
  end
777
780
 
778
781
  on_iq do |ctx|
779
- si = ctx.bit(:streaminitiation)
780
- if si
782
+ if ctx.bit?(:streaminitiation)
783
+ si = ctx.bit(:streaminitiation)
781
784
  puts "=== FileTransfer request from #{si.from}:#{si.id} ==="
782
785
  puts "file details: #{si.file_name} (#{si.file_size} bytes) (mime:#{si.mime_type})"
783
786
  puts "description: #{si.description}" if si.description
@@ -796,8 +799,8 @@ module RosterClient
796
799
  end
797
800
 
798
801
  on_iq do |ctx|
799
- ibb = ctx.bit(:ibb)
800
- if ibb
802
+ if ctx.bit?(:ibb)
803
+ ibb = ctx.bit(:ibb)
801
804
  key = ibb_conversation_key(ibb)
802
805
 
803
806
  if ibb.open_node
@@ -954,7 +957,7 @@ module RosterClient
954
957
  end
955
958
 
956
959
  def default_dataform_conversation(ctx, banner, &action)
957
- ctx.env['dataform'] = ctx.bit!(:dataforms).form
960
+ ctx.env['dataform'] = ctx.bit(:dataforms).form
958
961
  dataform_conversation(ctx) do |step|
959
962
  step.on(:start) do
960
963
  puts banner
@@ -16,5 +16,6 @@ Gem::Specification.new do |gem|
16
16
  gem.version = Em::Xmpp::VERSION
17
17
  gem.add_dependency "eventmachine"
18
18
  gem.add_dependency "nokogiri"
19
+ gem.add_dependency "ox"
19
20
  gem.add_dependency "ruby-sasl"
20
21
  end
@@ -1,6 +1,4 @@
1
- require 'eventmachine'
2
1
  require "em-xmpp/version"
3
- require "em-xmpp/connection"
4
2
 
5
3
  module EM
6
4
  module Xmpp
@@ -0,0 +1,18 @@
1
+ require 'em-xmpp/namespaces'
2
+
3
+ module EM::Xmpp
4
+ module Component
5
+ def stream_start(node)
6
+ send_raw("<handshake>#{Digest::SHA1.hexdigest(node['id']+@pass)}</handshake>")
7
+ end
8
+
9
+ private
10
+ def open_xml_stream_tag
11
+ "<stream:stream
12
+ to='#{@jid}'
13
+ xmlns='#{Namespaces::Component}:accept'
14
+ xmlns:stream='#{Namespaces::Stream}'
15
+ >"
16
+ end
17
+ end
18
+ end
@@ -1,22 +1,39 @@
1
1
 
2
+ require 'eventmachine'
3
+
2
4
  require 'em-xmpp/namespaces'
3
- require 'em-xmpp/connector'
4
- require 'em-xmpp/handler'
5
+ require 'em-xmpp/evented'
5
6
  require 'em-xmpp/jid'
6
- require 'em-xmpp/entity'
7
- require 'em-xmpp/cert_store'
8
- require 'eventmachine'
9
- require 'fiber'
7
+ require 'em-xmpp/component'
8
+ require 'em-xmpp/resolver'
9
+
10
10
 
11
11
  module EM::Xmpp
12
12
  class Connection < EM::Connection
13
13
  include Namespaces
14
- include Connector
14
+ include Evented
15
15
 
16
16
  attr_reader :jid, :pass, :user_data
17
17
 
18
+ def self.start(jid, pass=nil, mod=nil, cfg={}, server=nil, port=5222, &blk)
19
+ jid = JID.parse jid
20
+ if server.nil?
21
+ record = Resolver.resolve jid.domain
22
+ if record
23
+ server = record.target.to_s
24
+ port = record.port
25
+ else
26
+ server = jid.domain
27
+ end
28
+ end
29
+
30
+ EM.connect(server, port, self, jid, pass, mod, cfg, &blk)
31
+ end
32
+
18
33
  def initialize(jid, pass, mod=nil, cfg={})
19
34
  @jid = jid
35
+ @component = jid.node.nil?
36
+ self.extend Component if component?
20
37
  @pass = pass.dup.freeze
21
38
  self.extend mod if mod
22
39
  certdir = cfg[:certificates]
@@ -30,112 +47,27 @@ module EM::Xmpp
30
47
 
31
48
  def post_init
32
49
  super
33
- @handler = StreamNegotiation.new self
50
+ prepare_parser!
51
+ set_negotiation_handler!
34
52
  end
35
53
 
36
- def stanza_start(node)
54
+ def send_raw(data)
55
+ puts ">> out\n#{data}\n" if $DEBUG
56
+ send_data data
37
57
  end
38
58
 
39
- def stanza_end(node)
40
- Fiber.new { @handler.handle(node) }.resume
59
+ def receive_data(dat)
60
+ puts "<< in\n#{dat}\n" if $DEBUG
61
+ receive_raw(dat)
41
62
  end
42
63
 
43
- def unhandled_stanza(node)
44
- raise RuntimeError, "did not handle node:\n#{node}"
64
+ def unbind
65
+ puts "**** unbound ****" if $DEBUG
45
66
  end
46
67
 
47
- def jid_received(jid)
48
- @jid = entity jid
49
- end
50
-
51
- def entity(jid)
52
- Entity.new(self, jid)
53
- end
54
-
55
- def negotiation_finished
56
- @pass = nil
57
- @handler = Routine.new self
58
- send_stanza presence_stanza()
59
- framework_ready if respond_to? :framework_ready
60
- ready
61
- end
62
-
63
- def negotiation_failed(node)
64
- raise RuntimeError, "could not negotiate a stream:\n#{node}"
65
- end
66
-
67
- OutgoingStanza = Struct.new(:xml, :params)
68
-
69
- def default_presence_params
70
- {}
71
- end
72
-
73
- def default_message_params
74
- {'to' => @jid.domain, 'id' => "em-xmpp.#{rand(65535)}"}
75
- end
76
-
77
- def default_iq_params
78
- {'type' => 'get', 'id' => "em-xmpp.#{rand(65535)}"}
79
- end
80
-
81
- def presence_stanza(params={}, &blk)
82
- params = default_presence_params.merge(params)
83
- xml = build_xml do |x|
84
- x.presence(params, &blk)
85
- end
86
- OutgoingStanza.new xml, params
87
- end
88
-
89
- def message_stanza(params={}, &blk)
90
- params = default_message_params.merge(params)
91
- xml = build_xml do |x|
92
- x.message(params, &blk)
93
- end
94
- OutgoingStanza.new xml, params
95
- end
96
-
97
- def iq_stanza(params={}, &blk)
98
- params = default_iq_params.merge(params)
99
- xml = build_xml do |x|
100
- x.iq(params, &blk)
101
- end
102
- OutgoingStanza.new xml, params
103
- end
104
-
105
- def send_stanza(stanza)
106
- send_raw stanza.xml
107
- if block_given?
108
- upon(:anything) do |ctx|
109
- if ctx.bit!(:stanza).id == stanza.params['id']
110
- yield ctx
111
- ctx.delete_xpath_handler!
112
- else
113
- ctx
114
- end
115
- end
116
- end
117
- end
118
-
119
- %w{upon on on_exception on_presence on_iq on_message on_decorator on_iq_decorator on_presence_decorator on_message_decorator}.each do |meth|
120
- define_method(meth) do |*args,&blk|
121
- @handler.send meth, *args, &blk
122
- end
123
- end
124
-
125
- def ready
126
- end
127
-
128
- def start_using_tls_and_reset_stream
68
+ def initiate_tls
129
69
  bool = !! @certstore
130
70
  start_tls(:verify_peer => bool)
131
- restart_xml_stream
132
71
  end
133
-
134
- def ssl_verify_peer(pem)
135
- @certstore.trusted?(pem).tap do |trusted|
136
- close_connection unless trusted
137
- end
138
- end
139
-
140
72
  end
141
73
  end
@@ -89,11 +89,7 @@ module EM::Xmpp
89
89
  end
90
90
 
91
91
  def bit(klassname)
92
- bits[bit_klass_name(klassname)]
93
- end
94
-
95
- def bit!(klassname)
96
- ret = bit klassname
92
+ ret = bits[bit_klass_name(klassname)]
97
93
  unless ret
98
94
  klass = if klassname.is_a?(Class)
99
95
  klassname
@@ -105,6 +101,16 @@ module EM::Xmpp
105
101
  ret
106
102
  end
107
103
 
104
+ def bit!(klassname)
105
+ if $DEBUG
106
+ $stderr.puts "EM::Xmpp::Context#bit! is outdated, please use bit (without bang)"
107
+ line = caller.first
108
+ $stderr.puts " caller is here> #{line}"
109
+ end
110
+ bit klassname
111
+ end
112
+
113
+
108
114
  def bit?(klassname)
109
115
  bits.has_key? bit_klass_name(klassname)
110
116
  end
@@ -177,9 +183,8 @@ module EM::Xmpp
177
183
  jid = connection.jid.full
178
184
  {'from' => jid, 'to' => from, 'id' => id}
179
185
  end
180
- def reply(args={},&blk)
181
- args = reply_default_params.merge args
182
- connection.presence_stanza(args,&blk)
186
+ def reply(*args)
187
+ connection.presence_stanza(reply_default_params,*args)
183
188
  end
184
189
  def priority_node
185
190
  xpath('//xmlns:priority',{'xmlns' => Client}).first
@@ -236,9 +241,8 @@ module EM::Xmpp
236
241
  h
237
242
  end
238
243
 
239
- def reply(args={},&blk)
240
- args = reply_default_params.merge args
241
- connection.message_stanza(args,&blk)
244
+ def reply(*args)
245
+ connection.message_stanza(reply_default_params,*args)
242
246
  end
243
247
 
244
248
  def groupchat?
@@ -261,9 +265,8 @@ module EM::Xmpp
261
265
  {'from' => jid, 'to' => from, 'type' => 'result', 'id' => id}
262
266
  end
263
267
 
264
- def reply(args={},&blk)
265
- args = reply_default_params.merge args
266
- connection.iq_stanza(args,&blk)
268
+ def reply(*args)
269
+ connection.iq_stanza(reply_default_params,*args)
267
270
  end
268
271
  end
269
272
 
@@ -748,15 +751,15 @@ module EM::Xmpp
748
751
  Base64.strict_encode64 data
749
752
  end
750
753
  end
751
-
754
+
752
755
  def reply(item,*args)
753
756
  ref = "cid:#{item.cid}"
754
757
  params = {}
755
758
  params['max-age'] = item.max_age if item.max_age
756
- super(*args) do |xml|
757
- xml.data({:xmlns => EM::Xmpp::Namespaces::BoB, :cid => ref, :type => item.mime}.merge(params), item.b64)
758
- yield xml if block_given?
759
- end
759
+ super(
760
+ x('data',{:xmlns => EM::Xmpp::Namespaces::BoB, :cid => ref, :type => item.mime}.merge(params), item.b64),
761
+ *args
762
+ )
760
763
  end
761
764
 
762
765
  def data_node
@@ -1096,6 +1099,18 @@ module EM::Xmpp
1096
1099
  read_attr(n, 'role') if n
1097
1100
  end
1098
1101
  end
1102
+
1103
+ module Ping
1104
+ include Iq
1105
+
1106
+ def ping?
1107
+ stanza.child && stanza.child.name == 'ping'
1108
+ end
1109
+
1110
+ def pong
1111
+ reply
1112
+ end
1113
+ end
1099
1114
  end
1100
1115
 
1101
1116
  class Bit
@@ -1206,6 +1221,9 @@ module EM::Xmpp
1206
1221
  class Mucuser < Bit
1207
1222
  include Contexts::Mucuser
1208
1223
  end
1224
+ class Ping < Bit
1225
+ include Contexts::Ping
1226
+ end
1209
1227
  end
1210
1228
 
1211
1229
  end