]> code.delx.au - pymsnt/blobdiff - src/ft.py
Sensible messages are now sent to both participants if a file is rejected for being...
[pymsnt] / src / ft.py
index 8ffd2c66598461e51d310a8db19316dacdeec68b..756d3bfa16dd08979ffc4bc29c3b1f6b2a9291bf 100644 (file)
--- a/src/ft.py
+++ b/src/ft.py
@@ -1,10 +1,12 @@
 # Copyright 2005 James Bunton <james@delx.cjb.net>
 # Licensed for distribution under the GPL version 2, check COPYING for details
 
+from tlib.throttle import Throttler
 from tlib.xmlw import Element
 from twisted.internet import protocol
 
 import disco
+import lang
 from debug import LogEvent, INFO, WARN, ERROR
 import config
 import utils
@@ -13,24 +15,58 @@ import random
 import sys
 
 
+def doRateLimit(setConsumer, consumer):
+       try:
+               rateLimit = int(config.ftRateLimit)
+       except ValueError:
+               rateLimit = 0
+       if rateLimit > 0:
+               throttler = Throttler(consumer, rateLimit)
+               setConsumer(throttler)
+       else:
+               setConsumer(consumer)
+
+def checkSizeOk(size):
+       try:
+               size = int(size)
+               limit = int(config.ftSizeLimit)
+       except ValueError:
+               return False
+       if limit == 0:
+               return True
+       return limit > size
+
 ###########
 # Sending #
 ###########
 
 class FTSend:
        """ For file transfers going from Jabber to MSN. """
-       def __init__(self, startTransfer, cancelTransfer, filename, filesize):
+       def __init__(self, session, to, startTransfer, cancelTransfer, filename, filesize):
                self.startTransfer = startTransfer
                self.cancelTransfer = cancelTransfer
                self.filename = filename
                self.filesize = filesize
+               if not checkSizeOk(self.filesize):
+                       LogEvent(INFO, session.jabberID, "File too large.")
+                       text = lang.get(session.lang).msnFtSizeRejected % (self.filename, config.ftSizeLimit, config.website)
+                       session.legacycon.sendMessage(to, "", text, True)
+                       session.sendMessage(to=session.jabberID, fro=to, body=text)
+                       self.reject()
+                       return
+
+               session.legacycon.sendFile(to, self)
        
        def accept(self, legacyFileSend):
-               self.startTransfer(legacyFileSend)
+               doRateLimit(self.startTransfer, legacyFileSend)
+               self.cleanup()
        
        def reject(self):
-               del self.startTransfer
                self.cancelTransfer()
+               self.cleanup()
+       
+       def cleanup(self):
+               del self.startTransfer, self.cancelTransfer
 
 
 try:
@@ -98,12 +134,19 @@ class FTReceive:
        """
 
        def __init__(self, session, senderJID, legacyftp):
+               if not checkSizeOk(legacyftp.filesize):
+                       LogEvent(INFO, session.jabberID, "File too large.")
+                       legacyftp.reject()
+                       text = lang.get(session.lang).msnFtSizeRejected % (legacyftp.filename, config.ftSizeLimit, config.website)
+                       session.legacycon.sendMessage(senderJID, "", text, False)
+                       session.sendMessage(to=session.jabberID, fro=senderJID, body=text)
+                       return
                self.session = session
                self.toJID = self.session.jabberID + "/" + self.session.highestResource()
                self.senderJID = senderJID
                self.ident = (self.toJID, self.senderJID)
                self.legacyftp = legacyftp
-               LogEvent(INFO)
+               LogEvent(INFO, session.jabberID)
                self.checkSupport()
        
        def checkSupport(self):
@@ -128,7 +171,12 @@ class FTReceive:
 
                def discoFail(err=None):
                        LogEvent(INFO, self.ident, str(err))
-                       self.messageOobMode()
+                       if hasattr(self.session.pytrans, "ftOOBReceive"):
+                               self.messageOobMode()
+                       else:
+                               # No support
+                               self.legacyftp.reject()
+                               del self.legacyftp
                
                d = disco.DiscoRequest(self.session.pytrans, self.toJID).doDisco()
                d.addCallbacks(discoDone, discoFail)
@@ -150,7 +198,7 @@ class FTReceive:
                        query.attributes["mode"] = "tcp"
                        streamhost = query.addElement("streamhost")
                        streamhost.attributes["jid"] = self.senderJID
-                       streamhost.attributes["host"] = config.ip
+                       streamhost.attributes["host"] = config.host
                        streamhost.attributes["port"] = config.ftJabberPort
                        d = self.session.pytrans.discovery.sendIq(iq)
                        d.addErrback(ftDeclined) # Timeout
@@ -352,17 +400,17 @@ class Proxy65(protocol.Factory):
                        assert address not in self.activeConns
                        self.activeConns[address] = None
                        
-                       if not isinstance(olist[0], (JEP65ConnectionReceive, JEP65ConnectionSend)):
+                       if not isinstance(olist[0], JEP65ConnectionReceive):
                                legacyftp = olist[0]
                                connection = olist[1]
-                       elif not isinstance(olist[1], (JEP65ConnectionReceive, JEP65ConnectionSend)):
+                       elif not isinstance(olist[1], JEP65ConnectionReceive):
                                legacyftp = olist[1]
                                connection = olist[0]
                        else:
                                LogEvent(WARN, '', "No JEP65Connection")
                                return
 
-                       legacyftp.accept(connection.transport)
+                       doRateLimit(legacyftp.accept, connection.transport)
                else:
                        LogEvent(WARN, '', "No pending connection.")
        
@@ -398,7 +446,7 @@ from debug import LogEvent, INFO, WARN, ERROR
 class OOBReceiveConnector:
        def __init__(self, ftReceive, ftHttpPush):
                self.ftReceive, self.ftHttpPush = ftReceive, ftHttpPush
-               self.ftReceive.legacyftp.accept(self)
+               doRateLimit(self.ftReceive.legacyftp.accept, self)
        
        def write(self, data):
                self.ftHttpPush.write(data)