Adjust to ObjFW changes

This commit is contained in:
Jonathan Schleifer 2018-12-22 21:59:02 +01:00
parent 5059b34193
commit 15c922cdad
No known key found for this signature in database
GPG key ID: D83A76BFE376345E
3 changed files with 66 additions and 166 deletions

View file

@ -29,6 +29,8 @@
OF_ASSUME_NONNULL_BEGIN OF_ASSUME_NONNULL_BEGIN
#define XMPP_CONNECTION_BUFFER_LENGTH 512
@class XMPPConnection; @class XMPPConnection;
@class XMPPJID; @class XMPPJID;
@class XMPPIQ; @class XMPPIQ;
@ -110,8 +112,10 @@ OF_ASSUME_NONNULL_BEGIN
* @brief This callback is called when the connection was closed. * @brief This callback is called when the connection was closed.
* *
* @param connection The connection that was closed * @param connection The connection that was closed
* @param error The error XML element the stream encountered or nil
*/ */
- (void)connectionWasClosed: (XMPPConnection *)connection; - (void)connectionWasClosed: (XMPPConnection *)connection
error: (nullable OFXMLElement *)error;
/*! /*!
* @brief This callback is called when the connection threw an exception. * @brief This callback is called when the connection threw an exception.
@ -141,10 +145,10 @@ OF_ASSUME_NONNULL_BEGIN
/*! /*!
* @brief A class which abstracts a connection to an XMPP service. * @brief A class which abstracts a connection to an XMPP service.
*/ */
@interface XMPPConnection: OFObject <OFXMLParserDelegate, @interface XMPPConnection: OFObject
OFXMLElementBuilderDelegate>
{ {
OF_KINDOF(OFTCPSocket *) _socket; OF_KINDOF(OFTCPSocket *) _socket;
char _buffer[XMPP_CONNECTION_BUFFER_LENGTH];
OFXMLParser *_parser, *_oldParser; OFXMLParser *_parser, *_oldParser;
OFXMLElementBuilder *_elementBuilder, *_oldElementBuilder; OFXMLElementBuilder *_elementBuilder, *_oldElementBuilder;
OFString *_Nullable _username, *_Nullable _password, *_Nullable _server; OFString *_Nullable _username, *_Nullable _password, *_Nullable _server;
@ -157,6 +161,7 @@ OF_ASSUME_NONNULL_BEGIN
uint16_t _port; uint16_t _port;
id <XMPPStorage> _Nullable _dataStorage; id <XMPPStorage> _Nullable _dataStorage;
OFString *_Nullable _language; OFString *_Nullable _language;
OFMutableArray *_nextSRVRecords;
XMPPMulticastDelegate *_delegates; XMPPMulticastDelegate *_delegates;
OFMutableDictionary OF_GENERIC(OFString *, XMPPCallback *) *_callbacks; OFMutableDictionary OF_GENERIC(OFString *, XMPPCallback *) *_callbacks;
XMPPAuthenticator *_authModule; XMPPAuthenticator *_authModule;

View file

@ -56,26 +56,11 @@
#import <ObjFW/macros.h> #import <ObjFW/macros.h>
#define BUFFER_LENGTH 512 @interface XMPPConnection () <OFDNSResolverDelegate, OFTCPSocketDelegate,
OFXMLParserDelegate, OFXMLElementBuilderDelegate>
@interface XMPPConnection () - (void)xmpp_tryNextSRVRecord;
- (void)xmpp_socketDidConnect: (OFTCPSocket *)socket
context: (OFArray *)nextSRVRecords
exception: (id)exception;
- (void)xmpp_tryNextSRVRecord: (OFArray *)SRVRecords;
- (void)xmpp_resolver: (OFDNSResolver *)resolver
didResolveDomainName: (OFString *)domainName
answerRecords: (OFDictionary *)answerRecords
authorityRecords: (OFDictionary *)authorityRecords
additionalRecords: (OFDictionary *)additionalRecords
context: (OFString *)domainToASCII
exception: (id)exception;
- (bool)xmpp_parseBuffer: (const void *)buffer - (bool)xmpp_parseBuffer: (const void *)buffer
length: (size_t)length; length: (size_t)length;
- (bool)xmpp_stream: (OFStream *)stream
didReadIntoBuffer: (char *)buffer
length: (size_t)length
exception: (OFException *)exception;
- (void)xmpp_startStream; - (void)xmpp_startStream;
- (void)xmpp_handleStanza: (OFXMLElement *)element; - (void)xmpp_handleStanza: (OFXMLElement *)element;
- (void)xmpp_handleStream: (OFXMLElement *)element; - (void)xmpp_handleStream: (OFXMLElement *)element;
@ -142,6 +127,7 @@
[_domain release]; [_domain release];
[_resource release]; [_resource release];
[_JID release]; [_JID release];
[_nextSRVRecords release];
[_delegates release]; [_delegates release];
[_callbacks release]; [_callbacks release];
[_authModule release]; [_authModule release];
@ -271,20 +257,19 @@
[old release]; [old release];
} }
- (void)xmpp_socketDidConnect: (OFTCPSocket *)socket - (void)socket: (OF_KINDOF(OFTCPSocket *))sock
context: (OFArray *)nextSRVRecords didConnectToHost: (OFString *)host
port: (uint16_t)port
exception: (id)exception exception: (id)exception
{ {
char *buffer;
if (exception != nil) { if (exception != nil) {
if (nextSRVRecords != nil) { if ([_nextSRVRecords count] > 0) {
[self xmpp_tryNextSRVRecord: nextSRVRecords]; [self xmpp_tryNextSRVRecord];
return; return;
} }
[_delegates [_delegates broadcastSelector: @selector(connection:
broadcastSelector: @selector(connection:didThrowException:) didThrowException:)
withObject: self withObject: self
withObject: exception]; withObject: exception];
return; return;
@ -292,38 +277,29 @@
[self xmpp_startStream]; [self xmpp_startStream];
buffer = [self allocMemoryWithSize: BUFFER_LENGTH]; [_socket asyncReadIntoBuffer: _buffer
[_socket asyncReadIntoBuffer: buffer length: XMPP_CONNECTION_BUFFER_LENGTH];
length: BUFFER_LENGTH
target: self
selector: @selector(xmpp_stream:didReadIntoBuffer:
length:exception:)
context: nil];
} }
- (void)xmpp_tryNextSRVRecord: (OFArray *)SRVRecords - (void)xmpp_tryNextSRVRecord
{ {
OFSRVDNSResourceRecord *record = [SRVRecords objectAtIndex: 0]; OFSRVDNSResourceRecord *record =
[[[_nextSRVRecords objectAtIndex: 0] copy] autorelease];
SRVRecords = [SRVRecords objectsInRange: if ([_nextSRVRecords count] == 0) {
of_range(1, [SRVRecords count] - 1)]; [_nextSRVRecords release];
if ([SRVRecords count] == 0) _nextSRVRecords = nil;
SRVRecords = nil; }
[_socket asyncConnectToHost: [record target] [_socket asyncConnectToHost: [record target]
port: [record port] port: [record port]];
target: self
selector: @selector(xmpp_socketDidConnect:
context:exception:)
context: SRVRecords];
} }
- (void)xmpp_resolver: (OFDNSResolver *)resolver - (void)resolver: (OFDNSResolver *)resolver
didResolveDomainName: (OFString *)domainName didResolveDomainName: (OFString *)domainName
answerRecords: (OFDictionary *)answerRecords answerRecords: (OFDictionary *)answerRecords
authorityRecords: (OFDictionary *)authorityRecords authorityRecords: (OFDictionary *)authorityRecords
additionalRecords: (OFDictionary *)additionalRecords additionalRecords: (OFDictionary *)additionalRecords
context: (OFString *)domainToASCII
exception: (id)exception exception: (id)exception
{ {
OFMutableArray *records = [OFMutableArray array]; OFMutableArray *records = [OFMutableArray array];
@ -345,17 +321,16 @@
[records makeImmutable]; [records makeImmutable];
if ([records count] == 0) { if ([records count] == 0) {
/* Fall back to A / AAA record. */ /* Fall back to A / AAAA record. */
[_socket asyncConnectToHost: domainToASCII [_socket asyncConnectToHost: _domainToASCII
port: _port port: _port];
target: self
selector: @selector(xmpp_socketDidConnect:
context:exception:)
context: nil];
return; return;
} }
[self xmpp_tryNextSRVRecord: records]; [_nextSRVRecords release];
_nextSRVRecords = nil;
_nextSRVRecords = [records mutableCopy];
[self xmpp_tryNextSRVRecord];
} }
- (void)asyncConnect - (void)asyncConnect
@ -366,23 +341,14 @@
@throw [OFAlreadyConnectedException exception]; @throw [OFAlreadyConnectedException exception];
_socket = [[OFTCPSocket alloc] init]; _socket = [[OFTCPSocket alloc] init];
[_socket setDelegate: self];
if (_server != nil) if (_server != nil)
[_socket asyncConnectToHost: _server [_socket asyncConnectToHost: _server
port: _port port: _port];
target: self
selector: @selector(xmpp_socketDidConnect:
context:exception:)
context: nil];
else else
[[OFThread DNSResolver] [[OFThread DNSResolver] asyncResolveHost: _domainToASCII
asyncResolveHost: _domainToASCII delegate: self];
target: self
selector: @selector(xmpp_resolver:
didResolveDomainName:answerRecords:
authorityRecords:additionalRecords:
context:exception:)
context: _domainToASCII];
objc_autoreleasePoolPop(pool); objc_autoreleasePoolPop(pool);
} }
@ -391,8 +357,10 @@
length: (size_t)length length: (size_t)length
{ {
if ([_socket isAtEndOfStream]) { if ([_socket isAtEndOfStream]) {
[_delegates broadcastSelector: @selector(connectionWasClosed:) [_delegates broadcastSelector: @selector(connectionWasClosed:
withObject: self]; error:)
withObject: self
withObject: nil];
return false; return false;
} }
@ -422,10 +390,10 @@
_oldElementBuilder = nil; _oldElementBuilder = nil;
} }
- (bool)xmpp_stream: (OFStream *)stream - (bool)stream: (OF_KINDOF(OFStream *))stream
didReadIntoBuffer: (char *)buffer didReadIntoBuffer: (void *)buffer
length: (size_t)length length: (size_t)length
exception: (OFException *)exception exception: (id)exception
{ {
if (exception != nil) { if (exception != nil) {
[_delegates broadcastSelector: @selector(connection: [_delegates broadcastSelector: @selector(connection:
@ -456,14 +424,8 @@
_oldParser = nil; _oldParser = nil;
_oldElementBuilder = nil; _oldElementBuilder = nil;
[_socket asyncReadIntoBuffer: buffer [_socket asyncReadIntoBuffer: _buffer
length: BUFFER_LENGTH length: XMPP_CONNECTION_BUFFER_LENGTH];
target: self
selector: @selector(xmpp_stream:
didReadIntoBuffer:length:
exception:)
context: nil];
return false; return false;
} }
@ -586,7 +548,7 @@
- (void)parser: (OFXMLParser *)parser - (void)parser: (OFXMLParser *)parser
didStartElement: (OFString *)name didStartElement: (OFString *)name
prefix: (OFString *)prefix prefix: (OFString *)prefix
namespace: (OFString *)NS namespace: (OFString *)namespace
attributes: (OFArray *)attributes attributes: (OFArray *)attributes
{ {
if (![name isEqual: @"stream"]) { if (![name isEqual: @"stream"]) {
@ -602,7 +564,7 @@
return; return;
} }
if (![NS isEqual: XMPP_NS_STREAM]) { if (![namespace isEqual: XMPP_NS_STREAM]) {
[self xmpp_sendStreamError: @"invalid-namespace" [self xmpp_sendStreamError: @"invalid-namespace"
text: nil]; text: nil];
return; return;
@ -755,84 +717,15 @@
if ([[element name] isEqual: @"error"]) { if ([[element name] isEqual: @"error"]) {
OFString *condition, *reason; OFString *condition, *reason;
[self close]; [self close];
[_socket close]; // Remote has already closed his stream
if ([element elementForName: @"bad-format" [_delegates broadcastSelector: @selector(connectionWasClosed:)
namespace: XMPP_NS_XMPP_STREAM]) withObject: self
condition = @"bad-format"; withObject: element];
else if ([element elementForName: @"bad-namespace-prefix"
namespace: XMPP_NS_XMPP_STREAM]) condition = [[[element elementsForNamespace:
condition = @"bad-namespace-prefix"; XMPP_NS_XMPP_STREAM] firstObject] name];
else if ([element elementForName: @"conflict"
namespace: XMPP_NS_XMPP_STREAM]) if (condition == nil)
condition = @"conflict";
else if ([element elementForName: @"connection-timeout"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"connection-timeout";
else if ([element elementForName: @"host-gone"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"host-gone";
else if ([element elementForName: @"host-unknown"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"host-unknown";
else if ([element elementForName: @"improper-addressing"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"improper-addressing";
else if ([element elementForName: @"internal-server-error"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"internal-server-error";
else if ([element elementForName: @"invalid-from"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"invalid-from";
else if ([element elementForName: @"invalid-namespace"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"invalid-namespace";
else if ([element elementForName: @"invalid-xml"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"invalid-xml";
else if ([element elementForName: @"not-authorized"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"not-authorized";
else if ([element elementForName: @"not-well-formed"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"not-well-formed";
else if ([element elementForName: @"policy-violation"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"policy-violation";
else if ([element elementForName: @"remote-connection-failed"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"remote-connection-failed";
else if ([element elementForName: @"reset"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"reset";
else if ([element elementForName: @"resource-constraint"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"resource-constraint";
else if ([element elementForName: @"restricted-xml"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"restricted-xml";
else if ([element elementForName: @"see-other-host"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"see-other-host";
else if ([element elementForName: @"system-shutdown"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"system-shutdown";
else if ([element elementForName: @"undefined-condition"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"undefined-condition";
else if ([element elementForName: @"unsupported-encoding"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"unsupported-encoding";
else if ([element elementForName: @"unsupported-feature"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"unsupported-feature";
else if ([element elementForName: @"unsupported-stanza-type"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"unsupported-stanza-type";
else if ([element elementForName: @"unsupported-version"
namespace: XMPP_NS_XMPP_STREAM])
condition = @"unsupported-version";
else
condition = @"undefined"; condition = @"undefined";
reason = [[element reason = [[element
@ -870,6 +763,7 @@
[newSock startTLSWithExpectedHost: nil]; [newSock startTLSWithExpectedHost: nil];
[_socket release]; [_socket release];
_socket = newSock; _socket = newSock;
[_socket setDelegate: self];
_encrypted = true; _encrypted = true;

View file

@ -269,7 +269,8 @@ OF_APPLICATION_DELEGATE(AppDelegate)
} }
- (void)connectionWasClosed: (XMPPConnection *)conn - (void)connectionWasClosed: (XMPPConnection *)conn
error: (OFXMLElement *)error
{ {
of_log(@"Connection was closed!"); of_log(@"Connection was closed: %@", error);
} }
@end @end