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:
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
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
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)
self.ftHttpPush.finish()
self.ftReceive.error()
-class FileTransferOOB(resource.Resource):
+class FileTransferOOBReceive(resource.Resource):
def __init__(self, port):
LogEvent(INFO)
self.isLeaf = True
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)