sprsquish-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/client/client.rb +19 -13
  10. data/lib/blather/client/dsl/pubsub.rb +133 -0
  11. data/lib/blather/client/dsl.rb +16 -0
  12. data/lib/blather/client.rb +1 -1
  13. data/lib/blather/core_ext/active_support/inheritable_attributes.rb +117 -0
  14. data/lib/blather/core_ext/active_support.rb +1 -117
  15. data/lib/blather/core_ext/nokogiri.rb +35 -0
  16. data/lib/blather/errors/sasl_error.rb +3 -1
  17. data/lib/blather/errors/stanza_error.rb +10 -17
  18. data/lib/blather/errors/stream_error.rb +11 -14
  19. data/lib/blather/errors.rb +3 -20
  20. data/lib/blather/jid.rb +1 -0
  21. data/lib/blather/roster.rb +9 -0
  22. data/lib/blather/roster_item.rb +6 -1
  23. data/lib/blather/stanza/disco/disco_info.rb +45 -33
  24. data/lib/blather/stanza/disco/disco_items.rb +32 -21
  25. data/lib/blather/stanza/disco.rb +7 -1
  26. data/lib/blather/stanza/iq/query.rb +16 -8
  27. data/lib/blather/stanza/iq/roster.rb +33 -22
  28. data/lib/blather/stanza/iq.rb +13 -8
  29. data/lib/blather/stanza/message.rb +20 -31
  30. data/lib/blather/stanza/presence/status.rb +13 -21
  31. data/lib/blather/stanza/presence/subscription.rb +11 -16
  32. data/lib/blather/stanza/presence.rb +3 -5
  33. data/lib/blather/stanza/pubsub/affiliations.rb +50 -0
  34. data/lib/blather/stanza/pubsub/create.rb +43 -0
  35. data/lib/blather/stanza/pubsub/errors.rb +9 -0
  36. data/lib/blather/stanza/pubsub/event.rb +77 -0
  37. data/lib/blather/stanza/pubsub/items.rb +63 -0
  38. data/lib/blather/stanza/pubsub/publish.rb +58 -0
  39. data/lib/blather/stanza/pubsub/retract.rb +53 -0
  40. data/lib/blather/stanza/pubsub/subscribe.rb +42 -0
  41. data/lib/blather/stanza/pubsub/subscription.rb +66 -0
  42. data/lib/blather/stanza/pubsub/subscriptions.rb +55 -0
  43. data/lib/blather/stanza/pubsub/unsubscribe.rb +42 -0
  44. data/lib/blather/stanza/pubsub.rb +63 -0
  45. data/lib/blather/stanza/pubsub_owner/delete.rb +34 -0
  46. data/lib/blather/stanza/pubsub_owner/purge.rb +34 -0
  47. data/lib/blather/stanza/pubsub_owner.rb +41 -0
  48. data/lib/blather/stanza.rb +35 -18
  49. data/lib/blather/stream/client.rb +1 -2
  50. data/lib/blather/stream/component.rb +9 -5
  51. data/lib/blather/stream/features/resource.rb +63 -0
  52. data/lib/blather/stream/{sasl.rb → features/sasl.rb} +53 -52
  53. data/lib/blather/stream/features/session.rb +44 -0
  54. data/lib/blather/stream/features/tls.rb +28 -0
  55. data/lib/blather/stream/features.rb +53 -0
  56. data/lib/blather/stream/parser.rb +70 -46
  57. data/lib/blather/stream.rb +76 -168
  58. data/lib/blather/xmpp_node.rb +113 -52
  59. data/lib/blather.rb +35 -12
  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 +53 -17
  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/ext/push_parser.c DELETED
@@ -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
@@ -1,36 +0,0 @@
1
- module Blather # :nodoc:
2
- class Stream # :nodoc:
3
-
4
- class Session < StreamHandler # :nodoc:
5
- def initialize(stream, to)
6
- super stream
7
- @to = to
8
- end
9
-
10
- private
11
- ##
12
- # Send a start session command
13
- def session
14
- response = Stanza::Iq.new :set
15
- response.to = @to
16
- sess = XMPPNode.new 'session'
17
- sess['xmlns'] = 'urn:ietf:params:xml:ns:xmpp-session'
18
- response << sess
19
- @stream.send response
20
- end
21
-
22
- ##
23
- # The server should respond with a <result> node if all is well
24
- def result
25
- success
26
- end
27
-
28
- ##
29
- # Server returned an error.
30
- def error
31
- failure StanzaError.import(@node)
32
- end
33
- end
34
-
35
- end
36
- end
@@ -1,39 +0,0 @@
1
- module Blather # :nodoc:
2
- class Stream # :nodoc:
3
-
4
- class StreamHandler # :nodoc:
5
- def on_success(&block); @success = block; end
6
- def on_failure(&block); @failure = block; end
7
-
8
- def initialize(stream)
9
- @stream = stream
10
- end
11
-
12
- def handle(node)
13
- @node = node
14
- method = @node.element_name == 'iq' ? @node['type'] : @node.element_name
15
- if self.respond_to?(method, true)
16
- self.__send__ method
17
- else
18
- @failure.call UnknownResponse.new(@node)
19
- end
20
- end
21
-
22
- protected
23
- ##
24
- # Handle error response from the server
25
- def error
26
- failure
27
- end
28
-
29
- def success(message_back = nil)
30
- @success.call message_back
31
- end
32
-
33
- def failure(err = nil)
34
- @failure.call err
35
- end
36
- end #StreamHandler
37
-
38
- end #Stream
39
- end #Blather
@@ -1,33 +0,0 @@
1
- module Blather # :nodoc:
2
- class Stream # :nodoc:
3
-
4
- # TLS negotiation invovles 3 node types:
5
- # * starttls -- Server asking for TLS to be started
6
- # * proceed -- Server saying it's ready for a TLS connection to be started
7
- # * failure -- Failed TLS negotiation. Failure results in a closed connection.
8
- # so there's no message to pass back to the tream
9
- class TLS < StreamHandler # :nodoc:
10
- private
11
- ##
12
- # After receiving <starttls> from the server send one
13
- # back to let it know we're ready to start TLS
14
- def starttls
15
- @stream.send "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>"
16
- end
17
-
18
- ##
19
- # Server's ready for TLS, so start it up
20
- def proceed
21
- @stream.start_tls
22
- success
23
- end
24
-
25
- ##
26
- # Negotiations failed
27
- def failure
28
- super StreamError::TLSFailure.new
29
- end
30
- end #TLS
31
-
32
- end #Stream
33
- end #Blather
@@ -1,58 +0,0 @@
1
- require File.join(File.dirname(__FILE__), *%w[.. .. spec_helper])
2
-
3
- describe 'LibXML::XML::Node' do
4
- it 'aliases #name to #element_name' do
5
- node = LibXML::XML::Node.new 'foo'
6
- node.must_respond_to :element_name
7
- node.element_name.must_equal node.name
8
- end
9
-
10
- it 'aliases #name= to #element_name=' do
11
- node = LibXML::XML::Node.new 'foo'
12
- node.must_respond_to :element_name=
13
- node.element_name.must_equal node.name
14
- node.element_name = 'bar'
15
- node.element_name.must_equal 'bar'
16
- end
17
- end
18
-
19
- describe 'LibXML::XML::Attributes' do
20
- it 'provides a helper to remove a specified attribute' do
21
- attrs = LibXML::XML::Node.new('foo').attributes
22
- attrs['foo'] = 'bar'
23
- attrs['foo'].must_equal 'bar'
24
- attrs.remove 'foo'
25
- attrs['foo'].must_be_nil
26
-
27
- attrs['foo'] = 'bar'
28
- attrs['foo'].must_equal 'bar'
29
- attrs.remove :foo
30
- attrs['foo'].must_be_nil
31
- end
32
-
33
- it 'allows symbols as hash keys' do
34
- attrs = LibXML::XML::Node.new('foo').attributes
35
- attrs['foo'] = 'bar'
36
-
37
- attrs['foo'].must_equal 'bar'
38
- attrs[:foo].must_equal 'bar'
39
- end
40
-
41
- it 'removes an attribute when set to nil' do
42
- attrs = LibXML::XML::Node.new('foo').attributes
43
- attrs['foo'] = 'bar'
44
-
45
- attrs['foo'].must_equal 'bar'
46
- attrs['foo'] = nil
47
- attrs['foo'].must_be_nil
48
- end
49
-
50
- it 'allows attribute values to change' do
51
- attrs = LibXML::XML::Node.new('foo').attributes
52
- attrs['foo'] = 'bar'
53
-
54
- attrs['foo'].must_equal 'bar'
55
- attrs['foo'] = 'baz'
56
- attrs['foo'].must_equal 'baz'
57
- end
58
- end