[Zope-Checkins] CVS: Zope3/lib/python/Zope/Server/FTP - FTPServer.py:1.1.2.2 FTPServerChannel.py:1.1.2.2
Stephan Richter
srichter@cbu.edu
Wed, 3 Apr 2002 00:28:39 -0500
Update of /cvs-repository/Zope3/lib/python/Zope/Server/FTP
In directory cvs.zope.org:/tmp/cvs-serv10910/FTP
Modified Files:
Tag: Zope3-Server-Branch
FTPServer.py FTPServerChannel.py
Log Message:
Got a couple of simple FTP commands working.
Wee, I have no clue how to write tests for this; this seems to be
non-trivial. I guess I need to have a close look at the HTTP Server
tests.
=== Zope3/lib/python/Zope/Server/FTP/FTPServer.py 1.1.2.1 => 1.1.2.2 ===
$Id$
"""
-
+import asyncore
from FTPServerChannel import FTPServerChannel
-from ServerBase import ServerBase
+from Zope.Server.ServerBase import ServerBase
+
+from Zope.Server.VFS.UnixFileSystem import UnixFileSystem
+from Zope.Server.Authentication.DictionaryAuthentication import \
+ DictionaryAuthentication
class FTPServer(ServerBase):
"""Generic FTP Server"""
+
+ filesystem = UnixFileSystem('/')
+ auth_source = DictionaryAuthentication({'foo': 'bar'})
+
channel_class = FTPServerChannel
SERVER_IDENT = 'Zope.Server.FTPServer'
if __name__ == '__main__':
- from TaskThreads import ThreadedTaskDispatcher
+ from Zope.Server.TaskThreads import ThreadedTaskDispatcher
td = ThreadedTaskDispatcher()
td.setThreadCount(4)
FTPServer('', 8021, task_dispatcher=td)
=== Zope3/lib/python/Zope/Server/FTP/FTPServerChannel.py 1.1.2.1 => 1.1.2.2 ===
"""
+from Zope.Server.ServerChannelBase import ServerChannelBase
+from FTPStatusMessages import status_msgs
+from FTPCommandParser import FTPCommandParser
+from FTPTask import FTPTask
+
from IFTPCommandHandler import IFTPCommandHandler
-from ServerBase import ServerChannelBase
+from PassiveAcceptor import PassiveAcceptor
class FTPServerChannel(ServerChannelBase):
@@ -40,6 +45,25 @@
passive_mode = 0
+ system = ('UNIX', 'L8')
+ cwd = '/'
+
+
+ type_map = {
+ 'a':'ASCII',
+ 'i':'Binary',
+ 'e':'EBCDIC',
+ 'l':'Binary'
+ }
+
+ type_mode_map = {
+ 'a':'t',
+ 'i':'b',
+ 'e':'b',
+ 'l':'b'
+ }
+
+
def process_request(self, command):
"""Processes an FTP command.
@@ -47,10 +71,14 @@
"""
assert isinstance(command, FTPCommandParser)
cmd = command.cmd
- m = 'do_' + cmd.lower()
- if hasattr(self, m):
+ m = 'cmd_' + cmd.lower()
+ if m == 'cmd_':
+ self.reply(500, 0, (''))
+ self.end_task(0)
+ elif hasattr(self, m):
# Quick processing
getattr(self, m)(command.args)
+ self.end_task(0)
else:
# Process in another thread.
task = self.task_class(self, command, m)
@@ -58,15 +86,129 @@
self.set_sync()
self.server.addTask(task)
else:
- # TODO: reply "command unknown"
- pass
+ self.reply(500, 0, (cmd.upper()))
+
+
+ ############################################################
+ # Implementation methods for interface
+ # Zope.Server.FTP.IFTPCommandHandler
+
+ def cmd_abor(self, args):
+ 'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
+ pass
+
+
+ def cmd_help(self, args):
+ 'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
+ self.reply(214, flush=0)
+ self.write('Help goes here somewhen.\r\n')
+ self.reply(214, 1)
+
+
+ def cmd_mode(self, args):
+ 'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
+ if len(args) == 1 and args in 'sS':
+ self.reply(200, 3)
+ else:
+ self.reply(502)
+
+
+ def cmd_noop(self, args):
+ 'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
+ self.reply(200, 0, ('NOOP'))
+
+
+ def cmd_pasv(self, args):
+ 'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
+ pc = PassiveAcceptor(self)
+ port = pc.addr[1]
+ ip_addr = pc.control_channel.getsockname()[0]
+ self.reply(227, args=( ','.join('.'.split(ip_addr)),
+ port/256,
+ port%256 ) )
+
+
+ def cmd_port(self, args):
+ 'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
+ info = string.split (args, ',')
+ ip = string.join (info[:4], '.')
+ port = int(info[4])*256 + int(info[5])
+
+ # how many data connections at a time?
+ # I'm assuming one for now...
+ # XXX: we should (optionally) verify that the
+ # ip number belongs to the client. [wu-ftpd does this?]
+
+ self.client_addr = (ip, port)
+ self.respond (200, args=('PORT',))
+
+
+ def cmd_pwd(self, args):
+ 'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
+ self.reply(257, 0, self.cwd)
+
+
+ def cmd_quit(self, args):
+ 'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
+ self.reply(221)
+ self.close_when_done()
+
+
+ def cmd_syst(self, args):
+ 'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
+ self.reply(215, 0, self.system)
+
+
+ def cmd_type(self, args):
+ 'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
+ # ascii, ebcdic, image, local <byte size>
+ args = args.split()
+ t = args[0].lower()
+ # no support for EBCDIC
+ # if t not in ['a','e','i','l']:
+ if t not in ['a','i','l']:
+ self.reply(500, 0, args=('TYPE',))
+
+ elif t == 'l' and (len(args) > 2 and args[2] != '8'):
+ self.reply(504, 0)
+
+ else:
+ if t == 'a':
+ self.ascii_mode = 1
+ else:
+ self.ascii_mode = 0
+ self.reply(200, 1, self.type_map[t])
+
+ def cmd_user(self, args):
+ 'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
+ if len(args) > 1:
+ self.user_name = args
+ self.reply(331) # Or whatever the code should be
+ else:
+ self.reply(500, 0, ('USER'))
+
+ #
+ ############################################################
+
+
+ def reply(self, code, pos=0, args=(), flush=1):
+ """ """
+ try:
+ msg = status_msgs[code][pos] %args
+ except:
+ # XXX: Somehow handle the nonexisting response.
+ msg = 'The server created a bad response type (code %i).' %code
+ code = 500
+
+ if msg.startswith('-'):
+ fill = ''
+ else:
+ fill = ' '
- def do_user(self, args):
- self.user_name = args
- self.reply(200) # Or whatever the code should be
+ self.write('%i%s%s\r\n' %(code, fill, msg))
+ if flush:
+ self.flush()
- def do_pass(self, args):
- self.user_password = args
- self.reply(200) # Or whatever the code should be
+ # XXX: Somelogging should go on here.