]> code.delx.au - pymsnt/blobdiff - src/ft.py
OOB file sending works.
[pymsnt] / src / ft.py
index 9d8aed960efdbf60fed6c3596dc9d8f567c5828e..1dfa6e88b6dc08986d3d1734759947e123a91b8e 100644 (file)
--- a/src/ft.py
+++ b/src/ft.py
@@ -12,8 +12,81 @@ import utils
 import random
 import sys
 
+
+###########
+# Sending #
+###########
+
+class FTSend:
+       """ For file transfers going from Jabber to MSN. """
+       def __init__(self, startTransfer, cancelTransfer, filename, filesize):
+               self.startTransfer = startTransfer
+               self.cancelTransfer = cancelTransfer
+               self.filename = filename
+               self.filesize = filesize
+       
+       def accept(self, legacyFileSend):
+               self.startTransfer(legacyFileSend)
+       
+       def reject(self):
+               del self.startTransfer
+               self.cancelTransfer
+
+
+try:
+       from twisted.web import http
+except ImportError:
+       try:
+               from twisted.protocols import http
+       except ImportError:
+               print "Couldn't find http.HTTPClient. If you're using Twisted 2.0, make sure that you've installed twisted.web"
+               raise
+
+
+class OOBHeaderHelper(http.HTTPClient):
+       """ Makes a HEAD request and grabs the length """
+       def connectionMade(self):
+               self.sendCommand("HEAD", self.factory.path.encode("utf-8"))
+               self.sendHeader("Host", (self.factory.host + ":" + str(self.factory.port)).encode("utf-8"))
+               self.endHeaders()
+       
+       def handleEndHeaders(self):
+               self.factory.gotLength(self.length)
+       
+       def handleResponse(self, data):
+               pass
+
+
+class OOBSendConnector(http.HTTPClient):
+       def connectionMade(self):
+               self.sendCommand("GET", self.factory.path.encode("utf-8"))
+               self.sendHeader("Host", (self.factory.host + ":" + str(self.factory.port)).encode("utf-8"))
+               self.endHeaders()
+               self.first = True
+       
+       def handleResponsePart(self, data):
+               self.factory.consumer.write(data)
+       
+       def handleResponseEnd(self):
+               # This is called once before writing is finished, and once when the
+               # connection closes. We only consumer.close() on the second.
+               if self.first:
+                       self.first = False
+               else:
+                       self.factory.consumer.close()
+                       self.factory.consumer = None
+                       self.factory.finished()
+
+
+
+
+
+#############
+# Receiving #
+#############
+
 class FTReceive:
-       """ Manager for file transfers going from MSN to Jabber. """
+       """ For file transfers going from MSN to Jabber. """
 
        """
        Plan of action for this class:
@@ -97,7 +170,7 @@ class FTReceive:
                si.attributes["profile"] = disco.FT
                si.attributes["id"] = self.sid
                file = si.addElement("file")
-               file.attributes["profile"] = disco.FT
+               file.attributes["xmlns"] = disco.FT
                file.attributes["size"] = str(self.legacyftp.filesize)
                file.attributes["name"] = self.legacyftp.filename
                # Feature negotiation
@@ -171,7 +244,7 @@ class JEP65Connection(socks5.SOCKSv5):
        
        def connectRequested(self, addr, port):
                # So that the legacyftp can close the connection
-               self.transport.close = self.transport.disconnect
+               self.transport.close = self.transport.loseConnection
        
                # Check for special connect to the namespace -- this signifies that
                # the client is just checking that it can connect to the streamhost
@@ -268,7 +341,7 @@ from twisted.internet import reactor
 
 from debug import LogEvent, INFO, WARN, ERROR
 
-class Connector:
+class OOBReceiveConnector:
        def __init__(self, ftReceive, ftHttpPush):
                self.ftReceive, self.ftHttpPush = ftReceive, ftHttpPush
                self.ftReceive.legacyftp.accept(self)
@@ -283,7 +356,7 @@ class Connector:
                self.ftHttpPush.finish()
                self.ftReceive.error()
 
-class FileTransferOOB(resource.Resource):
+class FileTransferOOBReceive(resource.Resource):
        def __init__(self, port):
                LogEvent(INFO)
                self.isLeaf = True
@@ -307,12 +380,22 @@ class FileTransferOOB(resource.Resource):
                        file = self.files[filename]
                        request.setHeader("Content-Length", str(file.legacyftp.filesize))
                        request.setHeader("Content-Disposition", "attachment; filename=\"%s\"" % file.legacyftp.filename.encode("utf-8"))
-                       Connector(file, request)
+                       OOBReceiveConnector(file, request)
                        del self.files[filename]
                        return server.NOT_DONE_YET
                else:
                        page = error.NoResource(message="404 File Not Found")
                        return page.render(request)
-
+       
+       def render_HEAD(self, request):
+               filename = request.path[1:] # Remove the leading /
+               if self.files.has_key(filename):
+                       file = self.files[filename]
+                       request.setHeader("Content-Length", str(file.legacyftp.filesize))
+                       request.setHeader("Content-Disposition", "attachment; filename=\"%s\"" % file.legacyftp.filename.encode("utf-8"))
+                       return ""
+               else:
+                       page = error.NoResource(message="404 File Not Found")
+                       return page.render(request)