em-xmpp 0.0.11 → 0.0.12

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/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