[Zope-Checkins] CVS: Zope3/lib/python/Zope/Server/FTP - FTPServer.py:1.1.2.6 FTPServerChannel.py:1.1.2.11 FTPCommandParser.py:NONE FTPTask.py:NONE

Stephan Richter srichter@cbu.edu
Thu, 4 Apr 2002 20:36:35 -0500


Update of /cvs-repository/Zope3/lib/python/Zope/Server/FTP
In directory cvs.zope.org:/tmp/cvs-serv20145/FTP

Modified Files:
      Tag: Zope3-Server-Branch
	FTPServer.py FTPServerChannel.py 
Removed Files:
      Tag: Zope3-Server-Branch
	FTPCommandParser.py FTPTask.py 
Log Message:
This is a first take on providing a generic framework for comamnd line
protocols. They share quiet a bit of code, so I think it is worthwhile
doing that. I also fixed the FTP server to work with this.


=== Zope3/lib/python/Zope/Server/FTP/FTPServer.py 1.1.2.5 => 1.1.2.6 ===
-#
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""
-
-$Id$
-"""
-import asyncore
-from FTPServerChannel import FTPServerChannel
-from Zope.Server.ServerBase import ServerBase
-from Zope.Server.Counter import Counter
-
-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'
-
-
-    def __init__(self, ip, port, task_dispatcher=None, adj=None, start=1,
-                 hit_log=None, verbose=0, socket_map=None):
-        super(FTPServer, self).__init__(ip, port, task_dispatcher,
-                                        adj, start, hit_log,
-                                        verbose, socket_map)
-
-        # statistics
-        self.total_sessions = Counter()
-        self.closed_sessions = Counter()
-        self.total_files_out = Counter()
-        self.total_files_in = Counter()
-        self.total_bytes_out = Counter()
-        self.total_bytes_in = Counter()
-        self.total_exceptions = Counter()
-
-
-if __name__ == '__main__':
-    from Zope.Server.TaskThreads import ThreadedTaskDispatcher
-    td = ThreadedTaskDispatcher()
-    td.setThreadCount(4)
-    FTPServer('', 8021, task_dispatcher=td)
-    try:
-        while 1:
-            asyncore.poll(5)
-            print 'active channels:', FTPServerChannel.active_channels
-    except KeyboardInterrupt:
-        print 'shutting down...'
-        td.shutdown()
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+import asyncore
+from FTPServerChannel import FTPServerChannel
+from Zope.Server.ServerBase import ServerBase
+from Zope.Server.Counter import Counter
+
+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'
+
+
+    def __init__(self, ip, port, task_dispatcher=None, adj=None, start=1,
+                 hit_log=None, verbose=0, socket_map=None):
+        super(FTPServer, self).__init__(ip, port, task_dispatcher,
+                                        adj, start, hit_log,
+                                        verbose, socket_map)
+
+        # statistics
+        self.total_sessions = Counter()
+        self.closed_sessions = Counter()
+        self.total_files_out = Counter()
+        self.total_files_in = Counter()
+        self.total_bytes_out = Counter()
+        self.total_bytes_in = Counter()
+        self.total_exceptions = Counter()
+
+
+if __name__ == '__main__':
+    from Zope.Server.TaskThreads import ThreadedTaskDispatcher
+    td = ThreadedTaskDispatcher()
+    td.setThreadCount(4)
+    FTPServer('', 8021, task_dispatcher=td)
+    try:
+        while 1:
+            asyncore.poll(5)
+            print 'active channels:', FTPServerChannel.active_channels
+    except KeyboardInterrupt:
+        print 'shutting down...'
+        td.shutdown()


=== Zope3/lib/python/Zope/Server/FTP/FTPServerChannel.py 1.1.2.10 => 1.1.2.11 ===
 import time
 
-from Zope.Server.ServerChannelBase import ServerChannelBase
+from Zope.Server.LineReceiver.LineServerChannel import LineServerChannel
 from FTPStatusMessages import status_msgs
-from FTPCommandParser import FTPCommandParser
-from FTPTask import FTPTask
 from FileProducer import FileProducer
 
 from IFTPCommandHandler import IFTPCommandHandler
@@ -33,24 +31,34 @@
 from XmitChannel import XmitChannel
 
 
-# These are the commands that are accessing the filesystem.
-# Since this could be also potentially a longer process, these commands
-# are also the ones that are executed in a different thread.
-fs_access_cmds = ('cmd_appe', 'cmd_cdup', 'cmd_cwd', 'cmd_dele', 'cmd_list',
-                  'cmd_nlst', 'cmd_mdtm', 'cmd_mkd', 'cmd_pass', 'cmd_retr',
-                  'cmd_rmd', 'cmd_rnfr', 'cmd_rnto', 'cmd_size', 'cmd_stor',
-                  'cmd_stru')
-
-
-class FTPServerChannel(ServerChannelBase):
+class FTPServerChannel(LineServerChannel):
     """The FTP Server Channel represents a connection to a particular
        client. We can therefore store information here."""
 
-    __implements__ = IFTPCommandHandler
+    __implements__ = LineServerChannel.__implements__, IFTPCommandHandler
+
+
+    # List of commands that are always available 
+    special_commands = ('cmd_quit', 'cmd_user', 'cmd_pass')
+
+    # These are the commands that are accessing the filesystem.
+    # Since this could be also potentially a longer process, these commands
+    # are also the ones that are executed in a different thread.
+    thread_commands = ('cmd_appe', 'cmd_cdup', 'cmd_cwd', 'cmd_dele',
+                       'cmd_list', 'cmd_nlst', 'cmd_mdtm', 'cmd_mkd',
+                       'cmd_pass', 'cmd_retr', 'cmd_rmd', 'cmd_rnfr',
+                       'cmd_rnto', 'cmd_size', 'cmd_stor', 'cmd_stru')
+
+    # Define the reply code for non-authenticated responses
+    not_auth_reply = (530, 1)
 
-    task_class = FTPTask
-    parser_class = FTPCommandParser
+    # Define the reply code for an unrecognized command
+    unknown_reply = (500, 0)
 
+    # Define the status messages
+    status_messages = status_msgs
+
+    # Define the type of directory listing this server is returning
     system = ('UNIX', 'L8')
 
     # comply with (possibly troublesome) RFC959 requirements
@@ -61,20 +69,9 @@
 
     restart_position = 0
 
+    type_map = {'a':'ASCII', 'i':'Binary', 'e':'EBCDIC', 'l':'Binary'}
 
-    type_map = {
-            'a':'ASCII',
-            'i':'Binary',
-            'e':'EBCDIC',
-            'l':'Binary'
-            }
-
-    type_mode_map = {
-            'a':'t',
-            'i':'b',
-            'e':'b',
-            'l':'b'
-            }
+    type_mode_map = {'a':'t', 'i':'b', 'e':'b', 'l':'b'}
 
 
     def __init__(self, server, conn, addr, adj=None, socket_map=None):
@@ -96,35 +93,10 @@
 
         self.username = ''
         self.password = ''
-        self.authenticated = 0
 
         self.reply(220, 0, self.server.server_name)
 
 
-    def process_request(self, command):
-        """Processes an FTP command.
-
-        Some commands use an alternate thread.
-        """
-        assert isinstance(command, FTPCommandParser)
-        cmd = command.cmd
-        method = 'cmd_' + cmd.lower()
-        if ( not self.authenticated and
-             method not in ('cmd_user', 'cmd_pass', 'cmd_quit')):
-            # The user is not logged in, therefore don't allow anything
-            self.reply(530, 1)
-
-        elif method in fs_access_cmds:
-            # Process in another thread.
-            return self.task_class(self, command, method)
-
-        elif hasattr(self, method):
-            getattr(self, method)(command.args)
-
-        else:
-            self.reply(500, 0, (cmd.upper()))
-
-
     ############################################################
     # Implementation methods for interface
     # Zope.Server.FTP.IFTPCommandHandler
@@ -573,25 +545,3 @@
                 self.reply(425)
 
         self.client_dc = cdc
-
-
-    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 = ' '
-
-        self.write('%i%s%s\r\n' %(code, fill, msg))
-
-        if flush:
-            self.flush(0)
-
-        # XXX: Some logging should go on here.

=== Removed File Zope3/lib/python/Zope/Server/FTP/FTPCommandParser.py ===

=== Removed File Zope3/lib/python/Zope/Server/FTP/FTPTask.py ===