Changeset 69:cc2fc0173c4d in ralphm-patches
- Timestamp:
- Oct 27, 2012, 1:55:56 AM (10 years ago)
- Branch:
- default
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
c2s_stanza_handlers.patch
r67 r69 1 1 # HG changeset patch 2 # Parent 0010b81dc2caab48246d1e3d3d4f555af549688c2 # Parent eb898b91399636715feb9530c3d3e0090628926a 3 3 Add c2s protocol handlers for iq, message and presence stanzas. 4 4 … … 95 95 + 96 96 +sessionManager.connectionManager = c2sFactory 97 diff --git a/wokkel/client.py b/wokkel/client.py 98 --- a/wokkel/client.py 99 +++ b/wokkel/client.py 100 @@ -589,13 +589,38 @@ 101 return defer.succeed(entity) 102 103 104 + def lookupSessions(self, entity): 105 + """ 106 + Return all sessions for a user. 107 + 108 + @param entity: Entity to retrieve sessions for. This the resource part 109 + will be ignored. 110 + @type entity: L{JID<twisted.words.protocols.jabber.jid.JID>} 111 + 112 + @return: Mapping of sessions keyed by resource. 113 + @rtype: C{dict} 114 + """ 115 + localpart = entity.user 116 + 117 + try: 118 + return self.sessions[localpart] 119 + except: 120 + return {} 121 + 122 + 123 def lookupSession(self, entity): 124 - localpart = entity.user 125 - resource = entity.resource 126 + """ 127 + Return the session for a particular resource of an entity. 128 129 - userSessions = self.sessions[localpart] 130 - session = userSessions[resource] 131 - return session 132 + @param entity: Entity to retrieve sessions for. 133 + @type entity: L{JID<twisted.words.protocols.jabber.jid.JID>} 134 + 135 + @return: C{UserSession}. 136 + """ 137 + 138 + userSessions = self.lookupSessions(entity) 139 + return userSessions[entity.resource] 140 + 141 142 143 def unbindResource(self, session, reason=None): 97 144 diff --git a/wokkel/test/test_xmppim.py b/wokkel/test/test_xmppim.py 98 145 --- a/wokkel/test/test_xmppim.py … … 241 288 242 289 243 @@ -1067,6 +1075,440 @@ 290 @@ -1035,6 +1043,13 @@ 291 return element 292 293 294 + @classmethod 295 + def fromElement(cls, element): 296 + stanza = super(Message, cls).fromElement(element) 297 + stanza.stanzaType = stanza.stanzaType or 'normal' 298 + return stanza 299 + 300 + 301 302 class MessageProtocol(XMPPHandler): 303 """ 304 @@ -1067,6 +1082,441 @@ 244 305 245 306 … … 270 331 + return 271 332 + 272 + try: 273 + recipient = JID(iq['to']) 274 + except KeyError: 333 + stanza = Stanza.fromElement(iq) 334 + recipient = stanza.recipient 335 + 336 + if not recipient: 337 + # This stanza doesn't have a recipient, ignore it. 275 338 + return 276 + 277 + if not recipient.user: 339 + elif not recipient.user: 278 340 + # This is not for an account, ignore it 279 341 + return … … 285 347 + return 286 348 + 287 + userSessions = self.sessionManager.sessions.get(recipient.user, 288 + {}) 349 + userSessions = self.sessionManager.lookupSessions(recipient) 289 350 + if recipient.resource in userSessions: 290 351 + self.sessionManager.deliverStanza(iq, recipient) … … 292 353 + # Full JID without connected resource, return error 293 354 + exc = error.StanzaError('service-unavailable') 294 + if iq['type']in ('result', 'error'):355 + if stanza.stanzaType in ('result', 'error'): 295 356 + log.err(exc, 'Could not deliver IQ response') 296 357 + else: … … 312 373 + 313 374 + 314 + def onMessage(self, message):375 + def onMessage(self, element): 315 376 + """ 316 377 + Handler for message stanzas to user accounts. 317 378 + """ 318 379 + 319 + if message.handled:380 + if element.handled: 320 381 + return 321 382 + 383 + message = Message.fromElement(element) 384 + recipient = message.recipient 385 + stanzaType = message.stanzaType or 'normal' 386 + 322 387 + try: 323 + recipient = JID(message['to']) 324 + except KeyError: 325 + return 326 + 327 + stanzaType = message.getAttribute('type', 'normal') 328 + 329 + try: 388 + if not recipient: 389 + # This stanza doesn't have a recipient, ignore it. 390 + return 330 391 + if not recipient.user: 331 392 + # This is not for an account, ignore it … … 335 396 + return 336 397 + elif recipient.resource: 337 + userSessions = self.sessionManager.sessions.get(recipient.user, 338 + {}) 398 + userSessions = self.sessionManager.lookupSessions(recipient) 339 399 + if recipient.resource in userSessions: 340 + self.sessionManager.deliverStanza( message, recipient)400 + self.sessionManager.deliverStanza(element, recipient) 341 401 + else: 342 402 + if stanzaType in ('normal', 'chat', 'headline'): 343 + self.onMessageBareJID(message , recipient.userhostJID())403 + self.onMessageBareJID(message) 344 404 + elif stanzaType == 'error': 345 405 + log.msg("Dropping message to unconnected resource %r" % … … 348 408 + raise error.StanzaError('service-unavailable') 349 409 + else: 350 + self.onMessageBareJID(message , recipient)410 + self.onMessageBareJID(message) 351 411 + except error.StanzaError, exc: 352 412 + if stanzaType == 'error': 353 413 + log.err(exc, "Undeliverable error") 354 414 + else: 355 + self.send(exc.toResponse(message)) 356 + 357 + message.handled = True 358 + 359 + 360 + def onMessageBareJID(self, message, bareJID): 361 + stanzaType = message.getAttribute('type', 'normal') 362 + 363 + userSessions = self.sessionManager.sessions.get(bareJID.user, {}) 415 + self.send(exc.toResponse(element)) 416 + 417 + element.handled = True 418 + 419 + 420 + def onMessageBareJID(self, message): 421 + userSessions = self.sessionManager.lookupSessions(message.recipient) 364 422 + 365 423 + recipients = set() 366 424 + 367 + if stanzaType == 'headline':368 + for session in userSessions :425 + if message.stanzaType == 'headline': 426 + for session in userSessions.itervalues(): 369 427 + if session.presence.priority >= 0: 370 428 + recipients.add(session.entity) 371 + elif stanzaType in ('chat', 'normal'):429 + elif message.stanzaType in ('chat', 'normal'): 372 430 + priorities = {} 373 431 + for session in userSessions.itervalues(): … … 377 435 + if priority >= 0: 378 436 + priorities.setdefault(priority, set()).add(session.entity) 437 + if priorities: 379 438 + maxPriority = max(priorities.keys()) 380 439 + recipients.update(priorities[maxPriority]) 381 + elif stanzaType == 'groupchat':440 + elif message.stanzaType == 'groupchat': 382 441 + raise error.StanzaError('service-unavailable') 383 442 + 384 443 + if recipients: 385 444 + for recipient in recipients: 386 + self.sessionManager.deliverStanza(message , recipient)387 + elif stanzaType in ('chat', 'normal'):445 + self.sessionManager.deliverStanza(message.element, recipient) 446 + elif message.stanzaType in ('chat', 'normal'): 388 447 + raise error.StanzaError('service-unavailable') 389 448 + else: 390 449 + # silently discard 391 + log.msg("Discarding message to %r" % message ['to'])450 + log.msg("Discarding message to %r" % message.recipient) 392 451 + 393 452 + … … 535 594 + # save presence 536 595 + self.presences[user][resource] = presence 537 + self.sessionManager.sessions[user][resource].presence = presence 596 + session = self.sessionManager.lookupSession(fromJID) 597 + session.presence = presence 538 598 + 539 599 + return True … … 556 616 + toJID = presence.recipient 557 617 + 558 + if toJID.user not in self.roster: 618 + if not toJID.user: 619 + # This is not for an account, ignore it. 559 620 + return False 560 + 561 + if toJID.user in self.presences: 621 + elif toJID.user not in self.roster: 622 + # This is not for a known account, ignore it. 623 + return False 624 + elif toJID.user not in self.presences: 625 + # No available resource, drop it. 626 + return True 627 + else: 562 628 + for resource in self.presences[toJID.user]: 563 629 + resourceJID = JID(tuple=(toJID.user, … … 566 632 + self.sessionManager.deliverStanza(presence.element, resourceJID) 567 633 + self.remotePresences[toJID.user][fromJID] = presence 568 + else: 569 + # no such user or no available resource, ignore this stanza 570 + pass 571 + 572 + return True 634 + return True 573 635 + 574 636 +
Note: See TracChangeset
for help on using the changeset viewer.