ObjXMPP  Check-in [758ecec9ee]

Overview
Comment:Correctly handle stream restart.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 758ecec9ee9b74b2aa16de7c858d78374917811340f73cc3e96d586b65d5c0d3
User & Date: js on 2011-04-23 22:41:18
Other Links: manifest | tags
Context
2011-04-25
17:48
Move all roster handling code to XMPPRoster. check-in: 55e37a4da2 user: js tags: trunk
2011-04-23
22:41
Correctly handle stream restart. check-in: 758ecec9ee user: js tags: trunk
20:40
Adjust to recent ObjFW changes. check-in: d7038ec36d user: js tags: trunk
Changes

Modified src/XMPPConnection.h from [72439fbdc3] to [2a89c085aa].

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
 */
@interface XMPPConnection: OFObject
#ifdef OF_HAVE_OPTONAL_PROTOCOLS
    <OFXMLParserDelegate, OFXMLElementBuilderDelegate>
#endif
{
	OFTCPSocket *sock;
	OFXMLParser *parser;
	OFXMLElementBuilder *elementBuilder;
	OFString *username, *password, *server, *resource;
	XMPPJID *JID;
	uint16_t port;
	id <XMPPConnectionDelegate, OFObject> delegate;
	XMPPAuthenticator *authModule;
	BOOL needsSession;
	unsigned int lastID;







|
|







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
 */
@interface XMPPConnection: OFObject
#ifdef OF_HAVE_OPTONAL_PROTOCOLS
    <OFXMLParserDelegate, OFXMLElementBuilderDelegate>
#endif
{
	OFTCPSocket *sock;
	OFXMLParser *parser, *oldParser;
	OFXMLElementBuilder *elementBuilder, *oldElementBuilder;
	OFString *username, *password, *server, *resource;
	XMPPJID *JID;
	uint16_t port;
	id <XMPPConnectionDelegate, OFObject> delegate;
	XMPPAuthenticator *authModule;
	BOOL needsSession;
	unsigned int lastID;

Modified src/XMPPConnection.m from [9e2fd410e9] to [c97c429eb9].

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

- init
{
	self = [super init];

	@try {
		sock = [[OFTCPSocket alloc] init];
		parser = [[OFXMLParser alloc] init];
		elementBuilder = [[OFXMLElementBuilder alloc] init];

		port = 5222;

		[parser setDelegate: self];
		[elementBuilder setDelegate: self];

		roster = [[XMPPRoster alloc] initWithConnection: self];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}







<
<
<

<
<
<
<
<







50
51
52
53
54
55
56



57





58
59
60
61
62
63
64

- init
{
	self = [super init];

	@try {
		sock = [[OFTCPSocket alloc] init];



		port = 5222;





	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
234
235
236
237
238
239
240










241
242
243
244
245
246
247
{
	if (length < 1 && [delegate respondsToSelector:
	    @selector(connectionWasClosed:)])
		[delegate connectionWasClosed: self];

	[parser parseBuffer: buffer
		 withLength: length];










}

- (OFTCPSocket*)socket
{
	return [[sock retain] autorelease];
}








>
>
>
>
>
>
>
>
>
>







226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
{
	if (length < 1 && [delegate respondsToSelector:
	    @selector(connectionWasClosed:)])
		[delegate connectionWasClosed: self];

	[parser parseBuffer: buffer
		 withLength: length];

	if (oldParser != nil) {
		[oldParser release];
		oldParser = nil;
	}

	if (oldElementBuilder != nil) {
		[oldElementBuilder release];
		oldElementBuilder = nil;
	}
}

- (OFTCPSocket*)socket
{
	return [[sock retain] autorelease];
}

256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329





















330
331
332
333
334
335
336
	return [OFString stringWithFormat: @"objxmpp_%u", lastID++];
}

-    (void)parser: (OFXMLParser*)p
  didStartElement: (OFString*)name
       withPrefix: (OFString*)prefix
	namespace: (OFString*)ns
       attributes: (OFArray*)attrs
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFEnumerator *enumerator;
	OFXMLAttribute *attr;

	if (![name isEqual: @"stream"] || ![prefix isEqual: @"stream"] ||
	    ![ns isEqual: XMPP_NS_STREAM]) {
		of_log(@"Did not get expected stream start!");
		assert(0);
	}

	enumerator = [attrs objectEnumerator];
	while ((attr = [enumerator nextObject]) != nil) {
		if ([[attr name] isEqual: @"from"] &&
		    ![[attr stringValue] isEqual: server]) {
			of_log(@"Got invalid from in stream start!");
			assert(0);
		}
	}

	[parser setDelegate: elementBuilder];

	[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*)builder
       didBuildElement: (OFXMLElement*)element
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];

	[element setDefaultNamespace: XMPP_NS_CLIENT];
	[element setPrefix: @"stream"
	      forNamespace: XMPP_NS_STREAM];

	of_log(@"In:  %@", element);

	if ([[element namespace] isEqual: XMPP_NS_CLIENT])
		[self XMPP_handleStanza: element];

	if ([[element namespace] isEqual: XMPP_NS_STREAM])
		[self XMPP_handleStream: element];

	if ([[element namespace] isEqual: XMPP_NS_STARTTLS])
		[self XMPP_handleTLS: element];

	if ([[element namespace] isEqual: XMPP_NS_SASL])
		[self XMPP_handleSASL: element];

	[pool release];
}

- (void)XMPP_startStream
{





















	[sock writeFormat: @"<?xml version='1.0'?>\n"
			   @"<stream:stream to='%@' "
			   @"xmlns='" XMPP_NS_CLIENT @"' "
			   @"xmlns:stream='" XMPP_NS_STREAM @"' "
			   @"version='1.0'>", server];
}








|

<

|







|
|
|
|






<
<


















<
<

















<
<




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







258
259
260
261
262
263
264
265
266

267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285


286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303


304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320


321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
	return [OFString stringWithFormat: @"objxmpp_%u", lastID++];
}

-    (void)parser: (OFXMLParser*)p
  didStartElement: (OFString*)name
       withPrefix: (OFString*)prefix
	namespace: (OFString*)ns
       attributes: (OFArray*)attributes
{

	OFEnumerator *enumerator;
	OFXMLAttribute *attribute;

	if (![name isEqual: @"stream"] || ![prefix isEqual: @"stream"] ||
	    ![ns isEqual: XMPP_NS_STREAM]) {
		of_log(@"Did not get expected stream start!");
		assert(0);
	}

	enumerator = [attributes objectEnumerator];
	while ((attribute = [enumerator nextObject]) != nil) {
		if ([[attribute name] isEqual: @"from"] &&
		    ![[attribute stringValue] isEqual: server]) {
			of_log(@"Got invalid from in stream start!");
			assert(0);
		}
	}

	[parser setDelegate: elementBuilder];


}

-    (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*)builder
       didBuildElement: (OFXMLElement*)element
{


	[element setDefaultNamespace: XMPP_NS_CLIENT];
	[element setPrefix: @"stream"
	      forNamespace: XMPP_NS_STREAM];

	of_log(@"In:  %@", element);

	if ([[element namespace] isEqual: XMPP_NS_CLIENT])
		[self XMPP_handleStanza: element];

	if ([[element namespace] isEqual: XMPP_NS_STREAM])
		[self XMPP_handleStream: element];

	if ([[element namespace] isEqual: XMPP_NS_STARTTLS])
		[self XMPP_handleTLS: element];

	if ([[element namespace] isEqual: XMPP_NS_SASL])
		[self XMPP_handleSASL: element];


}

- (void)XMPP_startStream
{
	/* Make sure we don't get any old events */
	[parser setDelegate: nil];
	[elementBuilder setDelegate: nil];

	/*
	 * We can't release them now, as we are currently inside them. Release
	 * them the next time the parser returns.
	 */
	oldParser = parser;
	oldElementBuilder = elementBuilder;

	[roster release];

	parser = [[OFXMLParser alloc] init];
	[parser setDelegate: self];

	elementBuilder = [[OFXMLElementBuilder alloc] init];
	[elementBuilder setDelegate: self];

	roster = [[XMPPRoster alloc] initWithConnection: self];

	[sock writeFormat: @"<?xml version='1.0'?>\n"
			   @"<stream:stream to='%@' "
			   @"xmlns='" XMPP_NS_CLIENT @"' "
			   @"xmlns:stream='" XMPP_NS_STREAM @"' "
			   @"version='1.0'>", server];
}

477
478
479
480
481
482
483
484
485

486
487
488
489
490
491
492
		sock = newSock;

		if ([delegate respondsToSelector:
		    @selector(connectionDidUpgradeToTLS:)])
			[delegate connectionDidUpgradeToTLS: self];

		/* Stream restart */
		[parser setDelegate: self];
		[self XMPP_startStream];

		return;
	}

	if ([[element name] isEqual: @"failure"])
		/* TODO: Find/create an exception to throw here */
		@throw [OFException newWithClass: isa];








<

>







493
494
495
496
497
498
499

500
501
502
503
504
505
506
507
508
		sock = newSock;

		if ([delegate respondsToSelector:
		    @selector(connectionDidUpgradeToTLS:)])
			[delegate connectionDidUpgradeToTLS: self];

		/* Stream restart */

		[self XMPP_startStream];

		return;
	}

	if ([[element name] isEqual: @"failure"])
		/* TODO: Find/create an exception to throw here */
		@throw [OFException newWithClass: isa];

516
517
518
519
520
521
522
523
524

525
526
527
528
529
530
531
		    dataArrayWithBase64EncodedString: [element stringValue]]];

		if ([delegate respondsToSelector:
		    @selector(connectionWasAuthenticated:)])
			[delegate connectionWasAuthenticated: self];

		/* Stream restart */
		[parser setDelegate: self];
		[self XMPP_startStream];

		return;
	}

	if ([[element name] isEqual: @"failure"]) {
		of_log(@"Auth failed!");
		// FIXME: Do more parsing/handling
		@throw [XMPPAuthFailedException







<

>







532
533
534
535
536
537
538

539
540
541
542
543
544
545
546
547
		    dataArrayWithBase64EncodedString: [element stringValue]]];

		if ([delegate respondsToSelector:
		    @selector(connectionWasAuthenticated:)])
			[delegate connectionWasAuthenticated: self];

		/* Stream restart */

		[self XMPP_startStream];

		return;
	}

	if ([[element name] isEqual: @"failure"]) {
		of_log(@"Auth failed!");
		// FIXME: Do more parsing/handling
		@throw [XMPPAuthFailedException