from twisted.internet.defer import Deferred
from twisted.internet.protocol import ClientFactory
try:
- from twisted.internet.ssl import ClientContextFactory
+ from twisted.internet.ssl import ClientContextFactory
except ImportError:
- print "You must install pycrypto and pyopenssl."
- raise
+ print "You must install pycrypto and pyopenssl."
+ raise
from twisted.python import failure, log
-from twisted.xish.domish import unescapeFromXml
# Compat stuff
from tlib import xmlw
PINGSPEED = 50.0
-DEBUGALL = False
+DEBUGALL = True
LINEDEBUG = False
MESSAGEDEBUG = False
MSNP2PDEBUG = False
self.screenName = screenName
self.specialMessage = specialMessage
self.message = message
- self.headers = {'MIME-Version' : '1.0', 'Content-Type' : 'text/plain'}
+ self.headers = {'MIME-Version' : '1.0', 'Content-Type' : 'text/plain; charset=UTF-8'}
self.length = length
self.readPos = 0
"""
return reduce(operator.add, [len(x[0]) + len(x[1]) + 4 for x in self.headers.items()]) + len(self.message) + 2
+ def delHeader(self, header):
+ """ delete the desired header """
+ if self.headers.has_key(header):
+ del self.headers[header]
+
def setHeader(self, header, value):
""" set the desired header """
self.headers[header] = value
self.setLineMode(extra)
return
except Exception, e:
- log.msg("Traceback - ERROR in checkMessage: " + str(e))
self.setLineMode(extra)
- return
+ raise
self.gotMessage(m)
self.setLineMode(extra)
p1 = lm.find("<psm>") + 5
p2 = lm.find("</psm>")
if p1 >= 0 and p2 >= 0:
- personal = unescapeFromXml(message.message[p1:p2])
+ personal = xmlw.unescapeFromXml(message.message[p1:p2])
msnContact.personal = personal
self.contactPersonalChanged(message.userHandle, personal)
else:
if not message.getHeader("P2P-Dest") == self.userHandle: return
packet = message.message
binaryFields = BinaryFields(packet=packet)
- if binaryFields[0] != 0:
+ if binaryFields[5] == BinaryFields.BYEGOT:
+ pass # Ignore the ACKs to SLP messages
+ elif binaryFields[0] != 0:
slpLink = self.slpLinks.get(binaryFields[0])
if not slpLink:
# Link has been killed. Ignore
return
if slpLink.remoteUser == message.userHandle:
slpLink.handlePacket(packet)
- if binaryFields[5] == BinaryFields.ACK or binaryFields[5] == BinaryFields.BYEGOT:
+ elif binaryFields[5] == BinaryFields.ACK:
pass # Ignore the ACKs to SLP messages
else:
slpMessage = MSNSLPMessage(packet)
else: id, d = self._createIDMapping()
if message.length == 0: message.length = message._calcMessageLen()
self.sendLine("MSG %s %s %s" % (id, message.ack, message.length))
- # apparently order matters with at least MIME-Version and Content-Type
- self.sendLine('MIME-Version: %s' % message.getHeader('MIME-Version'))
- self.sendLine('Content-Type: %s' % message.getHeader('Content-Type'))
+ # Apparently order matters with these
+ orderMatters = ("MIME-Version", "Content-Type", "Message-ID")
+ for header in orderMatters:
+ if message.hasHeader(header):
+ self.sendLine("%s: %s" % (header, message.getHeader(header)))
# send the rest of the headers
- for header in [h for h in message.headers.items() if h[0].lower() not in ('mime-version','content-type')]:
+ for header in [h for h in message.headers.items() if h[0] not in orderMatters]:
self.sendLine("%s: %s" % (header[0], header[1]))
self.transport.write("\r\n")
self.transport.write(message.message)
self.seqID = SeqID()
def killLink(self):
+ if MSNP2PDEBUG: log.msg("killLink")
def kill():
+ if MSNP2PDEBUG: log.msg("killLink - kill()")
if not self.switchboard: return
del self.switchboard.slpLinks[self.sessionID]
self.switchboard = None
else:
if slpMessage.status == "603":
self.acceptDeferred.callback((False,))
- # SLPLink is over due to decline, error or BYE
+ if MSNP2PDEBUG: log.msg("SLPLink is over due to decline, error or BYE")
self.killLink()
def wait_data_ack(self, packet):
self.handlePacket = lambda packet: None
def handleSLPMessage(self, slpMessage):
- self.killLink() # BYE or error
+ if MSNP2PDEBUG: log.msg("BYE or error")
+ self.killLink()
def close(self):
SLPLink_Send.close(self)
def reject(self):
# Send a 603 decline
+ if not self.switchboard: return
self.sendSLPMessage("603", "application/x-msnmsgr-sessionreqbody", {"SessionID":self.sessionID}, branch=self.initialBranch)
self.killLink()
def accept(self, consumer):
FileReceive.accept(self, consumer)
+ if not self.switchboard: return
self.sendSLPMessage("200", "application/x-msnmsgr-sessionreqbody", {"SessionID":self.sessionID}, branch=self.initialBranch)
+ self.handlePacket = self.wait_data # Moved here because sometimes the second INVITE seems to be skipped
def handleSLPMessage(self, slpMessage):
if slpMessage.method == "INVITE": # The second invite
"Listening" : "false",\
"Hashed-Nonce": "{00000000-0000-0000-0000-000000000000}"}
self.sendSLPMessage("200", "application/x-msnmsgr-transrespbody", data, branch=slpMessage.branch)
- self.handlePacket = self.wait_data
+# self.handlePacket = self.wait_data # Moved up
else:
- self.killLink() # It's either a BYE or an error
+ if MSNP2PDEBUG: log.msg("It's either a BYE or an error")
+ self.killLink()
# FIXME, do some error handling if it was an error
def doFinished(self):
if slpMessage.status == "200":
self.handlePacket = self.wait_dataprep
else:
- # SLPLink is over due to error or BYE
+ if MSNP2PDEBUG: log.msg("SLPLink is over due to error or BYE")
self.killLink()
def doFinished(self):