[15] | 1 | diff -r 5a5840e066fb -r 86b4a357ecae wokkel/server.py |
---|
| 2 | --- a/wokkel/server.py Fri Jun 12 15:32:06 2009 +0000 |
---|
| 3 | +++ b/wokkel/server.py Mon Jul 06 08:33:11 2009 +0200 |
---|
| 4 | @@ -557,7 +557,108 @@ |
---|
| 5 | else: |
---|
| 6 | self.service.dispatch(xs, element) |
---|
| 7 | |
---|
| 8 | +class XMPPS2SClientFactory(BootstrapMixin, protocol.ClientFactory): |
---|
| 9 | |
---|
| 10 | + protocol = xmlstream.XmlStream |
---|
| 11 | + |
---|
| 12 | + def __init__(self, thisHost, otherHost, secret) |
---|
| 13 | + BootstrapMixin.__init__(self) |
---|
| 14 | + |
---|
| 15 | + self.thisHost = thisHost |
---|
| 16 | + self.otherHost = otherHost |
---|
| 17 | + |
---|
| 18 | + self.authenticator = XMPPServerConnectAuthenticator(self.thisHost, |
---|
| 19 | + self.otherHost, |
---|
| 20 | + secret) |
---|
| 21 | + |
---|
| 22 | + |
---|
| 23 | + def buildProtocol(self, addr): |
---|
| 24 | + """ |
---|
| 25 | + Create an instance of XmlStream. |
---|
| 26 | + |
---|
| 27 | + A new authenticator instance will be created and passed to the new |
---|
| 28 | + XmlStream. Registered bootstrap event observers are installed as well. |
---|
| 29 | + """ |
---|
| 30 | + xs = self.protocol(self.authenticator) |
---|
| 31 | + xs.factory = self |
---|
| 32 | + self.installBootstraps(xs) |
---|
| 33 | + return xs |
---|
| 34 | + |
---|
| 35 | + |
---|
| 36 | + def startedConnecting(self, connector): |
---|
| 37 | + """ |
---|
| 38 | + Called when a connection has been started. |
---|
| 39 | + """ |
---|
| 40 | + |
---|
| 41 | + |
---|
| 42 | + def clientConnectionFailed(self, connector, reason): |
---|
| 43 | + """ |
---|
| 44 | + Called when a connection has failed to connect. |
---|
| 45 | + """ |
---|
| 46 | + |
---|
| 47 | + |
---|
| 48 | + def clientConnectionLost(self, connector, reason): |
---|
| 49 | + """ |
---|
| 50 | + Called when an established connection is lost. |
---|
| 51 | + """ |
---|
| 52 | + |
---|
| 53 | + |
---|
| 54 | +class StreamController(modal.Modal): |
---|
| 55 | + |
---|
| 56 | + initialMode = 'disconnected' |
---|
| 57 | + |
---|
| 58 | + def __init__(self, factory): |
---|
| 59 | + factory.addBootstrap(xmlstream.STREAM_AUTHD_EVENT, |
---|
| 60 | + self.streamValid) |
---|
| 61 | + factory.addBootstrap(xmlstream.INIT_FAILED_EVENT, |
---|
| 62 | + self.streamInvalid) |
---|
| 63 | + |
---|
| 64 | + |
---|
| 65 | + |
---|
| 66 | + self.xmlstream = None |
---|
| 67 | + |
---|
| 68 | + |
---|
| 69 | + class connecting(modal.mode): |
---|
| 70 | + def __enter__(self): |
---|
| 71 | + self.pending = [] |
---|
| 72 | + |
---|
| 73 | + def send(self, obj): |
---|
| 74 | + self.pending.append(obj) |
---|
| 75 | + |
---|
| 76 | + |
---|
| 77 | + class connected(modal.mode): |
---|
| 78 | + def send(self, obj): |
---|
| 79 | + self.xmlstream.send(obj) |
---|
| 80 | + |
---|
| 81 | + |
---|
| 82 | + class disconnected(modal.mode): |
---|
| 83 | + pass |
---|
| 84 | + |
---|
| 85 | + |
---|
| 86 | + def streamValid(self, xs): |
---|
| 87 | + """ |
---|
| 88 | + Called when the stream was validated. |
---|
| 89 | + """ |
---|
| 90 | + connecting = False |
---|
| 91 | + self.xmlstream = xs |
---|
| 92 | + |
---|
| 93 | + |
---|
| 94 | + def streamInvalid(self, xs): |
---|
| 95 | + """ |
---|
| 96 | + Called when the stream was not validated. |
---|
| 97 | + """ |
---|
| 98 | + connecting = False |
---|
| 99 | + |
---|
| 100 | + |
---|
| 101 | + def send(self, obj): |
---|
| 102 | + """ |
---|
| 103 | + Send or queue obj. |
---|
| 104 | + """ |
---|
| 105 | + if self.xmlstream is None: |
---|
| 106 | + # queue up |
---|
| 107 | + |
---|
| 108 | + else: |
---|
| 109 | + # send immediately |
---|
| 110 | |
---|
| 111 | class ServerService(object): |
---|
| 112 | """ |
---|
| 113 | @@ -601,12 +702,6 @@ |
---|
| 114 | xs.addObserver(xmlstream.STREAM_END_EVENT, |
---|
| 115 | lambda _: self.outgoingDisconnected(xs)) |
---|
| 116 | |
---|
| 117 | - if (thisHost, otherHost) in self._outgoingQueues: |
---|
| 118 | - for element in self._outgoingQueues[thisHost, otherHost]: |
---|
| 119 | - xs.send(element) |
---|
| 120 | - del self._outgoingQueues[thisHost, otherHost] |
---|
| 121 | - |
---|
| 122 | - |
---|
| 123 | def outgoingDisconnected(self, xs): |
---|
| 124 | thisHost = xs.thisEntity.host |
---|
| 125 | otherHost = xs.otherEntity.host |
---|
| 126 | @@ -622,24 +717,26 @@ |
---|
| 127 | Initiate an outgoing XMPP server-to-server connection. |
---|
| 128 | """ |
---|
| 129 | |
---|
| 130 | - def resetConnecting(_): |
---|
| 131 | + def resetConnecting(result): |
---|
| 132 | self._outgoingConnecting.remove((thisHost, otherHost)) |
---|
| 133 | + return result |
---|
| 134 | |
---|
| 135 | - if (thisHost, otherHost) in self._outgoingConnecting: |
---|
| 136 | - return |
---|
| 137 | + #if (thisHost, otherHost) in self._outgoingConnecting: |
---|
| 138 | + # return |
---|
| 139 | |
---|
| 140 | authenticator = XMPPServerConnectAuthenticator(thisHost, |
---|
| 141 | otherHost, |
---|
| 142 | self.secret) |
---|
| 143 | factory = DeferredS2SClientFactory(authenticator) |
---|
| 144 | - factory.addBootstrap(xmlstream.STREAM_AUTHD_EVENT, |
---|
| 145 | - self.outgoingInitialized) |
---|
| 146 | + #factory.addBootstrap(xmlstream.STREAM_AUTHD_EVENT, |
---|
| 147 | + # self.outgoingInitialized) |
---|
| 148 | factory.logTraffic = self.logTraffic |
---|
| 149 | |
---|
| 150 | self._outgoingConnecting.add((thisHost, otherHost)) |
---|
| 151 | |
---|
| 152 | d = initiateS2S(factory) |
---|
| 153 | d.addBoth(resetConnecting) |
---|
| 154 | + d.addCallback(self.outgoingInitialized) |
---|
| 155 | return d |
---|
| 156 | |
---|
| 157 | |
---|
| 158 | diff -r 5a5840e066fb -r 86b4a357ecae wokkel/test/test_server.py |
---|
| 159 | --- a/wokkel/test/test_server.py Fri Jun 12 15:32:06 2009 +0000 |
---|
| 160 | +++ b/wokkel/test/test_server.py Mon Jul 06 08:33:11 2009 +0200 |
---|
| 161 | @@ -448,3 +448,38 @@ |
---|
| 162 | self.service.dispatch(self.xmlstream, stanza) |
---|
| 163 | |
---|
| 164 | self.assertEqual(1, len(errors)) |
---|
| 165 | + |
---|
| 166 | + |
---|
| 167 | + def test_send(self): |
---|
| 168 | + print |
---|
| 169 | + factories = [] |
---|
| 170 | + inits = [] |
---|
| 171 | + |
---|
| 172 | + def initiateS2S(factory): |
---|
| 173 | + factories.append(factory) |
---|
| 174 | + return factory.deferred |
---|
| 175 | + |
---|
| 176 | + self.patch(server, 'initiateS2S', initiateS2S) |
---|
| 177 | + #self.service.outgoingInitialized = lambda xs: inits.append(xs) |
---|
| 178 | + stanza = domish.Element((None, "presence")) |
---|
| 179 | + stanza['to'] = 'other@example.com' |
---|
| 180 | + stanza['from'] = 'user@example.org' |
---|
| 181 | + |
---|
| 182 | + print "Sending first stanza" |
---|
| 183 | + self.service.send(stanza) |
---|
| 184 | + print "Output after first send", self.output |
---|
| 185 | + xs = factories[-1].buildProtocol(None) |
---|
| 186 | + xs.thisEntity = jid.JID('example.org') |
---|
| 187 | + xs.otherEntity = jid.JID('example.com') |
---|
| 188 | + xs.serial = 1 |
---|
| 189 | + xs.send = self.output.append |
---|
| 190 | + |
---|
| 191 | + print "Authenticating" |
---|
| 192 | + xs.dispatch(xs, xmlstream.STREAM_AUTHD_EVENT) |
---|
| 193 | + print "Output after authd", self.output |
---|
| 194 | + |
---|
| 195 | + print "Sending second stanza" |
---|
| 196 | + self.service.send(stanza) |
---|
| 197 | + print "Output after second send", self.output |
---|
| 198 | + |
---|
| 199 | + |
---|