[8] | 1 | # -*- test-case-name: wokkel.test.test_compat -*- |
---|
| 2 | # |
---|
[34] | 3 | # Copyright (c) 2001-2008 Twisted Matrix Laboratories. |
---|
[8] | 4 | # See LICENSE for details. |
---|
| 5 | |
---|
[34] | 6 | from twisted.internet import protocol |
---|
| 7 | from twisted.words.protocols.jabber import xmlstream |
---|
[8] | 8 | from twisted.words.xish import domish |
---|
| 9 | |
---|
| 10 | def toResponse(stanza, stanzaType=None): |
---|
| 11 | """ |
---|
| 12 | Create a response stanza from another stanza. |
---|
| 13 | |
---|
| 14 | This takes the addressing and id attributes from a stanza to create a (new, |
---|
| 15 | empty) response stanza. The addressing attributes are swapped and the id |
---|
| 16 | copied. Optionally, the stanza type of the response can be specified. |
---|
| 17 | |
---|
| 18 | @param stanza: the original stanza |
---|
| 19 | @type stanza: L{domish.Element} |
---|
| 20 | @param stanzaType: optional response stanza type |
---|
| 21 | @type stanzaType: C{str} |
---|
| 22 | @return: the response stanza. |
---|
| 23 | @rtype: L{domish.Element} |
---|
| 24 | """ |
---|
| 25 | |
---|
| 26 | toAddr = stanza.getAttribute('from') |
---|
| 27 | fromAddr = stanza.getAttribute('to') |
---|
| 28 | stanzaID = stanza.getAttribute('id') |
---|
| 29 | |
---|
| 30 | response = domish.Element((None, stanza.name)) |
---|
| 31 | if toAddr: |
---|
| 32 | response['to'] = toAddr |
---|
| 33 | if fromAddr: |
---|
| 34 | response['from'] = fromAddr |
---|
| 35 | if stanzaID: |
---|
| 36 | response['id'] = stanzaID |
---|
[37] | 37 | if stanzaType: |
---|
[8] | 38 | response['type'] = stanzaType |
---|
| 39 | |
---|
| 40 | return response |
---|
| 41 | |
---|
| 42 | |
---|
[34] | 43 | |
---|
| 44 | class BootstrapMixin(object): |
---|
[8] | 45 | """ |
---|
[34] | 46 | XmlStream factory mixin to install bootstrap event observers. |
---|
[8] | 47 | |
---|
[34] | 48 | This mixin is for factories providing |
---|
| 49 | L{IProtocolFactory<twisted.internet.interfaces.IProtocolFactory>} to make |
---|
| 50 | sure bootstrap event observers are set up on protocols, before incoming |
---|
| 51 | data is processed. Such protocols typically derive from |
---|
| 52 | L{utility.EventDispatcher}, like L{XmlStream}. |
---|
[8] | 53 | |
---|
[34] | 54 | You can set up bootstrap event observers using C{addBootstrap}. The |
---|
| 55 | C{event} and C{fn} parameters correspond with the C{event} and |
---|
[8] | 56 | C{observerfn} arguments to L{utility.EventDispatcher.addObserver}. |
---|
[34] | 57 | |
---|
| 58 | @ivar bootstraps: The list of registered bootstrap event observers. |
---|
| 59 | @type bootstrap: C{list} |
---|
[8] | 60 | """ |
---|
| 61 | |
---|
[34] | 62 | def __init__(self): |
---|
[8] | 63 | self.bootstraps = [] |
---|
| 64 | |
---|
[34] | 65 | |
---|
| 66 | def installBootstraps(self, dispatcher): |
---|
[8] | 67 | """ |
---|
[34] | 68 | Install registered bootstrap observers. |
---|
[8] | 69 | |
---|
[34] | 70 | @param dispatcher: Event dispatcher to add the observers to. |
---|
| 71 | @type dispatcher: L{utility.EventDispatcher} |
---|
[8] | 72 | """ |
---|
| 73 | for event, fn in self.bootstraps: |
---|
[34] | 74 | dispatcher.addObserver(event, fn) |
---|
| 75 | |
---|
[8] | 76 | |
---|
| 77 | def addBootstrap(self, event, fn): |
---|
| 78 | """ |
---|
| 79 | Add a bootstrap event handler. |
---|
| 80 | """ |
---|
| 81 | self.bootstraps.append((event, fn)) |
---|
| 82 | |
---|
[34] | 83 | |
---|
[8] | 84 | def removeBootstrap(self, event, fn): |
---|
| 85 | """ |
---|
| 86 | Remove a bootstrap event handler. |
---|
| 87 | """ |
---|
| 88 | self.bootstraps.remove((event, fn)) |
---|
[34] | 89 | |
---|
| 90 | |
---|
| 91 | |
---|
| 92 | class XmlStreamServerFactory(BootstrapMixin, |
---|
| 93 | protocol.ServerFactory): |
---|
| 94 | """ |
---|
| 95 | Factory for Jabber XmlStream objects as a server. |
---|
| 96 | |
---|
| 97 | @since: 8.2. |
---|
| 98 | @ivar authenticatorFactory: Factory callable that takes no arguments, to |
---|
| 99 | create a fresh authenticator to be associated |
---|
| 100 | with the XmlStream. |
---|
| 101 | """ |
---|
| 102 | |
---|
| 103 | protocol = xmlstream.XmlStream |
---|
| 104 | |
---|
| 105 | def __init__(self, authenticatorFactory): |
---|
[38] | 106 | BootstrapMixin.__init__(self) |
---|
[34] | 107 | self.authenticatorFactory = authenticatorFactory |
---|
| 108 | |
---|
| 109 | |
---|
| 110 | def buildProtocol(self, addr): |
---|
| 111 | """ |
---|
| 112 | Create an instance of XmlStream. |
---|
| 113 | |
---|
| 114 | A new authenticator instance will be created and passed to the new |
---|
| 115 | XmlStream. Registered bootstrap event observers are installed as well. |
---|
| 116 | """ |
---|
| 117 | authenticator = self.authenticatorFactory() |
---|
| 118 | xs = self.protocol(authenticator) |
---|
| 119 | xs.factory = self |
---|
| 120 | self.installBootstraps(xs) |
---|
| 121 | return xs |
---|