ObjXMPP  Check-in [423434d147]

Overview
Comment:Adjust to newest ObjFW and greatly improve XML handling.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 423434d147dabe90fa497a17a626ec1138af1a37f84b6e9b61540ce56e7e8768
User & Date: js on 2011-03-31 12:25:41
Other Links: manifest | tags
Context
2011-04-01
01:09
Change how roster items are stored. check-in: e53970f55f user: js tags: trunk
2011-03-31
12:25
Adjust to newest ObjFW and greatly improve XML handling. check-in: 423434d147 user: js tags: trunk
2011-03-30
18:35
Set the default namespace and prefixes when creating a new XMPPStanza. check-in: efd0127bff user: js tags: trunk
Changes

Modified src/XMPPConnection.m from [a4f8793bd7] to [8c6dc2da09].

223
224
225
226
227
228
229
230

231
232
233
234
235
236
237
223
224
225
226
227
228
229

230
231
232
233
234
235
236
237







-
+







			   withSize: len];
	}
}

- (void)sendStanza: (OFXMLElement*)elem
{
	of_log(@"Out: %@", elem);
	[sock writeString: [elem stringValue]];
	[sock writeString: [elem XMLString]];
}

- (OFString*)generateStanzaID
{
	return [OFString stringWithFormat: @"objxmpp_%u", lastID++];
}

341
342
343
344
345
346
347
348

349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366

367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384

385
386
387
388
389
390
391
341
342
343
344
345
346
347

348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365

366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383

384
385
386
387
388
389
390
391







-
+

















-
+

















-
+







	}

	if ([[elem namespace] isEqual: XMPP_NS_SASL]) {
		if ([[elem name] isEqual: @"challenge"]) {
			OFXMLElement *responseTag;
			OFDataArray *challenge =
			    [OFDataArray dataArrayWithBase64EncodedString:
			    [[[elem children] firstObject] stringValue]];
			    [elem stringValue]];
			OFDataArray *response = [authModule
			    calculateResponseWithChallenge: challenge];

			responseTag = [OFXMLElement
			    elementWithName: @"response"
				  namespace: XMPP_NS_SASL];
			[responseTag addChild:
			    [OFXMLElement elementWithCharacters:
			    [response stringByBase64Encoding]]];

			[self sendStanza: responseTag];
			return;
		}

		if ([[elem name] isEqual: @"success"]) {
			[authModule parseServerFinalMessage:
			    [OFDataArray dataArrayWithBase64EncodedString:
				[[[elem children] firstObject] stringValue]]];
				[elem stringValue]]];

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

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

		if ([[elem name] isEqual: @"failure"]) {
			of_log(@"Auth failed!");
			// FIXME: Do more parsing/handling
			@throw [XMPPAuthFailedException
			    newWithClass: isa
			      connection: self
				  reason: [elem stringValue]];
				  reason: [elem XMLString]];
		}

		assert(0);
	}

	assert(0);
}
448
449
450
451
452
453
454
455

456
457
458
459
460




461
462
463
464



465
466
467
468
469
470
471
472
473
474

475
476
477
478

479
480

481
482
483
484
485
486
487
488
448
449
450
451
452
453
454

455





456
457
458
459




460
461
462
463
464
465
466
467
468
469
470
471

472
473
474
475

476
477

478

479
480
481
482
483
484
485







-
+
-
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+









-
+



-
+

-
+
-







	     @selector(connection:didReceivePresence:)])
		[delegate connection: self
		  didReceivePresence: pres];
}

- (void)XMPP_handleFeatures: (OFXMLElement*)elem
{
	OFXMLElement *starttls =
	OFXMLElement *starttls = [elem elementForName: @"starttls"
	    [[elem elementsForName: @"starttls"
			 namespace: XMPP_NS_STARTTLS] firstObject];
	OFXMLElement *bind = [[elem elementsForName: @"bind"
					  namespace: XMPP_NS_BIND] firstObject];
	OFXMLElement *session =
					    namespace: XMPP_NS_STARTTLS];
	OFXMLElement *bind = [elem elementForName: @"bind"
					namespace: XMPP_NS_BIND];
	OFXMLElement *session = [elem elementForName: @"session"
	    [[elem elementsForName: @"session"
			 namespace: XMPP_NS_SESSION] firstObject];
	OFArray *mechs = [elem elementsForName: @"mechanisms"
				     namespace: XMPP_NS_SASL];
					   namespace: XMPP_NS_SESSION];
	OFXMLElement *mechs = [elem elementForName: @"mechanisms"
					 namespace: XMPP_NS_SASL];
	OFMutableArray *mechanisms = [OFMutableArray array];

	if (starttls != nil) {
		[self sendStanza:
		    [OFXMLElement elementWithName: @"starttls"
					namespace: XMPP_NS_STARTTLS]];
		return;
	}

	if ([mechs count] > 0) {
	if (mechs != nil) {
		OFEnumerator *enumerator;
		OFXMLElement *mech;

		enumerator = [[[mechs firstObject] children] objectEnumerator];
		enumerator = [[mechs children] objectEnumerator];
		while ((mech = [enumerator nextObject]) != nil)
			[mechanisms addObject:
			[mechanisms addObject: [mech stringValue]];
			    [[[mech children] firstObject] stringValue]];

		if ([mechanisms containsObject: @"SCRAM-SHA-1"]) {
			authModule = [[XMPPSCRAMAuth alloc]
			    initWithAuthcid: username
				   password: password
				       hash: [OFSHA1Hash class]];
			[self XMPP_sendAuth: @"SCRAM-SHA-1"];
547
548
549
550
551
552
553
554

555
556
557


558
559
560
561

562
563
564



565
566
567
568
569
570
571
572
544
545
546
547
548
549
550

551

552

553
554
555



556
557


558
559
560

561
562
563
564
565
566
567







-
+
-

-
+
+

-
-
-
+

-
-
+
+
+
-







}

- (void)XMPP_handleResourceBind: (XMPPIQ*)iq
{
	OFXMLElement *bindElem;
	OFXMLElement *jidElem;

	if (![[iq type] isEqual: @"result"])
	assert([[iq type] isEqual: @"result"]);
		assert(0);

	bindElem = [[iq children] firstObject];
	bindElem = [iq elementForName: @"bind"
			    namespace: XMPP_NS_BIND];

	if (![[bindElem name] isEqual: @"bind"] ||
	    ![[bindElem namespace] isEqual: XMPP_NS_BIND])
		assert(0);
	assert(bindElem != nil);

	jidElem = [[bindElem children] firstObject];
	JID = [[XMPPJID alloc] initWithString:
	jidElem = [bindElem elementForName: @"jid"
				 namespace: XMPP_NS_BIND];
	JID = [[XMPPJID alloc] initWithString: [jidElem stringValue]];
	    [[[jidElem children] firstObject] stringValue]];

	[bindID release];
	bindID = nil;

	if (needsSession) {
		[self XMPP_sendSession];
		return;
619
620
621
622
623
624
625
626

627
628
629


630
631
632
633

634
635
636
637
638
639
640
614
615
616
617
618
619
620

621

622

623
624
625



626
627
628
629
630
631
632
633







-
+
-

-
+
+

-
-
-
+








- (void)XMPP_handleRoster: (XMPPIQ*)iq
{
	OFXMLElement *rosterElem;
	OFEnumerator *enumerator;
	OFXMLElement *elem;

	if (![[iq type] isEqual: @"result"])
	assert([[iq type] isEqual: @"result"]);
		assert(0);

	rosterElem = [[iq children] firstObject];
	rosterElem = [iq elementForName: @"query"
			      namespace: XMPP_NS_ROSTER];

	if (![[rosterElem name] isEqual: @"query"] ||
	    ![[rosterElem namespace] isEqual: XMPP_NS_ROSTER])
		assert(0);
	assert(rosterElem != nil);

	enumerator = [[rosterElem children] objectEnumerator];
	while ((elem = [enumerator nextObject]) != nil) {
		XMPPRosterItem *rosterItem;
		OFMutableArray *groups = [OFMutableArray array];
		OFEnumerator *groupEnumerator;
		OFXMLElement *groupElem;
651
652
653
654
655
656
657
658

659
660
661
662
663
664
665
666
644
645
646
647
648
649
650

651

652
653
654
655
656
657
658







-
+
-







		[rosterItem setSubscription:
		    [[elem attributeForName: @"subscription"] stringValue]];

		groupEnumerator =
		    [[elem elementsForName: @"group"
				 namespace: XMPP_NS_ROSTER] objectEnumerator];
		while ((groupElem = [groupEnumerator nextObject]) != nil)
			[groups addObject:
			[groups addObject: [groupElem stringValue]];
			    [[[groupElem children] firstObject] stringValue]];

		if ([groups count] > 0)
			[rosterItem setGroups: groups];

		[roster XMPP_addRosterItem: rosterItem];
	}

Modified tests/test.m from [4765f2a59a] to [d26de2a21f].

49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65

66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
49
50
51
52
53
54
55

56
57
58
59
60
61
62
63
64

65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
94







-
+








-
+







-
+













-
+








	XMPPPresence *pres = [XMPPPresence presence];
	[pres addShow: @"chat"];
	[pres addStatus: @"Bored"];
	[pres addPriority: 20];
	[pres setTo: [XMPPJID JIDWithString: @"alice@example.com"]];
	[pres setFrom: [XMPPJID JIDWithString: @"bob@example.org"]];
	assert([[pres stringValue] isEqual: @"<presence to='alice@example.com' "
	assert([[pres XMLString] isEqual: @"<presence to='alice@example.com' "
	    @"from='bob@example.org'><show>chat</show>"
	    @"<status>Bored</status><priority>20</priority>"
	    @"</presence>"]);

	XMPPMessage *msg = [XMPPMessage messageWithType: @"chat"];
	[msg addBody: @"Hello everyone"];
	[msg setTo: [XMPPJID JIDWithString: @"jdev@conference.jabber.org"]];
	[msg setFrom: [XMPPJID JIDWithString: @"alice@example.com"]];
	assert([[msg stringValue] isEqual: @"<message type='chat' "
	assert([[msg XMLString] isEqual: @"<message type='chat' "
	    @"to='jdev@conference.jabber.org' "
	    @"from='alice@example.com'><body>Hello everyone</body>"
	    @"</message>"]);

	XMPPIQ *iq = [XMPPIQ IQWithType: @"set" ID: @"128"];
	[iq setTo: [XMPPJID JIDWithString: @"juliet@capulet.lit"]];
	[iq setFrom: [XMPPJID JIDWithString: @"romeo@montague.lit"]];
	assert([[iq stringValue] isEqual: @"<iq type='set' id='128' "
	assert([[iq XMLString] isEqual: @"<iq type='set' id='128' "
	    @"to='juliet@capulet.lit' "
	    @"from='romeo@montague.lit'/>"]);

	OFXMLElement *elem = [OFXMLElement elementWithName: @"iq"];
	[elem addAttributeWithName: @"from"
		       stringValue: @"bob@localhost"];
	[elem addAttributeWithName: @"to"
		       stringValue: @"alice@localhost"];
	[elem addAttributeWithName: @"type"
		       stringValue: @"get"];
	[elem addAttributeWithName: @"id"
		       stringValue: @"42"];
	XMPPStanza *stanza = [XMPPStanza stanzaWithElement: elem];
	assert([[elem stringValue] isEqual: [stanza stringValue]]);
	assert([[elem XMLString] isEqual: [stanza XMLString]]);
	assert(([[OFString stringWithFormat: @"%@, %@, %@, %@",
	    [[stanza from] fullJID], [[stanza to] fullJID], [stanza type],
	    [stanza ID]] isEqual: @"bob@localhost, alice@localhost, get, 42"]));

	conn = [[XMPPConnection alloc] init];
	[conn setDelegate: self];