blather 0.3.4 → 0.4.0

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 (110) hide show
  1. data/LICENSE +1 -1
  2. data/README.rdoc +41 -12
  3. data/examples/echo.rb +1 -1
  4. data/examples/execute.rb +0 -5
  5. data/examples/pubsub/cli.rb +64 -0
  6. data/examples/pubsub/ping_pong.rb +18 -0
  7. data/examples/rosterprint.rb +14 -0
  8. data/examples/xmpp4r/echo.rb +35 -0
  9. data/lib/blather.rb +35 -12
  10. data/lib/blather/client.rb +1 -1
  11. data/lib/blather/client/client.rb +19 -13
  12. data/lib/blather/client/dsl.rb +16 -0
  13. data/lib/blather/client/dsl/pubsub.rb +133 -0
  14. data/lib/blather/core_ext/active_support.rb +1 -117
  15. data/lib/blather/core_ext/active_support/inheritable_attributes.rb +117 -0
  16. data/lib/blather/core_ext/nokogiri.rb +35 -0
  17. data/lib/blather/errors.rb +3 -20
  18. data/lib/blather/errors/sasl_error.rb +3 -1
  19. data/lib/blather/errors/stanza_error.rb +10 -17
  20. data/lib/blather/errors/stream_error.rb +11 -14
  21. data/lib/blather/jid.rb +1 -0
  22. data/lib/blather/roster.rb +9 -0
  23. data/lib/blather/roster_item.rb +6 -1
  24. data/lib/blather/stanza.rb +35 -18
  25. data/lib/blather/stanza/disco.rb +7 -1
  26. data/lib/blather/stanza/disco/disco_info.rb +45 -33
  27. data/lib/blather/stanza/disco/disco_items.rb +32 -21
  28. data/lib/blather/stanza/iq.rb +13 -8
  29. data/lib/blather/stanza/iq/query.rb +16 -8
  30. data/lib/blather/stanza/iq/roster.rb +33 -22
  31. data/lib/blather/stanza/message.rb +20 -31
  32. data/lib/blather/stanza/presence.rb +3 -5
  33. data/lib/blather/stanza/presence/status.rb +13 -21
  34. data/lib/blather/stanza/presence/subscription.rb +11 -16
  35. data/lib/blather/stanza/pubsub.rb +63 -0
  36. data/lib/blather/stanza/pubsub/affiliations.rb +50 -0
  37. data/lib/blather/stanza/pubsub/create.rb +43 -0
  38. data/lib/blather/stanza/pubsub/errors.rb +9 -0
  39. data/lib/blather/stanza/pubsub/event.rb +77 -0
  40. data/lib/blather/stanza/pubsub/items.rb +63 -0
  41. data/lib/blather/stanza/pubsub/publish.rb +58 -0
  42. data/lib/blather/stanza/pubsub/retract.rb +53 -0
  43. data/lib/blather/stanza/pubsub/subscribe.rb +42 -0
  44. data/lib/blather/stanza/pubsub/subscription.rb +66 -0
  45. data/lib/blather/stanza/pubsub/subscriptions.rb +55 -0
  46. data/lib/blather/stanza/pubsub/unsubscribe.rb +42 -0
  47. data/lib/blather/stanza/pubsub_owner.rb +41 -0
  48. data/lib/blather/stanza/pubsub_owner/delete.rb +34 -0
  49. data/lib/blather/stanza/pubsub_owner/purge.rb +34 -0
  50. data/lib/blather/stream.rb +76 -168
  51. data/lib/blather/stream/client.rb +1 -2
  52. data/lib/blather/stream/component.rb +9 -5
  53. data/lib/blather/stream/features.rb +53 -0
  54. data/lib/blather/stream/features/resource.rb +63 -0
  55. data/lib/blather/stream/{sasl.rb → features/sasl.rb} +53 -52
  56. data/lib/blather/stream/features/session.rb +44 -0
  57. data/lib/blather/stream/features/tls.rb +28 -0
  58. data/lib/blather/stream/parser.rb +70 -46
  59. data/lib/blather/xmpp_node.rb +113 -52
  60. data/spec/blather/client/client_spec.rb +44 -58
  61. data/spec/blather/client/dsl/pubsub_spec.rb +465 -0
  62. data/spec/blather/client/dsl_spec.rb +19 -6
  63. data/spec/blather/core_ext/nokogiri_spec.rb +83 -0
  64. data/spec/blather/errors/sasl_error_spec.rb +8 -8
  65. data/spec/blather/errors/stanza_error_spec.rb +25 -33
  66. data/spec/blather/errors/stream_error_spec.rb +21 -16
  67. data/spec/blather/errors_spec.rb +4 -11
  68. data/spec/blather/jid_spec.rb +31 -30
  69. data/spec/blather/roster_item_spec.rb +34 -23
  70. data/spec/blather/roster_spec.rb +27 -12
  71. data/spec/blather/stanza/discos/disco_info_spec.rb +61 -42
  72. data/spec/blather/stanza/discos/disco_items_spec.rb +47 -35
  73. data/spec/blather/stanza/iq/query_spec.rb +34 -11
  74. data/spec/blather/stanza/iq/roster_spec.rb +47 -30
  75. data/spec/blather/stanza/iq_spec.rb +19 -14
  76. data/spec/blather/stanza/message_spec.rb +30 -17
  77. data/spec/blather/stanza/presence/status_spec.rb +43 -20
  78. data/spec/blather/stanza/presence/subscription_spec.rb +41 -21
  79. data/spec/blather/stanza/presence_spec.rb +34 -21
  80. data/spec/blather/stanza/pubsub/affiliations_spec.rb +57 -0
  81. data/spec/blather/stanza/pubsub/create_spec.rb +56 -0
  82. data/spec/blather/stanza/pubsub/event_spec.rb +84 -0
  83. data/spec/blather/stanza/pubsub/items_spec.rb +79 -0
  84. data/spec/blather/stanza/pubsub/publish_spec.rb +83 -0
  85. data/spec/blather/stanza/pubsub/retract_spec.rb +75 -0
  86. data/spec/blather/stanza/pubsub/subscribe_spec.rb +61 -0
  87. data/spec/blather/stanza/pubsub/subscription_spec.rb +97 -0
  88. data/spec/blather/stanza/pubsub/subscriptions_spec.rb +59 -0
  89. data/spec/blather/stanza/pubsub/unsubscribe_spec.rb +61 -0
  90. data/spec/blather/stanza/pubsub_owner/delete_spec.rb +50 -0
  91. data/spec/blather/stanza/pubsub_owner/purge_spec.rb +50 -0
  92. data/spec/blather/stanza/pubsub_owner_spec.rb +27 -0
  93. data/spec/blather/stanza/pubsub_spec.rb +62 -0
  94. data/spec/blather/stanza_spec.rb +53 -38
  95. data/spec/blather/stream/client_spec.rb +231 -88
  96. data/spec/blather/stream/component_spec.rb +14 -5
  97. data/spec/blather/stream/parser_spec.rb +145 -0
  98. data/spec/blather/xmpp_node_spec.rb +192 -96
  99. data/spec/fixtures/pubsub.rb +311 -0
  100. data/spec/spec_helper.rb +5 -4
  101. metadata +54 -18
  102. data/Rakefile +0 -139
  103. data/ext/extconf.rb +0 -65
  104. data/ext/push_parser.c +0 -209
  105. data/lib/blather/core_ext/libxml.rb +0 -28
  106. data/lib/blather/stream/resource.rb +0 -48
  107. data/lib/blather/stream/session.rb +0 -36
  108. data/lib/blather/stream/stream_handler.rb +0 -39
  109. data/lib/blather/stream/tls.rb +0 -33
  110. data/spec/blather/core_ext/libxml_spec.rb +0 -58
data/Rakefile DELETED
@@ -1,139 +0,0 @@
1
- require 'rubygems'
2
- require 'rake'
3
-
4
- begin
5
- require 'jeweler'
6
- Jeweler::Tasks.new do |gem|
7
- gem.name = 'blather'
8
- gem.summary = 'Simpler XMPP'
9
- gem.description = 'An evented XMPP library written on EventMachine and libxml-ruby'
10
-
11
- gem.email = 'sprsquish@gmail.com'
12
- gem.homepage = 'http://github.com/sprsquish/blather'
13
- gem.authors = ['Jeff Smick']
14
-
15
- gem.rubyforge_project = 'squishtech'
16
-
17
- gem.extensions = ['Rakefile']
18
-
19
- gem.add_dependency 'eventmachine', '>= 0.12.6'
20
- gem.add_dependency 'libxml-ruby', '>= 1.1.2'
21
-
22
- gem.files = FileList['examples/**/*', 'lib/**/*', 'ext/*.{rb,c}'].to_a
23
-
24
- gem.test_files = FileList['spec/**/*.rb']
25
-
26
- # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
27
- end
28
- rescue LoadError
29
- puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
30
- end
31
-
32
- require 'rake/testtask'
33
- Rake::TestTask.new(:test) do |test|
34
- test.libs << 'lib' << 'spec'
35
- test.pattern = 'spec/**/*_spec.rb'
36
- test.verbose = true
37
- end
38
-
39
- begin
40
- require 'rcov/rcovtask'
41
- Rcov::RcovTask.new do |test|
42
- test.libs << 'spec'
43
- test.pattern = 'spec/**/*_spec.rb'
44
- test.rcov_opts += ['--exclude \/Library\/Ruby\/Gems,spec\/', '--xrefs']
45
- test.verbose = true
46
- end
47
- rescue LoadError
48
- task :rcov do
49
- abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
50
- end
51
- end
52
-
53
-
54
- begin
55
- require 'hanna/rdoctask'
56
-
57
- Rake::RDocTask.new do |rdoc|
58
- if File.exist?('VERSION.yml')
59
- config = YAML.load(File.read('VERSION.yml'))
60
- version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
61
- else
62
- version = ""
63
- end
64
-
65
- rdoc.rdoc_dir = 'rdoc'
66
- rdoc.title = "blather #{version}"
67
- rdoc.rdoc_files.include('README*')
68
- rdoc.rdoc_files.include('lib/**/*.rb')
69
- rdoc.options += %w[-S -T hanna --main README.rdoc --exclude autotest --exclude vendor]
70
- end
71
- rescue LoadError
72
- task :rdoc do
73
- abort "Hanna is not available. In order to use the Hanna, you must: sudo gem install mislav-hanna"
74
- end
75
- end
76
-
77
- begin
78
- require 'rake/contrib/sshpublisher'
79
- namespace :rubyforge do
80
-
81
- desc "Release gem and RDoc documentation to RubyForge"
82
- task :release => ["rubyforge:release:gem", "rubyforge:release:docs"]
83
-
84
- namespace :release do
85
- desc "Publish RDoc to RubyForge."
86
- task :docs => [:rdoc] do
87
- config = YAML.load(
88
- File.read(File.expand_path('~/.rubyforge/user-config.yml'))
89
- )
90
-
91
- host = "#{config['username']}@rubyforge.org"
92
- remote_dir = "/var/www/gforge-projects/squishtech/blather"
93
- local_dir = 'rdoc'
94
-
95
- Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
96
- end
97
- end
98
- end
99
- rescue LoadError
100
- puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
101
- end
102
-
103
- MAKE = ENV['MAKE'] || (RUBY_PLATFORM =~ /mswin/ ? 'nmake' : 'make')
104
-
105
- namespace :ext do
106
- ext_sources = FileList['ext/*.{rb,c}']
107
-
108
- desc 'Compile the makefile'
109
- file 'ext/Makefile' => ext_sources do
110
- chdir('ext') { ruby 'extconf.rb' }
111
- end
112
-
113
- desc "make extension"
114
- task :make => ext_sources + ['ext/Makefile'] do
115
- chdir('ext') { sh MAKE }
116
- end
117
-
118
- desc 'Build push parser'
119
- task :build => :make
120
-
121
- desc 'Clean extensions'
122
- task :clean do
123
- chdir 'ext' do
124
- sh "rm -f Makefile"
125
- sh "rm -f *.{o,so,bundle,log}"
126
- end
127
- end
128
- end
129
-
130
- # If running under rubygems...
131
- __DIR__ ||= File.expand_path(File.dirname(__FILE__))
132
- if Gem.path.any? {|path| %r(^#{Regexp.escape path}) =~ __DIR__}
133
- task :default => :gem_build
134
- else
135
- task :default => ['ext:build', :test]
136
- end
137
-
138
- desc ":default build when running under rubygems."
139
- task :gem_build => 'ext:build'
@@ -1,65 +0,0 @@
1
- require 'mkmf'
2
-
3
- flags = []
4
-
5
- case RUBY_PLATFORM.split('-',2)[1]
6
- when 'mswin32', 'mingw32', 'bccwin32'
7
- unless have_header('windows.h') and
8
- have_header('winsock.h') and
9
- have_library('kernel32') and
10
- have_library('rpcrt4') and
11
- have_library('gdi32')
12
- exit
13
- end
14
-
15
- flags << "-D OS_WIN32"
16
- flags << '-D BUILD_FOR_RUBY'
17
- flags << "-EHs"
18
- flags << "-GR"
19
-
20
- dir_config('xml2')
21
- exit unless have_library('xml2') && have_header('libxml/parser.h')
22
-
23
- when /solaris/
24
- unless have_library('pthread') and
25
- have_library('nsl') and
26
- have_library('socket')
27
- exit
28
- end
29
-
30
- flags << '-D OS_UNIX'
31
- flags << '-D OS_SOLARIS8'
32
- flags << '-D BUILD_FOR_RUBY'
33
-
34
- dir_config('xml2')
35
- exit unless have_library('xml2') && find_header('libxml/parser.h', '/usr/include/libxml2')
36
-
37
- # on Unix we need a g++ link, not gcc.
38
- #CONFIG['LDSHARED'] = "$(CXX) -shared"
39
-
40
- when /darwin/
41
- flags << '-DOS_UNIX'
42
- flags << '-DBUILD_FOR_RUBY'
43
-
44
- dir_config('xml2')
45
- exit unless have_library('xml2') && find_header('libxml/parser.h', '/usr/include/libxml2')
46
- # on Unix we need a g++ link, not gcc.
47
- #CONFIG['LDSHARED'] = "$(CXX) " + CONFIG['LDSHARED'].split[1..-1].join(' ')
48
-
49
- else
50
- unless have_library('pthread')
51
- exit
52
- end
53
-
54
- flags << '-DOS_UNIX'
55
- flags << '-DBUILD_FOR_RUBY'
56
-
57
- dir_config('xml2')
58
- exit unless have_library('xml2') && find_header('libxml/parser.h', '/usr/include/libxml2')
59
- # on Unix we need a g++ link, not gcc.
60
- #CONFIG['LDSHARED'] = "$(CXX) -shared"
61
- end
62
-
63
- $CFLAGS += ' ' + flags.join(' ')
64
-
65
- create_makefile "push_parser"
@@ -1,209 +0,0 @@
1
- /*
2
- * Most of this was ripped from libxml-ruby's SAX handler
3
- */
4
-
5
- #include <libxml/parser.h>
6
- #include <ruby.h>
7
-
8
- xmlSAXHandler saxHandler;
9
-
10
- static VALUE
11
- push_parser_raise_error (
12
- xmlErrorPtr error)
13
- {
14
- rb_raise(rb_eStandardError, "%s", rb_str_new2((const char*)error->message));
15
- return Qnil;
16
- }
17
-
18
- static VALUE
19
- push_parser_initialize (
20
- VALUE self,
21
- VALUE handler)
22
- {
23
- xmlParserCtxtPtr ctxt;
24
- ctxt = xmlCreatePushParserCtxt(&saxHandler, (void *)handler, NULL, 0, NULL);
25
-
26
- if (!ctxt)
27
- return push_parser_raise_error(&xmlLastError);
28
-
29
- ctxt->sax2 = 1;
30
-
31
- rb_iv_set(self, "@__libxml_push_parser", Data_Wrap_Struct(rb_cData, 0, xmlFreeParserCtxt, ctxt));
32
-
33
- return self;
34
- }
35
-
36
- static VALUE
37
- push_parser_close (
38
- VALUE self)
39
- {
40
- xmlParserCtxtPtr ctxt;
41
- Data_Get_Struct(rb_iv_get(self, "@__libxml_push_parser"), xmlParserCtxt, ctxt);
42
-
43
- if (xmlParseChunk(ctxt, "", 0, 1)) {
44
- return push_parser_raise_error(&xmlLastError);
45
- }
46
- else {
47
- return Qtrue;
48
- }
49
- }
50
-
51
- static VALUE
52
- push_parser_receive (
53
- VALUE self,
54
- VALUE chunk)
55
- {
56
- const char *data = StringValuePtr(chunk);
57
- int length = RSTRING_LEN(chunk);
58
-
59
- xmlParserCtxtPtr ctxt;
60
- Data_Get_Struct(rb_iv_get(self, "@__libxml_push_parser"), xmlParserCtxt, ctxt);
61
-
62
- int i;
63
- // Non-chunking version
64
- for (i = 0; i < length; i++) {
65
- xmlParseChunk (ctxt, data+i, 1, 0);
66
- }
67
-
68
- /* Chunk through in 4KB chunks so as not to overwhelm the buffers
69
- int chunkSize = length < 4096 ? length : 4096;
70
- for (i = 0; i < length; i += chunkSize) {
71
- xmlParseChunk(ctxt, data+i, chunkSize, 0);
72
- }
73
- if ((i -= length) > 0)
74
- xmlParseChunk(ctxt, data+(length-i), i, 0);
75
- */
76
-
77
- return self;
78
- }
79
-
80
- /*********
81
- CALLBACKS
82
- **********/
83
- static void
84
- push_parser_start_element_ns_callback (
85
- void * ctx,
86
- const xmlChar * localname,
87
- const xmlChar * prefix,
88
- const xmlChar * URI,
89
- int nb_namespaces,
90
- const xmlChar ** namespaces,
91
- int nb_attributes,
92
- int nb_defaulted,
93
- const xmlChar ** attributes)
94
- {
95
- VALUE handler = (VALUE) ctx;
96
- if (handler == Qnil)
97
- return;
98
-
99
- VALUE attrHash = rb_hash_new();
100
- VALUE nsHash = rb_hash_new();
101
-
102
- if (attributes)
103
- {
104
- /* Each attribute is an array of [localname, prefix, URI, value, end] */
105
- int i;
106
- for (i = 0; i < nb_attributes * 5; i += 5)
107
- {
108
- rb_hash_aset( attrHash,
109
- rb_str_new2((const char*)attributes[i+0]),
110
- rb_str_new((const char*)attributes[i+3], attributes[i+4] - attributes[i+3]));
111
- }
112
- }
113
-
114
- if (namespaces)
115
- {
116
- int i;
117
- for (i = 0; i < nb_namespaces * 2; i += 2)
118
- {
119
- rb_hash_aset( nsHash,
120
- namespaces[i+0] ? rb_str_new2((const char*)namespaces[i+0]) : Qnil,
121
- namespaces[i+1] ? rb_str_new2((const char*)namespaces[i+1]) : Qnil);
122
- }
123
- }
124
-
125
- rb_funcall(handler, rb_intern("on_start_element_ns"), 5,
126
- rb_str_new2((const char*)localname),
127
- attrHash,
128
- prefix ? rb_str_new2((const char*)prefix) : Qnil,
129
- URI ? rb_str_new2((const char*)URI) : Qnil,
130
- nsHash);
131
- }
132
-
133
- static void
134
- push_parser_end_element_ns_callback (
135
- void * ctx,
136
- const xmlChar * localname,
137
- const xmlChar * prefix,
138
- const xmlChar * URI)
139
- {
140
- VALUE handler = (VALUE) ctx;
141
- if (handler == Qnil)
142
- return;
143
-
144
- rb_funcall(handler, rb_intern("on_end_element_ns"), 3,
145
- rb_str_new2((const char*)localname),
146
- prefix ? rb_str_new2((const char*)prefix) : Qnil,
147
- URI ? rb_str_new2((const char*)URI) : Qnil);
148
- }
149
-
150
-
151
- static void
152
- push_parser_characters_callback (
153
- void *ctx,
154
- const char *chars,
155
- int len)
156
- {
157
- VALUE handler = (VALUE) ctx;
158
- if (handler != Qnil)
159
- rb_funcall (handler, rb_intern("on_characters"), 1, rb_str_new(chars, len));
160
- }
161
-
162
- xmlSAXHandler saxHandler = {
163
- 0, //internalSubset
164
- 0, //isStandalone
165
- 0, //hasInternalSubset
166
- 0, //hasExternalSubset
167
- 0, //resolveEntity
168
- 0, //getEntity
169
- 0, //entityDecl
170
- 0, //notationDecl
171
- 0, //attributeDecl
172
- 0, //elementDecl
173
- 0, //unparsedEntityDecl
174
- 0, //setDocumentLocator
175
- 0, //(startDocument)
176
- 0, //(endDocument)
177
- 0, //startElement
178
- 0, //endElement
179
- 0, //reference
180
- (charactersSAXFunc) push_parser_characters_callback,
181
- 0, //ignorableWhitespace
182
- 0, //processingInstruction
183
- 0, //comment
184
- 0, //warning
185
- 0, //error
186
- 0, //fatalError
187
- 0, //getParameterEntity
188
- 0, //cdataBlock
189
- 0, //externalSubset
190
- XML_SAX2_MAGIC,
191
- 0, //_private
192
- (startElementNsSAX2Func) push_parser_start_element_ns_callback,
193
- (endElementNsSAX2Func) push_parser_end_element_ns_callback,
194
- 0 // LibXML handles this globally
195
- };
196
-
197
- void
198
- Init_push_parser()
199
- {
200
- /* SaxPushParser */
201
- VALUE mLibXML = rb_define_module("LibXML");
202
- VALUE mXML = rb_define_module_under(mLibXML, "XML");
203
- VALUE cXMLSaxPushParser = rb_define_class_under(mXML, "SaxPushParser", rb_cObject);
204
-
205
- /* Instance Methods */
206
- rb_define_method(cXMLSaxPushParser, "initialize", push_parser_initialize, 1);
207
- rb_define_method(cXMLSaxPushParser, "receive", push_parser_receive, 1);
208
- rb_define_method(cXMLSaxPushParser, "close", push_parser_close, 0);
209
- }
@@ -1,28 +0,0 @@
1
- module LibXML # :nodoc:
2
- module XML # :nodoc:
3
-
4
- class Node
5
- alias_method :element_name, :name
6
- alias_method :element_name=, :name=
7
- end
8
-
9
- class Attributes
10
- # Helper method for removing attributes
11
- def remove(name)
12
- attribute = get_attribute(name.to_s)
13
- attribute.remove! if attribute
14
- end
15
-
16
- alias_method :old_hash_set, :[]= # :nodoc:
17
- def []=(name, val)
18
- val.nil? ? remove(name.to_s) : old_hash_set(name.to_s, val.to_s)
19
- end
20
-
21
- alias_method :old_hash_get, :[] # :nodoc:
22
- def [](name)
23
- old_hash_get name.to_s
24
- end
25
- end #Attributes
26
-
27
- end #XML
28
- end #LibXML
@@ -1,48 +0,0 @@
1
- module Blather # :nodoc:
2
- class Stream # :nodoc:
3
-
4
- class Resource < StreamHandler # :nodoc:
5
- def initialize(stream, jid)
6
- super stream
7
- @jid = jid
8
- end
9
-
10
- private
11
- ##
12
- # Respond to the bind request
13
- # If @jid has a resource set already request it from the server
14
- def bind
15
- response = Stanza::Iq.new :set
16
- @id = response.id
17
-
18
- binder = XMPPNode.new('bind')
19
- binder.namespace = 'urn:ietf:params:xml:ns:xmpp-bind'
20
-
21
- binder << XMPPNode.new('resource', @jid.resource) if @jid.resource
22
-
23
- response << binder
24
- @stream.send response
25
- end
26
-
27
- ##
28
- # Process the result from the server
29
- # Sets the sends the JID (now bound to a resource)
30
- # back to the stream
31
- def result
32
- LOG.debug "RESOURE NODE #{@node}"
33
- # ensure this is a response to our original request
34
- if @id == @node['id']
35
- @jid = JID.new @node.find_first('//bind_ns:bind/bind_ns:jid', :bind_ns => 'urn:ietf:params:xml:ns:xmpp-bind').content
36
- success @jid
37
- end
38
- end
39
-
40
- ##
41
- # Server returned an error
42
- def error
43
- failure StanzaError.import(@node)
44
- end
45
- end #Resource
46
-
47
- end #Stream
48
- end #Blather