Handle stream errors

This commit is contained in:
Florian Zeitz 2011-04-15 02:41:23 +02:00
parent 683fc1e3ae
commit d47fdd3380
4 changed files with 202 additions and 0 deletions

View file

@ -39,6 +39,7 @@
#define XMPP_NS_STARTTLS @"urn:ietf:params:xml:ns:xmpp-tls"
#define XMPP_NS_STANZAS @"urn:ietf:params:xml:ns:xmpp-stanzas"
#define XMPP_NS_SESSION @"urn:ietf:params:xml:ns:xmpp-session"
#define XMPP_NS_XMPP_STREAM @"urn:ietf:params:xml:ns:xmpp-streams"
#define XMPP_NS_STREAM @"http://etherx.jabber.org/streams"
@protocol XMPPConnectionDelegate

View file

@ -286,6 +286,19 @@
[pool release];
}
- (void)parser: (OFXMLParser*)p
didEndElement: (OFString*)name
withPrefix: (OFString*)prefix
namespace: (OFString*)ns
attributes: (OFArray*)attrs
{
if (![name isEqual: @"stream"] || ![prefix isEqual: @"stream"] ||
![ns isEqual: XMPP_NS_STREAM]) {
of_log(@"Did not get expected stream end!");
assert(0);
}
}
- (void)elementBuilder: (OFXMLElementBuilder*)b
didBuildElement: (OFXMLElement*)elem
{
@ -351,6 +364,101 @@
return;
}
if ([[elem name] isEqual: @"error"]) {
OFString *condition, *reason;
[parser setDelegate: self];
[sock writeString: @"</stream:stream>"];
[sock close];
if ([elem elementForName: @"bad-format"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"bad-format";
else if ([elem elementForName: @"bad-namespace-prefix"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"bad-namespace-prefix";
else if ([elem elementForName: @"conflict"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"conflict";
else if ([elem elementForName: @"connection-timeout"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"connection-timeout";
else if ([elem elementForName: @"host-gone"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"host-gone";
else if ([elem elementForName: @"host-unknown"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"host-unknown";
else if ([elem elementForName: @"improper-addressing"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"improper-addressing";
else if ([elem elementForName: @"internal-server-error"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"internal-server-error";
else if ([elem elementForName: @"invalid-from"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"invalid-from";
else if ([elem elementForName: @"invalid-namespace"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"invalid-namespace";
else if ([elem elementForName: @"invalid-xml"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"invalid-xml";
else if ([elem elementForName: @"not-authorized"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"not-authorized";
else if ([elem elementForName: @"not-well-formed"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"not-well-formed";
else if ([elem elementForName: @"policy-violation"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"policy-violation";
else if ([elem elementForName: @"remote-connection-failed"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"remote-connection-failed";
else if ([elem elementForName: @"reset"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"reset";
else if ([elem elementForName: @"resource-constraint"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"resource-constraint";
else if ([elem elementForName: @"restricted-xml"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"restricted-xml";
else if ([elem elementForName: @"see-other-host"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"see-other-host";
else if ([elem elementForName: @"system-shutdown"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"system-shutdown";
else if ([elem elementForName: @"undefined-condition"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"undefined-condition";
else if ([elem elementForName: @"unsupported-encoding"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"unsupported-encoding";
else if ([elem elementForName: @"unsupported-feature"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"unsupported-feature";
else if ([elem elementForName: @"unsupported-stanza-type"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"unsupported-stanza-type";
else if ([elem elementForName: @"unsupported-version"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"unsupported-version";
else
condition = @"undefined";
reason = [[elem elementForName: @"text"
namespace: XMPP_NS_XMPP_STREAM]
stringValue];
@throw [XMPPStreamErrorException newWithClass: isa
connection: self
condition: condition
reason: reason];
return;
}
assert(0);
}

View file

@ -41,6 +41,29 @@
- (XMPPConnection*)connection;
@end
@interface XMPPStreamErrorException: XMPPException
{
OFString *condition;
OFString *reason;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, nonatomic) OFString *condition;
@property (readonly, nonatomic) OFString *reason;
#endif
+ newWithClass: (Class)class_
connection: (XMPPConnection*)conn
condition: (OFString*)condition_
reason: (OFString*)reason_;
- initWithClass: (Class)class_
connection: (XMPPConnection*)conn
condition: (OFString*)condition_
reason: (OFString*)reason_;
- (OFString*)condition;
- (OFString*)reason;
@end
@interface XMPPStringPrepFailedException: XMPPException
{
OFString *profile;

View file

@ -77,6 +77,76 @@
}
@end
@implementation XMPPStreamErrorException
+ newWithClass: (Class)class_
connection: (XMPPConnection*)conn
condition: (OFString*)condition_
reason: (OFString*)reason_;
{
return [[self alloc] initWithClass: class_
connection: conn
condition: condition_
reason: reason_];
}
- initWithClass: (Class)class_
connection: (XMPPConnection*)conn
{
Class c = isa;
[self release];
@throw [OFNotImplementedException newWithClass: c
selector: _cmd];
}
- initWithClass: (Class)class_
connection: (XMPPConnection*)conn
condition: (OFString*)condition_
reason: (OFString*)reason_
{
self = [super initWithClass: class_
connection: conn];
@try {
condition = [condition_ copy];
reason = [reason_ copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[condition release];
[reason release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Got stream error: %@. Reason: %@!", condition, reason];
return description;
}
- (OFString*)condition
{
return condition;
}
- (OFString*)reason
{
return reason;
}
@end
@implementation XMPPStringPrepFailedException
+ newWithClass: (Class)class_
connection: (XMPPConnection*)conn