Changes in [74:355afce3af27:83:255aae0cf8c5] in ralphm-patches
- Files:
-
- 20 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
async-observer.patch
r73 r79 1 1 # HG changeset patch 2 # Parent ed052dd5cb7a57faf1693f78457401fd820fdd792 # Parent 56607e5ddb53e3fafbecb41118bd220dea9310c7 3 3 4 4 diff --git a/wokkel/subprotocols.py b/wokkel/subprotocols.py … … 260 260 + observer(self, element) 261 261 + self.assertTrue(element.handled) 262 + self.assertEqual (1, len(self.output))262 + self.assertEquals(1, len(self.output)) 263 263 + exc = error.exceptionFromStanza(self.output[-1]) 264 + self.assertEqual (u'service-unavailable', exc.condition)264 + self.assertEquals(u'service-unavailable', exc.condition) 265 265 + 266 266 + … … 277 277 + observer(self, element) 278 278 + self.assertTrue(element.handled) 279 + self.assertEqual (1, len(self.output))279 + self.assertEquals(1, len(self.output)) 280 280 + exc = error.exceptionFromStanza(self.output[-1]) 281 + self.assertEqual (u'forbidden', exc.condition)281 + self.assertEquals(u'forbidden', exc.condition) 282 282 + 283 283 + … … 297 297 + observer(self, element) 298 298 + self.assertTrue(element.handled) 299 + self.assertEqual (1, len(self.output))299 + self.assertEquals(1, len(self.output)) 300 300 + exc = error.exceptionFromStanza(self.output[-1]) 301 + self.assertEqual (u'internal-server-error', exc.condition)302 + self.assertEqual (1, len(self.flushLoggedErrors()))301 + self.assertEquals(u'internal-server-error', exc.condition) 302 + self.assertEquals(1, len(self.flushLoggedErrors())) 303 303 + 304 304 + … … 318 318 + observer(self, element) 319 319 + self.assertTrue(element.handled) 320 + self.assertEqual (1, len(self.output))320 + self.assertEquals(1, len(self.output)) 321 321 + exc = error.exceptionFromStanza(self.output[-1]) 322 + self.assertEqual (u'internal-server-error', exc.condition)323 + self.assertEqual (1, len(self.flushLoggedErrors()))322 + self.assertEquals(u'internal-server-error', exc.condition) 323 + self.assertEquals(1, len(self.flushLoggedErrors())) 324 324 + 325 325 + … … 340 340 + observer(self, element) 341 341 + self.assertTrue(element.handled) 342 + self.assertEqual (0, len(self.output))343 + self.assertEqual (1, len(self.flushLoggedErrors()))342 + self.assertEquals(0, len(self.output)) 343 + self.assertEquals(1, len(self.flushLoggedErrors())) 344 344 + 345 345 + -
c2s_server_factory.patch
r72 r80 1 1 # HG changeset patch 2 2 # Parent 49294b2cf829414b42141731b5130d91474c0443 3 # Parent 0a68c01ed5b5f429eed343df521bc706fe88afd1 3 4 Add factory for accepting client connections. 4 5 … … 52 53 + Make sure each stanza has a sender address. 53 54 + """ 54 + if element.uri :55 + if element.uri != self.xmlstream.namespace: 55 56 + return 56 57 + … … 106 107 --- a/wokkel/generic.py 107 108 +++ b/wokkel/generic.py 108 @@ - 628,3 +628,65@@109 @@ -480,3 +480,64 @@ 109 110 standard full stop. 110 111 """ … … 135 136 + Called when the stream has been initialized. 136 137 + """ 137 + self.xmlstream.addObserver('/*[@xmlns="%s"]' %138 + self.xmlstream.namespace,139 + stripNamespace, priority=1)140 138 + self.xmlstream.addObserver('/*', self.onStanza, priority=-1) 141 139 + … … 157 155 + 158 156 + if (element.name not in ('iq', 'message', 'presence') or 159 + element.uri is not None):157 + element.uri != self.xmlstream.namespace): 160 158 + return 161 159 + 162 + if not element.getAttribute('to'): 160 + stanza = Stanza.fromElement(element) 161 + 162 + if not stanza.recipient: 163 163 + exc = error.StanzaError('service-unavailable') 164 + self.send(exc.toResponse( element))164 + self.send(exc.toResponse(stanza.element)) 165 165 + else: 166 + self.xmlstream.avatar.send( element)166 + self.xmlstream.avatar.send(stanza.element) 167 167 + 168 168 + … … 316 316 --- a/wokkel/test/test_generic.py 317 317 +++ b/wokkel/test/test_generic.py 318 @@ - 681,3 +681,105@@318 @@ -728,3 +728,91 @@ 319 319 name = u"example.com." 320 320 result = generic.prepareIDNName(name) … … 351 351 + self.protocol.connectionInitialized() 352 352 + 353 + element = domish.Element(( None, u'message'))353 + element = domish.Element((u'jabber:client', u'message')) 354 354 + element[u'to'] = u'other@example.org' 355 355 + self.stub.send(element) … … 365 365 + self.protocol.connectionInitialized() 366 366 + 367 + element = domish.Element(( None, u'message'))367 + element = domish.Element((u'jabber:client', u'message')) 368 368 + self.stub.send(element) 369 369 + 370 370 + self.assertEqual(0, len(self.avatar.sent)) 371 371 + self.assertEqual(1, len(self.stub.output)) 372 +373 +374 + def test_onStanzaClientNamespace(self):375 + """376 + Stanzas with an explicit namespace are delivered.377 + """378 + self.protocol.connectionInitialized()379 +380 + element = domish.Element(('jabber:client', u'message'))381 + element[u'to'] = u'other@example.org'382 + self.stub.send(element)383 +384 + self.assertEqual(1, len(self.avatar.sent))385 + self.assertEqual(0, len(self.stub.output))386 372 + 387 373 + -
c2s_stanza_handlers.patch
r73 r82 1 1 # HG changeset patch 2 2 # Parent 70ce9e97aa58780ac7f75a177fe8c0d2aaf1bfc6 3 # Parent 92b3f7089a61a8998999b67562917675732f8a4e 3 4 Add c2s protocol handlers for iq, message and presence stanzas. 4 5 … … 48 49 from wokkel.subprotocols import IQHandlerMixin 49 50 50 @@ -2031,3 +2031,41 8@@51 @@ -2031,3 +2031,411 @@ 51 52 d = self.sessionManager.probePresence(user) 52 53 d.addCallback(cb) … … 255 256 + def __init__(self, *args, **kwargs): 256 257 + super(FakeUserSession, self).__init__(*args, **kwargs) 257 + self.probePresenceCalls = 0258 258 + self.broadcastPresenceCalls = [] 259 259 + 260 260 + 261 + def probePresence(self): 262 + self.probePresenceCalls += 1 263 + 264 + 265 + def broadcastPresence(self, presence, available): 266 + self.broadcastPresenceCalls.append((presence, available)) 261 + def broadcastPresence(self, presence): 262 + self.broadcastPresenceCalls.append(presence) 267 263 + 268 264 + … … 317 313 + 318 314 + self.assertTrue(self.protocol.availableReceived(stanza)) 319 + self.assertEqual(1, self.session.probePresenceCalls)320 315 + self.assertEqual(1, len(self.session.broadcastPresenceCalls)) 321 + presence , available= self.session.broadcastPresenceCalls[-1]316 + presence = self.session.broadcastPresenceCalls[-1] 322 317 + self.assertIdentical(stanza, presence) 323 + self.assertTrue( available)318 + self.assertTrue(presence.available) 324 319 + 325 320 + … … 345 340 + 346 341 + self.assertTrue(self.protocol.unavailableReceived(stanza)) 347 + self.assertEqual(0, self.session.probePresenceCalls)348 342 + self.assertEqual(1, len(self.session.broadcastPresenceCalls)) 349 + presence , available= self.session.broadcastPresenceCalls[-1]343 + presence = self.session.broadcastPresenceCalls[-1] 350 344 + self.assertIdentical(stanza, presence) 351 + self.assertFalse( available)345 + self.assertFalse(presence.available) 352 346 + 353 347 + … … 530 524 531 525 @asyncObserver 532 @@ -16 89,3 +1697,246@@526 @@ -1693,3 +1701,240 @@ 533 527 presence = ProbePresence(recipient=entity, 534 528 sender=user.entity) … … 720 714 + else: 721 715 + session = self.xmlstream.avatar 722 + sendProbe = not session.presence 723 + 724 + session.broadcastPresence(presence, available=True) 725 + 726 + if sendProbe: 727 + session.probePresence() 728 + 716 + session.broadcastPresence(presence) 729 717 + return True 730 718 + … … 736 724 + else: 737 725 + session = self.xmlstream.avatar 738 + session.broadcastPresence(presence , available=False)726 + session.broadcastPresence(presence) 739 727 + return True 740 728 + -
listening-authenticator-stream-features.patch
r72 r79 1 1 # HG changeset patch 2 2 # Parent 840b96390047670c5209195300f902689c18b12f 3 # Parent 146ff13d66e54c535445adf4a19a3ef07a0a6f57 3 4 Add FeatureListeningAuthenticator. 4 5 … … 9 10 --- a/wokkel/generic.py 10 11 +++ b/wokkel/generic.py 11 @@ -1 0,7 +10,7 @@12 @@ -14,6 +14,7 @@ 12 13 from zope.interface import implements 13 14 14 15 from twisted.internet import defer, protocol 15 -from twisted.python import reflect 16 +from twisted.python import log, reflect 16 +from twisted.python import log 17 17 from twisted.python.deprecate import deprecated 18 18 from twisted.python.versions import Version 19 from twisted.words.protocols.jabber import error, jid,xmlstream20 @@ - 18,7 +18,7 @@19 from twisted.words.protocols.jabber import error, xmlstream 20 @@ -21,7 +22,7 @@ 21 21 from twisted.words.xish import domish, utility 22 22 from twisted.words.xish.xmlstream import BootstrapMixin … … 24 24 -from wokkel.iwokkel import IDisco 25 25 +from wokkel.iwokkel import IDisco, IReceivingInitializer 26 from wokkel.stanza import Stanza, ErrorStanza, Request 26 27 from wokkel.subprotocols import XMPPHandler 27 28 28 IQ_GET = '/iq[@type="get"]' 29 @@ -27,6 +27,8 @@ 29 @@ -31,6 +32,8 @@ 30 30 NS_VERSION = 'jabber:iq:version' 31 31 VERSION = IQ_GET + '/query[@xmlns="' + NS_VERSION + '"]' … … 36 36 """ 37 37 Parse serialized XML into a DOM structure. 38 @@ - 332,6 +334,290 @@38 @@ -180,6 +183,290 @@ 39 39 40 40 … … 414 414 415 415 NS_VERSION = 'jabber:iq:version' 416 @@ - 276,6 +281,334 @@416 @@ -300,6 +305,334 @@ 417 417 418 418 -
message-stanza.patch
r73 r75 1 1 # HG changeset patch 2 # Parent a94e14d79311f8efde3bd001ce4b5c8bafbb80942 # Parent 5df04f703f9024cd3a73d51117df93e7f56fdd7a 3 3 Parse message stanzas into Message objects. 4 4 … … 359 359 + 360 360 + self.onMessage(message.element) 361 + return True361 + return getattr(message, "handled", False) -
series
r73 r79 1 py3-iwokkel.patch #+py3 2 py3-subprotocols.patch #+py3 3 py3-generic.patch #+py3 4 py3-dataforms.patch #+py3 5 py3-test-helpers.patch #+py3 6 py3-disco.patch #+py3 7 py3-ping.patch #+py3 8 py3-compat.patch #+py3 9 py3-shim.patch #+py3 10 py3-pubsub.patch #+py3 11 py3-xmppim.patch #+py3 12 py3-muc.patch #+py3 13 py3-component.patch #+py3 14 py3-server.patch #+py3 15 py3-examples.patch #+py3 16 minimum-Twisted.patch #+py3 17 18 delay-keyerror.patch 19 1 20 async-observer.patch 21 stanza-module.patch 22 response-tracking.patch 23 2 24 message-stanza.patch 3 25 server-stream-manager.patch … … 6 28 listening-authenticator-stream-features.patch #+c2s 7 29 client_listen_authenticator.patch #+c2s 30 receiving_tls_initializer.patch 8 31 c2s_server_factory.patch #+c2s 9 32 -
server-stream-manager.patch
r74 r83 1 1 # HG changeset patch 2 # Parent 71082c22f73200a0b8b4b5c6e5d2773f9f68dd4d2 # Parent 3f3fe954b1975c2d9115e0fa8177ae7b28a708a8 3 3 Generalize StreamManager and add ServerStreamManager. 4 4 … … 56 56 --- a/wokkel/subprotocols.py 57 57 +++ b/wokkel/subprotocols.py 58 @@ -1 20,7 +120,7 @@58 @@ -118,7 +118,7 @@ 59 59 60 60 … … 65 65 Business logic representing a managed XMPP connection. 66 66 67 @@ -1 31,43 +131,39 @@67 @@ -129,43 +129,39 @@ 68 68 69 69 @ivar xmlstream: currently managed XML stream … … 116 116 from twisted.internet import reactor 117 117 self._reactor = reactor 118 @@ -19 3,7 +189,7 @@118 @@ -191,7 +187,7 @@ 119 119 handler.connectionInitialized() 120 120 … … 125 125 Called when the transport connection has been established. 126 126 127 @@ -2 11,13 +207,17 @@127 @@ -209,13 +205,17 @@ 128 128 xs.rawDataInFn = logDataIn 129 129 xs.rawDataOutFn = logDataOut … … 144 144 Called when the stream has been initialized. 145 145 146 @@ -2 40,21 +240,8 @@146 @@ -238,21 +238,8 @@ 147 147 e.connectionInitialized() 148 148 … … 167 167 Called when the stream has been closed. 168 168 169 @@ - 464,6 +451,60 @@169 @@ -379,6 +366,60 @@ 170 170 171 171 … … 298 298 --- a/wokkel/test/test_subprotocols.py 299 299 +++ b/wokkel/test/test_subprotocols.py 300 @@ -189,2 0+189,7 @@300 @@ -189,22 +189,7 @@ 301 301 302 302 … … 315 315 - self.xmlstream.transport = self.transport 316 316 - 317 - self.request = IQGetStanza() 317 - self.request = IQGetStanza(recipient=JID('other@example.org'), 318 - sender=JID('user@example.org')) 319 - 318 320 +class BaseStreamManagerTestsMixin(object): 319 321 … … 588 590 self.assertFailure(d, ConnectionDone) 589 591 self.assertFalse(self.clock.calls) 590 @@ -778,6 +753,5 6@@592 @@ -778,6 +753,58 @@ 591 593 592 594 … … 605 607 + self.xmlstream.transport = self.transport 606 608 + 607 + self.request = IQGetStanza() 609 + self.request = IQGetStanza(recipient=JID('other@example.org'), 610 + sender=JID('user@example.org')) 608 611 + 609 612 + … … 638 641 + self.streamManager.makeConnection) 639 642 + 640 + self.request = IQGetStanza() 643 + self.request = IQGetStanza(recipient=JID('other@example.org'), 644 + sender=JID('user@example.org')) 641 645 + 642 646 + -
session_manager.patch
r73 r82 1 1 # HG changeset patch 2 # Parent 60135baa4e422ab203c780c9093c374481b17a7a 2 # Parent d800a4363f602f6ff344181f0d20b5809157b0b1 3 # Parent 55eb3f11240d719a97e32eabf3ce03fe346cb8bf 3 4 4 5 diff --git a/wokkel/ewokkel.py b/wokkel/ewokkel.py … … 42 43 --- a/wokkel/generic.py 43 44 +++ b/wokkel/generic.py 44 @@ - 7,6 +7,8 @@45 Generic XMPP protocol helpers.46 """45 @@ -11,6 +11,8 @@ 46 'DeferredXmlStreamFactory', 'prepareIDNName', 47 'Stanza', 'Request', 'ErrorStanza'] 47 48 48 49 +import copy … … 51 52 52 53 from twisted.internet import defer, protocol 53 @@ - 66,6 +68,24 @@54 return r ootElement54 @@ -53,6 +55,24 @@ 55 return results and results[0] or None 55 56 56 57 … … 76 77 class FallbackHandler(XMPPHandler): 77 78 """ 78 @@ -168,10 +188,23 @@79 """80 Abstract representation of a stanza.81 82 + @ivar recipient: The receiving entity.83 + @type recipient: L{jid.JID}84 +85 @ivar sender: The sending entity.86 @type sender: L{jid.JID}87 - @ivar recipient: The receiving entity.88 - @type recipient: L{jid.JID}89 +90 + @ivar stanzaKind: One of C{'message'}, C{'presence'}, C{'iq'}.91 + @type stanzaKind: L{unicode}.92 +93 + @ivar stanzaID: The optional stanza identifier.94 + @type stanzaID: L{unicode}.95 +96 + @ivar stanzaType: The optional stanza type.97 + @type stanzaType: L{unicode}.98 +99 + @ivar element: The serialized XML of this stanza.100 + @type element: L{domish.Element}.101 """102 103 recipient = None104 @@ -179,6 +212,8 @@105 stanzaKind = None106 stanzaID = None107 stanzaType = None108 + element = None109 +110 111 def __init__(self, recipient=None, sender=None):112 self.recipient = recipient113 @@ -217,6 +252,7 @@114 self.sender = jid.internJID(element['from'])115 if element.hasAttribute('to'):116 self.recipient = jid.internJID(element['to'])117 + self.stanzaKind = element.name118 self.stanzaType = element.getAttribute('type')119 self.stanzaID = element.getAttribute('id')120 121 @@ -242,6 +278,7 @@122 123 def toElement(self):124 element = domish.Element((None, self.stanzaKind))125 + self.element = element126 if self.sender is not None:127 element['from'] = self.sender.full()128 if self.recipient is not None:129 79 diff --git a/wokkel/iwokkel.py b/wokkel/iwokkel.py 130 80 --- a/wokkel/iwokkel.py … … 297 247 + 298 248 + 299 + def test_getRoster (self):249 + def test_getRosterReceived(self): 300 250 + """ 301 251 + The returned roster is gotten from the session user. … … 305 255 + 306 256 + request = xmppim.RosterRequest() 307 + d = self.service.getRoster (request)257 + d = self.service.getRosterReceived(request) 308 258 + d.addCallback(gotRoster) 309 259 + return d 310 260 + 311 261 + 312 + def test_getRoster Interested(self):262 + def test_getRosterReceivedInterested(self): 313 263 + """ 314 264 + Requesting the roster marks the session as interested in roster pushes. … … 318 268 + 319 269 + request = xmppim.RosterRequest() 320 + d = self.service.getRoster (request)270 + d = self.service.getRosterReceived(request) 321 271 + d.addCallback(gotRoster) 322 272 + return d … … 724 674 + 725 675 + 726 + def getRoster (self, request):676 + def getRosterReceived(self, request): 727 677 + """ 728 678 + Return the roster of the user associated with this session. … … 737 687 """ 738 688 A message stanza. 739 @@ -1175,3 +1244,4 48@@689 @@ -1175,3 +1244,452 @@ 740 690 741 691 self.onMessage(message.element) 742 return True692 return getattr(message, "handled", False) 743 693 + 744 694 + … … 821 771 + 822 772 + 823 + def probePresence(self): 824 + self.user.probePresence(self) 825 + 826 + 827 + def broadcastPresence(self, presence, available): 828 + if available: 773 + def broadcastPresence(self, presence): 774 + doProbe = presence.available and not self.presence 775 + 776 + if presence.available: 829 777 + self.presence = presence 830 778 + else: 831 779 + self.presence = None 832 + # TODO: unset probeSent on user?833 + # TODO: save last unavailable presence?834 780 + 835 781 + self.user.broadcastPresence(presence) 782 + 783 + if doProbe: 784 + self.user.probePresence(self) 836 785 + 837 786 + … … 875 824 + 876 825 + def bindResource(self, session, resource): 826 + if not self.sessions: 827 + self.probeSent = False 828 + 877 829 + if resource is None: 878 830 + resource = randbytes.secureRandom(8).encode('hex') … … 952 904 + def deliverPresence(self, stanza): 953 905 + if not stanza.recipient.resource: 954 + # record906 + # TODO: record presence in self.contactPresences for future probes 955 907 + 956 908 + for session in self.sessions.itervalues(): … … 983 935 + Broadcast presence to all subscribed contacts and myself. 984 936 + """ 937 + # TODO: set probeSent to False when last session becomes unavailable 938 + # TODO: save last unavailable presence? 985 939 + subscribers = yield self.roster.getSubscribers() 986 940 + self.realm.server.multicast(presence, subscribers)
Note: See TracChangeset
for help on using the changeset viewer.