source:
ralphm-patches/disco-addressing.patch
@
47:f6d222b68f1c
Last change on this file since 47:f6d222b68f1c was 47:f6d222b68f1c, checked in by Ralph Meijer <ralphm@…>, 10 years ago | |
---|---|
File size: 9.8 KB |
-
wokkel/disco.py
# HG changeset patch # Parent ec507e96d825c087430df236727e6f6161d8af12 Reimplement _DiscoRequest as generic.Request. Author: ralphm, Goffi. Fixes: #73. diff -r ec507e96d825 wokkel/disco.py
a b 14 14 from twisted.words.protocols.jabber import error, jid 15 15 from twisted.words.xish import domish 16 16 17 from wokkel import data_form 17 from wokkel import data_form, generic 18 18 from wokkel.compat import IQ 19 19 from wokkel.iwokkel import IDisco 20 20 from wokkel.subprotocols import IQHandlerMixin, XMPPHandler … … 346 346 347 347 348 348 349 class _DiscoRequest( IQ):349 class _DiscoRequest(generic.Request): 350 350 """ 351 Element representing an XMPP service discovery request. 351 A Service Discovery request. 352 353 @ivar verb: Type of request: C{'info'} or C{'items'}. 354 @type verb: C{str} 355 @ivar nodeIdentifier: Optional node to request info for. 356 @type nodeIdentifier: C{unicode} 352 357 """ 353 358 354 def __init__(self, xs, namespace, nodeIdentifier=''): 355 """ 356 Initialize the request. 359 verb = None 360 nodeIdentifier = '' 357 361 358 @param xs: XML Stream the request should go out on. 359 @type xs: L{xmlstream.XmlStream} 360 @param namespace: Request namespace. 361 @type namespace: C{str} 362 @param nodeIdentifier: Node to request info from. 363 @type nodeIdentifier: C{unicode} 364 """ 365 IQ.__init__(self, xs, "get") 366 query = self.addElement((namespace, 'query')) 367 if nodeIdentifier: 368 query['node'] = nodeIdentifier 362 _requestVerbMap = { 363 NS_DISCO_INFO: 'info', 364 NS_DISCO_ITEMS: 'items', 365 } 366 367 _verbRequestMap = dict(((v, k) for k, v in _requestVerbMap.iteritems())) 368 369 def __init__(self, verb=None, nodeIdentifier='', 370 recipient=None, sender=None): 371 generic.Request.__init__(self, 'get', recipient, sender) 372 self.verb = verb 373 self.nodeIdentifier = nodeIdentifier 374 375 376 def parseElement(self, element): 377 generic.Request.parseElement(self, element) 378 379 verbElement = None 380 for child in element.elements(): 381 if child.name == 'query' and child.uri in self._requestVerbMap: 382 self.verb = self._requestVerbMap[child.uri] 383 verbElement = child 384 385 if verbElement: 386 self.nodeIdentifier = verbElement.getAttribute('node', '') 387 388 389 def toElement(self): 390 element = generic.Request.toElement(self) 391 392 childURI = self._verbRequestMap[self.verb] 393 query = element.addElement((childURI, 'query')) 394 395 if self.nodeIdentifier: 396 query['node'] = self.nodeIdentifier 397 398 return element 369 399 370 400 371 401 … … 388 418 @type sender: L{jid.JID} 389 419 """ 390 420 391 request = _DiscoRequest( self.xmlstream, NS_DISCO_INFO, nodeIdentifier)392 if sender is not None:393 request['from'] = unicode(sender)421 request = _DiscoRequest('info', nodeIdentifier) 422 request.sender = sender 423 request.recipient = entity 394 424 395 d = request.send(entity.full())425 d = self.request(request) 396 426 d.addCallback(lambda iq: DiscoInfo.fromElement(iq.query)) 397 427 return d 398 428 … … 411 441 @type sender: L{jid.JID} 412 442 """ 413 443 414 request = _DiscoRequest( self.xmlstream, NS_DISCO_ITEMS, nodeIdentifier)415 if sender is not None:416 request['from'] = unicode(sender)444 request = _DiscoRequest('items', nodeIdentifier) 445 request.sender = sender 446 request.recipient = entity 417 447 418 d = request.send(entity.full())448 d = self.request(request) 419 449 d.addCallback(lambda iq: DiscoItems.fromElement(iq.query)) 420 450 return d 421 451 … … 445 475 @param iq: The request iq element. 446 476 @type iq: L{Element<twisted.words.xish.domish.Element>} 447 477 """ 448 requestor = jid.internJID(iq["from"]) 449 target = jid.internJID(iq["to"]) 450 nodeIdentifier = iq.query.getAttribute("node", '') 478 request = _DiscoRequest.fromElement(iq) 451 479 452 480 def toResponse(info): 453 if nodeIdentifier and not info:481 if request.nodeIdentifier and not info: 454 482 raise error.StanzaError('item-not-found') 455 483 else: 456 484 response = DiscoInfo() 457 response.nodeIdentifier = nodeIdentifier485 response.nodeIdentifier = request.nodeIdentifier 458 486 459 487 for item in info: 460 488 response.append(item) 461 489 462 490 return response.toElement() 463 491 464 d = self.info(requestor, target, nodeIdentifier) 492 d = self.info(request.sender, request.recipient, 493 request.nodeIdentifier) 465 494 d.addCallback(toResponse) 466 495 return d 467 496 … … 473 502 @param iq: The request iq element. 474 503 @type iq: L{Element<twisted.words.xish.domish.Element>} 475 504 """ 476 requestor = jid.internJID(iq["from"]) 477 target = jid.internJID(iq["to"]) 478 nodeIdentifier = iq.query.getAttribute("node", '') 505 request = _DiscoRequest.fromElement(iq) 479 506 480 507 def toResponse(items): 481 508 response = DiscoItems() 482 response.nodeIdentifier = nodeIdentifier509 response.nodeIdentifier = request.nodeIdentifier 483 510 484 511 for item in items: 485 512 response.append(item) 486 513 487 514 return response.toElement() 488 515 489 d = self.items(requestor, target, nodeIdentifier) 516 d = self.items(request.sender, request.recipient, 517 request.nodeIdentifier) 490 518 d.addCallback(toResponse) 491 519 return d 492 520 -
wokkel/generic.py
diff -r ec507e96d825 wokkel/generic.py
a b 20 20 except ImportError: 21 21 from wokkel.compat import BootstrapMixin 22 22 23 from wokkel import disco24 23 from wokkel.iwokkel import IDisco 25 24 from wokkel.subprotocols import XMPPHandler 26 25 … … 120 119 info = set() 121 120 122 121 if not node: 122 from wokkel import disco 123 123 info.add(disco.DiscoFeature(NS_VERSION)) 124 124 125 125 return defer.succeed(info) … … 174 174 @type recipient: L{jid.JID} 175 175 """ 176 176 177 recipient = None 178 sender = None 177 179 stanzaKind = None 178 180 stanzaID = None 179 181 stanzaType = None -
wokkel/test/test_disco.py
diff -r ec507e96d825 wokkel/test/test_disco.py
a b 477 477 Set up stub and protocol for testing. 478 478 """ 479 479 self.stub = XmlStreamStub() 480 self.patch(XMPPHandler, 'request', self.request) 480 481 self.protocol = disco.DiscoClientProtocol() 481 self.protocol.xmlstream = self.stub.xmlstream 482 self.protocol.connectionInitialized() 482 483 484 def request(self, request): 485 element = request.toElement() 486 self.stub.xmlstream.send(element) 487 return defer.Deferred() 483 488 484 489 485 490 def test_requestItems(self): … … 511 516 element = query.addElement(u'item') 512 517 element[u'jid'] = u"test2.example.org" 513 518 514 self.stub.send(response)519 d.callback(response) 515 520 return d 516 521 517 522 … … 527 532 528 533 response = toResponse(iq, u'result') 529 534 response.addElement((NS_DISCO_ITEMS, u'query')) 530 self.stub.send(response)531 535 536 d.callback(response) 532 537 return d 533 538 534 539 … … 566 571 element = query.addElement(u"feature") 567 572 element[u'var'] = u'http://jabber.org/protocol/muc' 568 573 569 self.stub.send(response)574 d.callback(response) 570 575 return d 571 576 572 577 … … 575 580 A disco info request can be sent with an explicit sender address. 576 581 """ 577 582 d = self.protocol.requestInfo(JID(u'example.org'), 578 583 sender=JID(u'test.example.org')) 579 584 580 585 iq = self.stub.output[-1] 581 586 self.assertEqual(u'test.example.org', iq.getAttribute(u'from')) 582 587 583 588 response = toResponse(iq, u'result') 584 589 response.addElement((NS_DISCO_INFO, u'query')) 585 self.stub.send(response)586 590 591 d.callback(response) 587 592 return d 588 593 589 594 … … 676 681 return d 677 682 678 683 684 def test_onDiscoInfoWithNoFromAttribute(self): 685 """ 686 Disco info request without a from attribute has requestor None. 687 """ 688 xml = """<iq to='example.com' 689 type='get'> 690 <query xmlns='%s'/> 691 </iq>""" % NS_DISCO_INFO 692 693 def info(requestor, target, nodeIdentifier): 694 self.assertEqual(None, requestor) 695 696 return defer.succeed([ 697 disco.DiscoIdentity('dummy', 'generic', 'Generic Dummy Entity'), 698 disco.DiscoFeature('jabber:iq:version') 699 ]) 700 701 self.service.info = info 702 d = self.handleRequest(xml) 703 return d 704 705 706 def test_onDiscoInfoWithNoToAttribute(self): 707 """ 708 Disco info request without a to attribute has target None. 709 """ 710 xml = """<iq from='test@example.com' 711 type='get'> 712 <query xmlns='%s'/> 713 </iq>""" % NS_DISCO_INFO 714 715 def info(requestor, target, nodeIdentifier): 716 self.assertEqual(JID('test@example.com'), requestor) 717 718 return defer.succeed([ 719 disco.DiscoIdentity('dummy', 'generic', 'Generic Dummy Entity'), 720 disco.DiscoFeature('jabber:iq:version') 721 ]) 722 723 self.service.info = info 724 d = self.handleRequest(xml) 725 return d 726 727 679 728 def test_onDiscoInfoWithNode(self): 680 729 """ 681 730 An info request for a node should return it in the response.
Note: See TracBrowser
for help on using the repository browser.