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.
- data/LICENSE +2 -0
- data/README.rdoc +100 -0
- data/Rakefile +110 -0
- data/examples/drb_client.rb +5 -0
- data/examples/echo.rb +18 -0
- data/ext/extconf.rb +65 -0
- data/ext/push_parser.c +231 -0
- data/lib/blather/client.rb +219 -44
- data/lib/blather/{core/sugar.rb → core_ext/active_support.rb} +25 -13
- data/lib/blather/core_ext/libxml.rb +28 -0
- data/lib/blather/errors/sasl_error.rb +87 -0
- data/lib/blather/errors/stanza_error.rb +262 -0
- data/lib/blather/errors/stream_error.rb +253 -0
- data/lib/blather/errors.rb +48 -0
- data/lib/blather/{core/jid.rb → jid.rb} +15 -26
- data/lib/blather/{core/roster.rb → roster.rb} +22 -0
- data/lib/blather/{core/roster_item.rb → roster_item.rb} +39 -8
- data/lib/blather/stanza/iq/disco.rb +11 -0
- data/lib/blather/stanza/iq/discos/disco_info.rb +86 -0
- data/lib/blather/stanza/iq/discos/disco_items.rb +61 -0
- data/lib/blather/stanza/iq/query.rb +51 -0
- data/lib/blather/stanza/iq/roster.rb +90 -0
- data/lib/blather/stanza/iq.rb +38 -0
- data/lib/blather/stanza/message.rb +58 -0
- data/lib/blather/stanza/presence/status.rb +78 -0
- data/lib/blather/stanza/presence/subscription.rb +72 -0
- data/lib/blather/stanza/presence.rb +45 -0
- data/lib/blather/stanza.rb +101 -0
- data/lib/blather/stream/client.rb +26 -0
- data/lib/blather/stream/component.rb +34 -0
- data/lib/blather/stream/parser.rb +70 -0
- data/lib/blather/stream/resource.rb +48 -0
- data/lib/blather/stream/sasl.rb +173 -0
- data/lib/blather/stream/session.rb +36 -0
- data/lib/blather/stream/stream_handler.rb +39 -0
- data/lib/blather/stream/tls.rb +33 -0
- data/lib/blather/stream.rb +249 -0
- data/lib/blather/xmpp_node.rb +199 -0
- data/lib/blather.rb +40 -41
- data/spec/blather/core_ext/libxml_spec.rb +58 -0
- data/spec/blather/errors/sasl_error_spec.rb +56 -0
- data/spec/blather/errors/stanza_error_spec.rb +148 -0
- data/spec/blather/errors/stream_error_spec.rb +114 -0
- data/spec/blather/errors_spec.rb +40 -0
- data/spec/blather/{core/jid_spec.rb → jid_spec.rb} +9 -1
- data/spec/blather/{core/roster_item_spec.rb → roster_item_spec.rb} +6 -1
- data/spec/blather/{core/roster_spec.rb → roster_spec.rb} +16 -6
- data/spec/blather/stanza/iq/discos/disco_info_spec.rb +207 -0
- data/spec/blather/stanza/iq/discos/disco_items_spec.rb +136 -0
- data/spec/blather/stanza/iq/query_spec.rb +34 -0
- data/spec/blather/stanza/iq/roster_spec.rb +123 -0
- data/spec/blather/stanza/iq_spec.rb +40 -0
- data/spec/blather/stanza/message_spec.rb +52 -0
- data/spec/blather/stanza/presence/status_spec.rb +102 -0
- data/spec/blather/stanza/presence/subscription_spec.rb +85 -0
- data/spec/blather/stanza/presence_spec.rb +53 -0
- data/spec/blather/{core/stanza_spec.rb → stanza_spec.rb} +14 -2
- data/spec/blather/stream/client_spec.rb +787 -0
- data/spec/blather/stream/component_spec.rb +86 -0
- data/spec/blather/{core/xmpp_node_spec.rb → xmpp_node_spec.rb} +76 -23
- data/spec/build_safe.rb +20 -0
- data/spec/spec_helper.rb +7 -17
- metadata +79 -59
- data/CHANGELOG +0 -1
- data/blather.gemspec +0 -73
- data/lib/blather/callback.rb +0 -24
- data/lib/blather/core/errors.rb +0 -24
- data/lib/blather/core/stanza.rb +0 -90
- data/lib/blather/core/stream.rb +0 -179
- data/lib/blather/core/xmpp_node.rb +0 -95
- data/lib/blather/extensions/last_activity.rb +0 -57
- data/lib/blather/extensions/version.rb +0 -85
- 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
|
-
#
|
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
|
49
|
-
|
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
|
-
|
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
|
-
|
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
|