sprsquish-blather 0.1 → 0.2.3

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 (73) hide show
  1. data/LICENSE +2 -0
  2. data/README.rdoc +100 -0
  3. data/Rakefile +110 -0
  4. data/examples/drb_client.rb +5 -0
  5. data/examples/echo.rb +18 -0
  6. data/ext/extconf.rb +65 -0
  7. data/ext/push_parser.c +231 -0
  8. data/lib/blather/client.rb +219 -44
  9. data/lib/blather/{core/sugar.rb → core_ext/active_support.rb} +25 -13
  10. data/lib/blather/core_ext/libxml.rb +28 -0
  11. data/lib/blather/errors/sasl_error.rb +87 -0
  12. data/lib/blather/errors/stanza_error.rb +262 -0
  13. data/lib/blather/errors/stream_error.rb +253 -0
  14. data/lib/blather/errors.rb +48 -0
  15. data/lib/blather/{core/jid.rb → jid.rb} +15 -26
  16. data/lib/blather/{core/roster.rb → roster.rb} +22 -0
  17. data/lib/blather/{core/roster_item.rb → roster_item.rb} +39 -8
  18. data/lib/blather/stanza/iq/disco.rb +11 -0
  19. data/lib/blather/stanza/iq/discos/disco_info.rb +86 -0
  20. data/lib/blather/stanza/iq/discos/disco_items.rb +61 -0
  21. data/lib/blather/stanza/iq/query.rb +51 -0
  22. data/lib/blather/stanza/iq/roster.rb +90 -0
  23. data/lib/blather/stanza/iq.rb +38 -0
  24. data/lib/blather/stanza/message.rb +58 -0
  25. data/lib/blather/stanza/presence/status.rb +78 -0
  26. data/lib/blather/stanza/presence/subscription.rb +72 -0
  27. data/lib/blather/stanza/presence.rb +45 -0
  28. data/lib/blather/stanza.rb +101 -0
  29. data/lib/blather/stream/client.rb +26 -0
  30. data/lib/blather/stream/component.rb +34 -0
  31. data/lib/blather/stream/parser.rb +70 -0
  32. data/lib/blather/stream/resource.rb +48 -0
  33. data/lib/blather/stream/sasl.rb +173 -0
  34. data/lib/blather/stream/session.rb +36 -0
  35. data/lib/blather/stream/stream_handler.rb +39 -0
  36. data/lib/blather/stream/tls.rb +33 -0
  37. data/lib/blather/stream.rb +249 -0
  38. data/lib/blather/xmpp_node.rb +199 -0
  39. data/lib/blather.rb +40 -41
  40. data/spec/blather/core_ext/libxml_spec.rb +58 -0
  41. data/spec/blather/errors/sasl_error_spec.rb +56 -0
  42. data/spec/blather/errors/stanza_error_spec.rb +148 -0
  43. data/spec/blather/errors/stream_error_spec.rb +114 -0
  44. data/spec/blather/errors_spec.rb +40 -0
  45. data/spec/blather/{core/jid_spec.rb → jid_spec.rb} +9 -1
  46. data/spec/blather/{core/roster_item_spec.rb → roster_item_spec.rb} +6 -1
  47. data/spec/blather/{core/roster_spec.rb → roster_spec.rb} +16 -6
  48. data/spec/blather/stanza/iq/discos/disco_info_spec.rb +207 -0
  49. data/spec/blather/stanza/iq/discos/disco_items_spec.rb +136 -0
  50. data/spec/blather/stanza/iq/query_spec.rb +34 -0
  51. data/spec/blather/stanza/iq/roster_spec.rb +123 -0
  52. data/spec/blather/stanza/iq_spec.rb +40 -0
  53. data/spec/blather/stanza/message_spec.rb +52 -0
  54. data/spec/blather/stanza/presence/status_spec.rb +102 -0
  55. data/spec/blather/stanza/presence/subscription_spec.rb +85 -0
  56. data/spec/blather/stanza/presence_spec.rb +53 -0
  57. data/spec/blather/{core/stanza_spec.rb → stanza_spec.rb} +14 -2
  58. data/spec/blather/stream/client_spec.rb +787 -0
  59. data/spec/blather/stream/component_spec.rb +86 -0
  60. data/spec/blather/{core/xmpp_node_spec.rb → xmpp_node_spec.rb} +76 -23
  61. data/spec/build_safe.rb +20 -0
  62. data/spec/spec_helper.rb +7 -17
  63. metadata +79 -59
  64. data/CHANGELOG +0 -1
  65. data/blather.gemspec +0 -73
  66. data/lib/blather/callback.rb +0 -24
  67. data/lib/blather/core/errors.rb +0 -24
  68. data/lib/blather/core/stanza.rb +0 -90
  69. data/lib/blather/core/stream.rb +0 -179
  70. data/lib/blather/core/xmpp_node.rb +0 -95
  71. data/lib/blather/extensions/last_activity.rb +0 -57
  72. data/lib/blather/extensions/version.rb +0 -85
  73. data/spec/blather/core/stream_spec.rb +0 -263
@@ -0,0 +1,262 @@
1
+ module Blather
2
+
3
+ ##
4
+ # Stanza errors
5
+ # RFC3920 Section 9.3 (http://xmpp.org/rfcs/rfc3920.html#stanzas-error)
6
+ class StanzaError < BlatherError
7
+ VALID_TYPES = [:cancel, :continue, :modify, :auth, :wait]
8
+
9
+ class_inheritable_accessor :err_name
10
+ @@registrations = {}
11
+
12
+ register :stanza_error
13
+
14
+ attr_reader :original, :type, :text, :extras
15
+
16
+ ##
17
+ # Register the handler and type to simplify importing
18
+ def self.register(handler, err_name)
19
+ super handler
20
+ self.err_name = err_name
21
+ @@registrations[err_name] = self
22
+ end
23
+
24
+ ##
25
+ # Retreive an error class from a given name
26
+ def self.class_from_registration(err_name)
27
+ @@registrations[err_name.to_s] || self
28
+ end
29
+
30
+ ##
31
+ # Factory method for instantiating the proper class
32
+ # for the error
33
+ def self.import(node)
34
+ original = node.copy
35
+ original.remove_child 'error'
36
+
37
+ error_node = node.find_first 'child::error'
38
+
39
+ name = error_node.find_first('child::*[name()!="text"]', 'urn:ietf:params:xml:ns:xmpp-stanzas').element_name
40
+ type = error_node['type']
41
+ text = node.find_first 'descendant::text', 'urn:ietf:params:xml:ns:xmpp-stanzas'
42
+ text = text.content if text
43
+
44
+ extras = error_node.find("descendant::*[name()!='text' and name()!='#{name}']").map { |n| n }
45
+
46
+ class_from_registration(name).new original, type, text, extras
47
+ end
48
+
49
+ ##
50
+ # <tt>original</tt> An original node must be provided for stanza errors. You can't declare
51
+ # a stanza error on without a stanza.
52
+ # <tt>type</tt> is the error type specified in RFC3920 (http://xmpp.org/rfcs/rfc3920.html#rfc.section.9.3.2)
53
+ # <tt>text</tt> is an option error description
54
+ # <tt>extras</tt> an array of application specific nodes to add to the error. These should be properly namespaced.
55
+ def initialize(original, type, text = nil, extras = [])
56
+ @original = original
57
+ self.type = type
58
+ @text = text
59
+ @extras = extras
60
+ end
61
+
62
+ ##
63
+ # XMPP defined error name
64
+ def err_name
65
+ self.class.err_name
66
+ end
67
+
68
+ ##
69
+ # Set the error type (see RFC3920 Section 9.3.2 (http://xmpp.org/rfcs/rfc3920.html#rfc.section.9.3.2))
70
+ def type=(type)
71
+ type = type.to_sym
72
+ raise ArgumentError, "Invalid Type (#{type}), use: #{VALID_TYPES*' '}" if !VALID_TYPES.include?(type)
73
+ @type = type
74
+ end
75
+
76
+ ##
77
+ # Creates an XML node from the error
78
+ def to_node
79
+ node = self.original.reply
80
+
81
+ error_node = XMPPNode.new 'error'
82
+ err = XMPPNode.new(self.err_name)
83
+ err.namespace = 'urn:ietf:params:xml:ns:xmpp-stanzas'
84
+ error_node << err
85
+
86
+ if self.text
87
+ text = XMPPNode.new('text')
88
+ text.namespace = 'urn:ietf:params:xml:ns:xmpp-stanzas'
89
+ text << self.text
90
+ error_node << text
91
+ end
92
+
93
+ self.extras.each do |extra|
94
+ extra_copy = extra.copy
95
+ extra_copy.namespace = extra.namespace
96
+ error_node << extra_copy
97
+ end
98
+
99
+ node << error_node
100
+ node.type = 'error'
101
+ node
102
+ end
103
+
104
+ ##
105
+ # Turns the object into XML fit to be sent over the stream
106
+ def to_xml
107
+ to_node.to_s
108
+ end
109
+
110
+ def inspect # :nodoc:
111
+ "Stanza Error (#{self.err_name}): #{self.text}"
112
+ end
113
+ alias_method :to_s, :inspect # :nodoc:
114
+
115
+ ##
116
+ # The sender has sent XML that is malformed or that cannot be processed (e.g., an IQ stanza that includes
117
+ # an unrecognized value of the 'type' attribute); the associated error type SHOULD be "modify"
118
+ class BadRequest < StanzaError
119
+ register :stanza_bad_request_error, 'bad-request'
120
+ end
121
+
122
+ ##
123
+ # Access cannot be granted because an existing resource or session exists with the same name or address;
124
+ # the associated error type SHOULD be "cancel"
125
+ class Conflict < StanzaError
126
+ register :stanza_conflict_error, 'conflict'
127
+ end
128
+
129
+ ##
130
+ # the feature requested is not implemented by the recipient or server and therefore cannot be processed;
131
+ # the associated error type SHOULD be "cancel".
132
+ class FeatureNotImplemented < StanzaError
133
+ register :stanza_feature_not_implemented_error, 'feature-not-implemented'
134
+ end
135
+
136
+ ##
137
+ # the requesting entity does not possess the required permissions to perform the action;
138
+ # the associated error type SHOULD be "auth".
139
+ class Forbidden < StanzaError
140
+ register :stanza_forbidden_error, 'forbidden'
141
+ end
142
+
143
+ ##
144
+ # the recipient or server can no longer be contacted at this address (the error stanza MAY contain a new address
145
+ # in the XML character data of the <gone/> element); the associated error type SHOULD be "modify".
146
+ class Gone < StanzaError
147
+ register :stanza_gone_error, 'gone'
148
+ end
149
+
150
+ ##
151
+ # the server could not process the stanza because of a misconfiguration or an otherwise-undefined internal server error;
152
+ # the associated error type SHOULD be "wait".
153
+ class InternalServerError < StanzaError
154
+ register :stanza_internal_server_error, 'internal-server-error'
155
+ end
156
+
157
+ ##
158
+ # the addressed JID or item requested cannot be found; the associated error type SHOULD be "cancel".
159
+ class ItemNotFound < StanzaError
160
+ register :stanza_item_not_found_error, 'item-not-found'
161
+ end
162
+
163
+ ##
164
+ # the addressed JID or item requested cannot be found; the associated error type SHOULD be "cancel".
165
+ class JidMalformed < StanzaError
166
+ register :stanza_jid_malformed_error, 'jid-malformed'
167
+ end
168
+
169
+ ##
170
+ # the recipient or server understands the request but is refusing to process it because it does not meet criteria defined
171
+ # by the recipient or server (e.g., a local policy regarding acceptable words in messages); the associated error type SHOULD be "modify".
172
+ class NotAcceptable < StanzaError
173
+ register :stanza_not_acceptable_error, 'not-acceptable'
174
+ end
175
+
176
+ ##
177
+ # The recipient or server does not allow any entity to perform the action; the associated error type SHOULD be "cancel".
178
+ class NotAllowed < StanzaError
179
+ register :stanza_not_allowed_error, 'not-allowed'
180
+ end
181
+
182
+ ##
183
+ # the sender must provide proper credentials before being allowed to perform the action, or has provided improper credentials;
184
+ # the associated error type SHOULD be "auth".
185
+ class NotAuthorized < StanzaError
186
+ register :stanza_not_authorized_error, 'not-authorized'
187
+ end
188
+
189
+ ##
190
+ # the requesting entity is not authorized to access the requested service because payment is required; the associated error type SHOULD be "auth".
191
+ class PaymentRequired < StanzaError
192
+ register :stanza_payment_required_error, 'payment-required'
193
+ end
194
+
195
+ ##
196
+ # the intended recipient is temporarily unavailable; the associated error type SHOULD be "wait" (note: an application MUST NOT
197
+ # return this error if doing so would provide information about the intended recipient's network availability to an entity that
198
+ # is not authorized to know such information).
199
+ class RecipientUnavailable < StanzaError
200
+ register :stanza_recipient_unavailable_error, 'recipient-unavailable'
201
+ end
202
+
203
+ ##
204
+ # the recipient or server is redirecting requests for this information to another entity, usually temporarily (the error stanza SHOULD contain
205
+ # the alternate address, which MUST be a valid JID, in the XML character data of the <redirect/> element); the associated error type SHOULD be "modify".
206
+ class Redirect < StanzaError
207
+ register :stanza_redirect_error, 'redirect'
208
+ end
209
+
210
+ ##
211
+ # the requesting entity is not authorized to access the requested service because registration is required; the associated error type SHOULD be "auth".
212
+ class RegistrationRequired < StanzaError
213
+ register :stanza_registration_required_error, 'registration-required'
214
+ end
215
+
216
+ ##
217
+ # a remote server or service specified as part or all of the JID of the intended recipient does not exist; the associated error type SHOULD be "cancel".
218
+ class RemoteServerNotFound < StanzaError
219
+ register :stanza_remote_server_not_found_error, 'remote-server-not-found'
220
+ end
221
+
222
+ ##
223
+ # a remote server or service specified as part or all of the JID of the intended recipient (or required to fulfill a request) could not be
224
+ # contacted within a reasonable amount of time; the associated error type SHOULD be "wait".
225
+ class RemoteServerTimeout < StanzaError
226
+ register :stanza_remote_server_timeout_error, 'remote-server-timeout'
227
+ end
228
+
229
+ ##
230
+ # the server or recipient lacks the system resources necessary to service the request; the associated error type SHOULD be "wait".
231
+ class ResourceConstraint < StanzaError
232
+ register :stanza_resource_constraint_error, 'resource-constraint'
233
+ end
234
+
235
+ ##
236
+ # the server or recipient does not currently provide the requested service; the associated error type SHOULD be "cancel".
237
+ class ServiceUnavailable < StanzaError
238
+ register :stanza_service_unavailable_error, 'service-unavailable'
239
+ end
240
+
241
+ ##
242
+ # the requesting entity is not authorized to access the requested service because a subscription is required; the associated error type SHOULD be "auth".
243
+ class SubscriptionRequired < StanzaError
244
+ register :stanza_subscription_required_error, 'subscription-required'
245
+ end
246
+
247
+ ##
248
+ # the error condition is not one of those defined by the other conditions in this list; any error type may be associated with this condition,
249
+ # and it SHOULD be used only in conjunction with an application-specific condition.
250
+ class UndefinedCondition < StanzaError
251
+ register :stanza_undefined_condition_error, 'undefined-condition'
252
+ end
253
+
254
+ ##
255
+ # the recipient or server understood the request but was not expecting it at this time (e.g., the request was out of order);
256
+ # the associated error type SHOULD be "wait".
257
+ class UnexpectedRequest < StanzaError
258
+ register :stanza_unexpected_request_error, 'unexpected-request'
259
+ end
260
+ end #StanzaError
261
+
262
+ end #Blather
@@ -0,0 +1,253 @@
1
+ module Blather
2
+
3
+ ##
4
+ # Stream Errors
5
+ # RFC3920 Section 9.3 (http://xmpp.org/rfcs/rfc3920.html#streams-error-rules)
6
+ class StreamError < BlatherError
7
+ class_inheritable_accessor :err_name
8
+ @@registrations = {}
9
+
10
+ register :stream_error
11
+
12
+ attr_reader :text, :extras
13
+
14
+ ##
15
+ # Register the handler and type to simplify importing
16
+ def self.register(handler, err_name)
17
+ super handler
18
+ self.err_name = err_name
19
+ @@registrations[err_name] = self
20
+ end
21
+
22
+ ##
23
+ # Retreive an error class from a given name
24
+ def self.class_from_registration(err_name)
25
+ @@registrations[err_name.to_s] || self
26
+ end
27
+
28
+ ##
29
+ # Factory method for instantiating the proper class
30
+ # for the error
31
+ def self.import(node)
32
+ name = node.find_first('descendant::*[name()!="text"]', 'urn:ietf:params:xml:ns:xmpp-streams').element_name
33
+ text = node.find_first 'descendant::text', 'urn:ietf:params:xml:ns:xmpp-streams'
34
+ text = text.content if text
35
+
36
+ extras = node.find("descendant::*[name()!='text' and name()!='#{name}']").map { |n| n }
37
+
38
+ class_from_registration(name).new text, extras
39
+ end
40
+
41
+ ##
42
+ # <tt>text</tt> is the (optional) error message.
43
+ # <tt>extras</tt> should be an array of nodes to attach to the error
44
+ # each extra should be in an application specific namespace
45
+ # see RFC3920 Section 4.7.2 (http://xmpp.org/rfcs/rfc3920.html#rfc.section.4.7.2)
46
+ def initialize(text = nil, extras = [])
47
+ @text = text
48
+ @extras = extras
49
+ end
50
+
51
+ ##
52
+ # XMPP defined error name
53
+ def err_name
54
+ self.class.err_name
55
+ end
56
+
57
+ ##
58
+ # Creates an XML node from the error
59
+ def to_node
60
+ node = XMPPNode.new('stream:error')
61
+
62
+ err = XMPPNode.new(self.err_name)
63
+ err.namespace = 'urn:ietf:params:xml:ns:xmpp-streams'
64
+ node << err
65
+
66
+ if self.text
67
+ text = XMPPNode.new('text')
68
+ text.namespace = 'urn:ietf:params:xml:ns:xmpp-streams'
69
+ text << self.text
70
+ node << text
71
+ end
72
+
73
+ self.extras.each do |extra|
74
+ extra_copy = extra.copy
75
+ extra_copy.namespace = extra.namespace
76
+ node << extra_copy
77
+ end
78
+ node
79
+ end
80
+
81
+ ##
82
+ # Turns the object into XML fit to be sent over the stream
83
+ def to_xml
84
+ to_node.to_s
85
+ end
86
+
87
+ def inspect # :nodoc:
88
+ "Stream Error (#{self.err_name}): #{self.text}"
89
+ end
90
+ alias_method :to_s, :inspect # :nodoc:
91
+
92
+ ##
93
+ # The entity has sent XML that cannot be processed; this error MAY be used instead of the more specific XML-related errors,
94
+ # such as <bad-namespace-prefix/>, <invalid-xml/>, <restricted-xml/>, <unsupported-encoding/>, and <xml-not-well-formed/>,
95
+ # although the more specific errors are preferred.
96
+ class BadFormat < StreamError
97
+ register :stream_bad_format_error, 'bad-format'
98
+ end
99
+
100
+ ##
101
+ # The entity has sent a namespace prefix that is unsupported, or has sent no namespace prefix on an element that requires
102
+ # such a prefix (see XML Namespace Names and Prefixes).
103
+ class BadNamespacePrefix < StreamError
104
+ register :stream_bad_namespace_prefix_error, 'bad-namespace-prefix'
105
+ end
106
+
107
+ ##
108
+ # The server is closing the active stream for this entity because a new stream has been initiated that conflicts with the
109
+ # existing stream.
110
+ class Conflict < StreamError
111
+ register :stream_conflict_error, 'conflict'
112
+ end
113
+
114
+ ##
115
+ # The entity has not generated any traffic over the stream for some period of time (configurable according to a local service policy).
116
+ class ConnectionTimeout < StreamError
117
+ register :stream_connection_timeout_error, 'connection-timeout'
118
+ end
119
+
120
+ ##
121
+ # The value of the 'to' attribute provided by the initiating entity in the stream header corresponds to a hostname that is no
122
+ # longer hosted by the server.
123
+ class HostGone < StreamError
124
+ register :stream_host_gone_error, 'host-gone'
125
+ end
126
+
127
+ ##
128
+ # The value of the 'to' attribute provided by the initiating entity in the stream header does not correspond to a hostname that
129
+ # is hosted by the server.
130
+ class HostUnknown < StreamError
131
+ register :stream_host_unknown_error, 'host-unknown'
132
+ end
133
+
134
+ ##
135
+ # a stanza sent between two servers lacks a 'to' or 'from' attribute (or the attribute has no value).
136
+ class ImproperAddressing < StreamError
137
+ register :stream_improper_addressing_error, 'improper-addressing'
138
+ end
139
+
140
+ ##
141
+ # The server has experienced a misconfiguration or an otherwise-undefined internal error that prevents it from servicing the stream.
142
+ class InternalServerError < StreamError
143
+ register :stream_internal_server_error, 'internal-server-error'
144
+ end
145
+
146
+ ##
147
+ # The JID or hostname provided in a 'from' address does not match an authorized JID or validated domain negotiated between
148
+ # servers via SASL or dialback, or between a client and a server via authentication and resource binding.
149
+ class InvalidFrom < StreamError
150
+ register :stream_invalid_from_error, 'invalid-from'
151
+ end
152
+
153
+ ##
154
+ # The stream ID or dialback ID is invalid or does not match an ID previously provided.
155
+ class InvalidId < StreamError
156
+ register :stream_invalid_id_error, 'invalid-id'
157
+ end
158
+
159
+ ##
160
+ # The streams namespace name is something other than "http://etherx.jabber.org/streams" or the dialback namespace name is something
161
+ # other than "jabber:server:dialback" (see XML Namespace Names and Prefixes).
162
+ class InvalidNamespace < StreamError
163
+ register :stream_invalid_namespace_error, 'invalid-namespace'
164
+ end
165
+
166
+ ##
167
+ # The entity has sent invalid XML over the stream to a server that performs validation (see Validation).
168
+ class InvalidXml < StreamError
169
+ register :stream_invalid_xml_error, 'invalid-xml'
170
+ end
171
+
172
+ ##
173
+ # The entity has attempted to send data before the stream has been authenticated, or otherwise is not authorized to perform an action
174
+ # related to stream negotiation; the receiving entity MUST NOT process the offending stanza before sending the stream error.
175
+ class NotAuthorized < StreamError
176
+ register :stream_not_authorized_error, 'not-authorized'
177
+ end
178
+
179
+ ##
180
+ # The entity has violated some local service policy; the server MAY choose to specify the policy in the <text/> element or an
181
+ # application-specific condition element.
182
+ class PolicyViolation < StreamError
183
+ register :stream_policy_violation_error, 'policy-violation'
184
+ end
185
+
186
+ ##
187
+ # The server is unable to properly connect to a remote entity that is required for authentication or authorization.
188
+ class RemoteConnectionFailed < StreamError
189
+ register :stream_remote_connection_failed_error, 'remote-connection-failed'
190
+ end
191
+
192
+ ##
193
+ # The server lacks the system resources necessary to service the stream.
194
+ class ResourceConstraint < StreamError
195
+ register :stream_resource_constraint_error, 'resource-constraint'
196
+ end
197
+
198
+ ##
199
+ # The entity has attempted to send restricted XML features such as a comment, processing instruction, DTD, entity reference,
200
+ # or unescaped character (see Restrictions).
201
+ class RestrictedXml < StreamError
202
+ register :stream_restricted_xml_error, 'restricted-xml'
203
+ end
204
+
205
+ ##
206
+ # The server will not provide service to the initiating entity but is redirecting traffic to another host; the server SHOULD
207
+ # specify the alternate hostname or IP address (which MUST be a valid domain identifier) as the XML character data of the
208
+ # <see-other-host/> element.
209
+ class SeeOtherHost < StreamError
210
+ register :stream_see_other_host_error, 'see-other-host'
211
+ end
212
+
213
+ ##
214
+ # The server is being shut down and all active streams are being closed.
215
+ class SystemShutdown < StreamError
216
+ register :stream_system_shutdown_error, 'system-shutdown'
217
+ end
218
+
219
+ ##
220
+ # The error condition is not one of those defined by the other conditions in this list; this error condition SHOULD be used
221
+ # only in conjunction with an application-specific condition.
222
+ class UndefinedCondition < StreamError
223
+ register :stream_undefined_condition_error, 'undefined-condition'
224
+ end
225
+
226
+ ##
227
+ # The initiating entity has encoded the stream in an encoding that is not supported by the server (see Character Encoding).
228
+ class UnsupportedEncoding < StreamError
229
+ register :stream_unsupported_encoding_error, 'unsupported-encoding'
230
+ end
231
+
232
+ ##
233
+ # The initiating entity has sent a first-level child of the stream that is not supported by the server.
234
+ class UnsupportedStanzaType < StreamError
235
+ register :stream_unsupported_stanza_type_error, 'unsupported-stanza-type'
236
+ end
237
+
238
+ ##
239
+ # The value of the 'version' attribute provided by the initiating entity in the stream header specifies a version of XMPP
240
+ # That is not supported by the server; the server MAY specify the version(s) it supports in the <text/> element.
241
+ class UnsupportedVersion < StreamError
242
+ register :stream_unsupported_version_error, 'unsupported-version'
243
+ end
244
+
245
+ ##
246
+ # The initiating entity has sent XML that is not well-formed as defined by [XML].
247
+ class XmlNotWellFormed < StreamError
248
+ register :stream_xml_not_well_formed_error, 'xml-not-well-formed'
249
+ end
250
+
251
+ end #StreamError
252
+
253
+ end #Blather
@@ -0,0 +1,48 @@
1
+ module Blather
2
+ # Main error class
3
+ class BlatherError < StandardError
4
+ class_inheritable_array :handler_heirarchy
5
+
6
+ self.handler_heirarchy ||= []
7
+ self.handler_heirarchy << :error
8
+
9
+ def self.register(handler)
10
+ self.handler_heirarchy.unshift handler
11
+ end
12
+ end
13
+
14
+ ##
15
+ # Used in cases where a stanza only allows specific values for its attributes
16
+ # and an invalid value is attempted.
17
+ class ArgumentError < BlatherError
18
+ register :argument_error
19
+ end
20
+
21
+ ##
22
+ # The stream handler received a response it didn't know how to handle
23
+ class UnknownResponse < BlatherError
24
+ register :unknown_response_error
25
+ attr_reader :node
26
+
27
+ def initialize(node)
28
+ @node = node
29
+ end
30
+ end
31
+
32
+ ##
33
+ # TLS negotiations broke down
34
+ class TLSFailure < BlatherError
35
+ register :tls_failure
36
+ end
37
+
38
+ ##
39
+ # Something bad happened while parsing the incoming stream
40
+ class ParseError < BlatherError
41
+ register :parse_error
42
+ attr_reader :message
43
+
44
+ def initialize(message)
45
+ @message = message
46
+ end
47
+ end
48
+ end
@@ -1,34 +1,27 @@
1
- # =XMPP4R - XMPP Library for Ruby
2
- # License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
3
- # Website::http://home.gna.org/xmpp4r/
4
-
5
1
  module Blather
2
+
6
3
  ##
7
- # The JID class represents a Jabber Identifier as described by
8
- # RFC3920 section 3.1.
9
- #
10
- # Note that you can use JIDs also for Sorting, Hash keys, ...
4
+ # This is a simple modification of the JID class from XMPP4R
11
5
  class JID
12
6
  include Comparable
13
7
 
14
- PATTERN = /^(?:([^@]*)@)??([^@\/]*)(?:\/(.*?))?$/
15
-
16
- begin
17
- require 'idn'
18
- USE_STRINGPREP = true
19
- rescue LoadError
20
- USE_STRINGPREP = false
21
- end
8
+ PATTERN = /^(?:([^@]*)@)??([^@\/]*)(?:\/(.*?))?$/.freeze
22
9
 
10
+ ##
23
11
  # Get the JID's node
24
12
  attr_reader :node
25
13
 
14
+ ##
26
15
  # Get the JID's domain
27
16
  attr_reader :domain
28
17
 
18
+ ##
29
19
  # Get the JID's resource
30
20
  attr_reader :resource
31
21
 
22
+ ##
23
+ # If a JID is passed in just return it.
24
+ # No need to copy out all the values
32
25
  def self.new(node, domain = nil, resource = nil)
33
26
  node.is_a?(JID) ? node : super
34
27
  end
@@ -45,14 +38,8 @@ module Blather
45
38
  @node, @domain, @resource = @node.to_s.scan(PATTERN).first
46
39
  end
47
40
 
48
- if USE_STRINGPREP
49
- @node = IDN::Stringprep.nodeprep(@node) if @node
50
- @domain = IDN::Stringprep.nameprep(@domain) if @domain
51
- @resource = IDN::Stringprep.resourceprep(@resource) if @resource
52
- else
53
- @node.downcase! if @node
54
- @domain.downcase! if @domain
55
- end
41
+ @node.downcase! if @node
42
+ @domain.downcase! if @domain
56
43
 
57
44
  raise ArgumentError, 'Node too long' if (@node || '').length > 1023
58
45
  raise ArgumentError, 'Domain too long' if (@domain || '').length > 1023
@@ -70,7 +57,7 @@ module Blather
70
57
  s = @domain
71
58
  s = "#{@node}@#{s}" if @node
72
59
  s = "#{s}/#{@resource}" if @resource
73
- return s
60
+ s
74
61
  end
75
62
 
76
63
  ##
@@ -97,9 +84,11 @@ module Blather
97
84
  to_s <=> o.to_s
98
85
  end
99
86
 
100
- # Test id jid is strepped
87
+ ##
88
+ # Test if JID is stripped
101
89
  def stripped?
102
90
  @resource.nil?
103
91
  end
104
92
  end
93
+
105
94
  end