[Zope-Checkins] CVS: Zope3/lib/python/Zope/Server/FTP - CommonFTPActivityLogger.py:1.1.2.3 FTPCommandParser.py:1.1.2.4 FTPServer.py:1.1.2.5 FTPServerChannel.py:1.1.2.9 FTPStatusMessages.py:1.1.2.5 FTPTask.py:1.1.2.3 FileProducer.py:1.1.2.3 IFTPCommandHandler.py:1.1.2.3 PassiveAcceptor.py:1.1.2.2 PublisherFTPServer.py:1.1.2.2 PublisherFTPTask.py:1.1.2.2 RecvChannel.py:1.1.2.3 XmitChannel.py:1.1.2.2 __init__.py:1.1.2.2
Shane Hathaway
shane@cvs.zope.org
Thu, 4 Apr 2002 13:46:28 -0500
Update of /cvs-repository/Zope3/lib/python/Zope/Server/FTP
In directory cvs.zope.org:/tmp/cvs-serv17993/FTP
Modified Files:
Tag: Zope3-Server-Branch
CommonFTPActivityLogger.py FTPCommandParser.py FTPServer.py
FTPServerChannel.py FTPStatusMessages.py FTPTask.py
FileProducer.py IFTPCommandHandler.py PassiveAcceptor.py
PublisherFTPServer.py PublisherFTPTask.py RecvChannel.py
XmitChannel.py __init__.py
Log Message:
Just fixed line endings. No carriage returns.
=== Zope3/lib/python/Zope/Server/FTP/CommonFTPActivityLogger.py 1.1.2.2 => 1.1.2.3 ===
-#
-# 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 time
-import sys
-
-from Zope.Server.Logger.FileLogger import FileLogger
-from Zope.Server.Logger.ResolvingLogger import ResolvingLogger
-from Zope.Server.Logger.UnresolvingLogger import UnresolvingLogger
-
-
-class CommonFTPActivityLogger:
- """Outputs hits in common HTTP log format.
- """
-
- def __init__(self, logger_object=None, resolver=None):
- if logger_object is None:
- logger_object = FileLogger(sys.stdout)
-
- if resolver is not None:
- self.output = ResolvingLogger(resolver, logger_object)
- else:
- self.output = UnresolvingLogger(logger_object)
-
-
- def log(self, task):
- """
- Receives a completed task and logs it in the
- common log format.
- """
-
- now = time.localtime(time.time())
-
- print now
- self.output.log('127.0.0.1', time.strftime('%Y/%m/%d %H:%M', now))
+##############################################################################
+#
+# 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 time
+import sys
+
+from Zope.Server.Logger.FileLogger import FileLogger
+from Zope.Server.Logger.ResolvingLogger import ResolvingLogger
+from Zope.Server.Logger.UnresolvingLogger import UnresolvingLogger
+
+
+class CommonFTPActivityLogger:
+ """Outputs hits in common HTTP log format.
+ """
+
+ def __init__(self, logger_object=None, resolver=None):
+ if logger_object is None:
+ logger_object = FileLogger(sys.stdout)
+
+ if resolver is not None:
+ self.output = ResolvingLogger(resolver, logger_object)
+ else:
+ self.output = UnresolvingLogger(logger_object)
+
+
+ def log(self, task):
+ """
+ Receives a completed task and logs it in the
+ common log format.
+ """
+
+ now = time.localtime(time.time())
+
+ print now
+ self.output.log('127.0.0.1', time.strftime('%Y/%m/%d %H:%M', now))
=== Zope3/lib/python/Zope/Server/FTP/FTPCommandParser.py 1.1.2.3 => 1.1.2.4 ===
-#
-# 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$
-"""
-
-from Zope.Server.IStreamConsumer import IStreamConsumer
-
-
-class FTPCommandParser:
- """FTP Command parser. Arguments are left alone for now."""
-
- __implements__ = IStreamConsumer
-
-
- # See Zope.Server.IStreamConsumer.IStreamConsumer
- completed = 0
- inbuf = ''
- cmd = ''
- args = ''
- empty = 0
-
-
- max_line_length = 1024 # Not a hard limit
-
-
- def __init__(self, adj):
- """
- adj is an Adjustments object.
- """
- self.adj = adj
-
-
- ############################################################
- # Implementation methods for interface
- # Zope.Server.IStreamConsumer
-
- def received(self, data):
- 'See Zope.Server.IStreamConsumer.IStreamConsumer'
- if self.completed:
- return 0 # Can't consume any more.
- pos = data.find('\n')
- datalen = len(data)
- if pos < 0:
- self.inbuf = self.inbuf + data
- if len(self.inbuf) > self.max_line_length:
- # Don't accept any more.
- self.completed = 1
- return datalen
- else:
- # Line finished.
- s = data[:pos + 1]
- self.inbuf = self.inbuf + s
- self.completed = 1
- line = self.inbuf.strip()
- self.parseLine(line)
- return len(s)
-
- #
- ############################################################
-
-
- def parseLine(self, line):
- parts = line.split(' ', 1)
- if len(parts) == 2:
- self.cmd, self.args = parts
- else:
- self.cmd = parts[0]
+##############################################################################
+#
+# 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$
+"""
+
+from Zope.Server.IStreamConsumer import IStreamConsumer
+
+
+class FTPCommandParser:
+ """FTP Command parser. Arguments are left alone for now."""
+
+ __implements__ = IStreamConsumer
+
+
+ # See Zope.Server.IStreamConsumer.IStreamConsumer
+ completed = 0
+ inbuf = ''
+ cmd = ''
+ args = ''
+ empty = 0
+
+
+ max_line_length = 1024 # Not a hard limit
+
+
+ def __init__(self, adj):
+ """
+ adj is an Adjustments object.
+ """
+ self.adj = adj
+
+
+ ############################################################
+ # Implementation methods for interface
+ # Zope.Server.IStreamConsumer
+
+ def received(self, data):
+ 'See Zope.Server.IStreamConsumer.IStreamConsumer'
+ if self.completed:
+ return 0 # Can't consume any more.
+ pos = data.find('\n')
+ datalen = len(data)
+ if pos < 0:
+ self.inbuf = self.inbuf + data
+ if len(self.inbuf) > self.max_line_length:
+ # Don't accept any more.
+ self.completed = 1
+ return datalen
+ else:
+ # Line finished.
+ s = data[:pos + 1]
+ self.inbuf = self.inbuf + s
+ self.completed = 1
+ line = self.inbuf.strip()
+ self.parseLine(line)
+ return len(s)
+
+ #
+ ############################################################
+
+
+ def parseLine(self, line):
+ parts = line.split(' ', 1)
+ if len(parts) == 2:
+ self.cmd, self.args = parts
+ else:
+ self.cmd = parts[0]
+
=== Zope3/lib/python/Zope/Server/FTP/FTPServer.py 1.1.2.4 => 1.1.2.5 ===
-#
-# 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.8 => 1.1.2.9 === (1103/1203 lines abridged)
-#
-# 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 os
-import stat
-import socket
-import time
-
-from Zope.Server.ServerChannelBase import ServerChannelBase
-from FTPStatusMessages import status_msgs
-from FTPCommandParser import FTPCommandParser
-from FTPTask import FTPTask
-from FileProducer import FileProducer
-
-from IFTPCommandHandler import IFTPCommandHandler
-from PassiveAcceptor import PassiveAcceptor
-from RecvChannel import RecvChannel
-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 slao 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):
- """The FTP Server Channel represents a connection to a particular
- client. We can therefore store information here."""
-
- __implements__ = IFTPCommandHandler
-
- task_class = FTPTask
[-=- -=- -=- 1103 lines omitted -=- -=- -=-]
+
+ # pretty much the same as xmit, but only right on the verge of
+ # being worth a merge.
+ def createRecvChannel(self, fd):
+ pa = self.passive_acceptor
+ if pa:
+ if pa.ready:
+ # a connection has already been made.
+ conn, addr = pa.ready
+ cdc = RecvChannel(self, addr, fd)
+ cdc.set_socket (conn)
+ cdc.connected = 1
+ self.passive_acceptor.close()
+ self.passive_acceptor = None
+ else:
+ # we're still waiting for a connect to the PASV port.
+ cdc = RecvChannel(self, None, fd)
+ else:
+ # not in PASV mode.
+ ip, port = self.client_addr
+ cdc = RecvChannel(self, self.client_addr, fd)
+ cdc.create_socket(socket.AF_INET, socket.SOCK_STREAM)
+ try:
+ cdc.connect ((ip, port))
+ except socket.error, why:
+ 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()
+
+ # XXX: Some logging should go on here.
=== Zope3/lib/python/Zope/Server/FTP/FTPStatusMessages.py 1.1.2.4 => 1.1.2.5 ===
-#
-# 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$
-"""
-
-
-status_msgs = {
- 150: ('Opening %s mode data connection for file list',
- 'Opening %s connection for %s',),
- 200: ('%s command successful.',
- 'Type set to %s.',
- 'STRU F Ok.',
- 'MODE S Ok.',),
- 213: ('%4d%02d%02d%02d%02d%02d', # A date
- '%d Bytes'), # Size
- 214: ('-The following commands are recognized',
- ''),
- 215: ('%s Type: %s',), # Server Type
- 220: ('%s FTP server (Zope Async/Thread V0.1) ready.',),
- 221: ('Goodbye.',),
- 226: ('%s command successful.',
- 'Transfer successful.'),
- 227: ('Entering Passive Mode (%s,%d,%d)',),
- 230: ('Login Successful.',),
- 250: ('%s command successful.',),
- 257: ('%s command successful.',
- "'%s' is the current directory.",),
- 331: ('Password required',),
- 350: ('Restarting at %d. Send STORE or RETRIEVE to initiate transfer.',
- 'File exists, ready for destination.',),
- 425: ("Can't build data connection",),
- 426: ('Connection closed; transfer aborted.',),
- 500: ("'%s': command not understood.",),
- 502: ("Unimplemented MODE type",),
- 504: ('Byte size must be 8',
- 'Unimplemented STRU type',),
- 530: ("You are not authorized to perform the '%s' command",
- 'Please log in with USER and PASS',
- 'The username and password do not match.',),
- 550: ('Could not list directory: %s',
- '%s: No such directory.',
- '%s: No such file.',
- '%s: Is not a file',
- 'Error creating file.',
- 'Error creating directory.',
- 'Error deleting file.',
- 'Error removing directory.'),
- 553: ('Could not open file for reading: %s',
- 'Could not open file for writing: %s',
- 'Restart on STOR not yet supported',),
-
- 560: ('Could not rename %s to %s.',
- 'No source filename specify. Call RNFR first.',),
- }
-
+##############################################################################
+#
+# 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$
+"""
+
+
+status_msgs = {
+ 150: ('Opening %s mode data connection for file list',
+ 'Opening %s connection for %s',),
+ 200: ('%s command successful.',
+ 'Type set to %s.',
+ 'STRU F Ok.',
+ 'MODE S Ok.',),
+ 213: ('%4d%02d%02d%02d%02d%02d', # A date
+ '%d Bytes'), # Size
+ 214: ('-The following commands are recognized',
+ ''),
+ 215: ('%s Type: %s',), # Server Type
+ 220: ('%s FTP server (Zope Async/Thread V0.1) ready.',),
+ 221: ('Goodbye.',),
+ 226: ('%s command successful.',
+ 'Transfer successful.'),
+ 227: ('Entering Passive Mode (%s,%d,%d)',),
+ 230: ('Login Successful.',),
+ 250: ('%s command successful.',),
+ 257: ('%s command successful.',
+ "'%s' is the current directory.",),
+ 331: ('Password required',),
+ 350: ('Restarting at %d. Send STORE or RETRIEVE to initiate transfer.',
+ 'File exists, ready for destination.',),
+ 425: ("Can't build data connection",),
+ 426: ('Connection closed; transfer aborted.',),
+ 500: ("'%s': command not understood.",),
+ 502: ("Unimplemented MODE type",),
+ 504: ('Byte size must be 8',
+ 'Unimplemented STRU type',),
+ 530: ("You are not authorized to perform the '%s' command",
+ 'Please log in with USER and PASS',
+ 'The username and password do not match.',),
+ 550: ('Could not list directory: %s',
+ '%s: No such directory.',
+ '%s: No such file.',
+ '%s: Is not a file',
+ 'Error creating file.',
+ 'Error creating directory.',
+ 'Error deleting file.',
+ 'Error removing directory.'),
+ 553: ('Could not open file for reading: %s',
+ 'Could not open file for writing: %s',
+ 'Restart on STOR not yet supported',),
+
+ 560: ('Could not rename %s to %s.',
+ 'No source filename specify. Call RNFR first.',),
+ }
+
=== Zope3/lib/python/Zope/Server/FTP/FTPTask.py 1.1.2.2 => 1.1.2.3 ===
-#
-# 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 socket
-import time
-from Zope.Server.ITask import ITask
-
-
-class FTPTask:
- """
- """
-
- __implements__ = ITask
-
-
- def __init__(self, channel, command, m_name):
- self.channel = channel
- self.m_name = m_name
- self.args = command.args
-
- self.close_on_finish = 0
-
-
- ############################################################
- # Implementation methods for interface
- # Zope.Server.ITask
-
- def service(self):
- """Called to execute the task.
- """
- try:
- try:
- self.start()
- getattr(self.channel, self.m_name)(self.args)
- self.finish()
- except socket.error:
- self.close_on_finish = 1
- if self.channel.adj.log_socket_errors:
- raise
- finally:
- self.channel.end_task(self.close_on_finish)
-
-
- def cancel(self):
- 'See Zope.Server.ITask.ITask'
- self.channel.close_when_done()
-
-
- def defer(self):
- 'See Zope.Server.ITask.ITask'
- pass
-
- #
- ############################################################
-
- def start(self):
- now = time.time()
- self.start_time = now
-
-
- def finish(self):
- hit_log = self.channel.server.hit_log
- if hit_log is not None:
- hit_log.log(self)
+##############################################################################
+#
+# 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 socket
+import time
+from Zope.Server.ITask import ITask
+
+
+class FTPTask:
+ """
+ """
+
+ __implements__ = ITask
+
+
+ def __init__(self, channel, command, m_name):
+ self.channel = channel
+ self.m_name = m_name
+ self.args = command.args
+
+ self.close_on_finish = 0
+
+
+ ############################################################
+ # Implementation methods for interface
+ # Zope.Server.ITask
+
+ def service(self):
+ """Called to execute the task.
+ """
+ try:
+ try:
+ self.start()
+ getattr(self.channel, self.m_name)(self.args)
+ self.finish()
+ except socket.error:
+ self.close_on_finish = 1
+ if self.channel.adj.log_socket_errors:
+ raise
+ finally:
+ self.channel.end_task(self.close_on_finish)
+
+
+ def cancel(self):
+ 'See Zope.Server.ITask.ITask'
+ self.channel.close_when_done()
+
+
+ def defer(self):
+ 'See Zope.Server.ITask.ITask'
+ pass
+
+ #
+ ############################################################
+
+ def start(self):
+ now = time.time()
+ self.start_time = now
+
+
+ def finish(self):
+ hit_log = self.channel.server.hit_log
+ if hit_log is not None:
+ hit_log.log(self)
=== Zope3/lib/python/Zope/Server/FTP/FileProducer.py 1.1.2.2 => 1.1.2.3 ===
-#
-# 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$
-"""
-
-class FileProducer:
- """ """
- block_size = 16384
-
- def __init__(self, server, dc, fd):
- self.fd = fd
- self.done = 0
-
-
- def more(self):
- if self.done:
- return ''
- else:
- block = self.fd.read(self.block_size)
- if not block:
- self.fd.close()
- self.done = 1
- return block
+##############################################################################
+#
+# 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$
+"""
+
+class FileProducer:
+ """ """
+ block_size = 16384
+
+ def __init__(self, server, dc, fd):
+ self.fd = fd
+ self.done = 0
+
+
+ def more(self):
+ if self.done:
+ return ''
+ else:
+ block = self.fd.read(self.block_size)
+ if not block:
+ self.fd.close()
+ self.done = 1
+ return block
=== Zope3/lib/python/Zope/Server/FTP/IFTPCommandHandler.py 1.1.2.2 => 1.1.2.3 ===
-
-from Interface import Interface
-
-class IFTPCommandHandler(Interface):
- """This interface defines all the FTP commands that are supported by the
- server.
-
- Every command takes the command line as first arguments, since it is
- responsible
- """
-
- def cmd_abor(args):
- """Abort operation. No read access required.
- """
-
- def cmd_appe(args):
- """Append to a file. Write access required.
- """
-
- def cmd_cdup(args):
- """Change to parent of current working directory.
- """
-
- def cmd_cwd(args):
- """Change working directory.
- """
-
- def cmd_dele(args):
- """Delete a file. Write access required.
- """
-
- def cmd_help(args):
- """Give help information. No read access required.
- """
-
- def cmd_list(args):
- """Give list files in a directory.
- """
-
- def cmd_mdtm(args):
- """Show last modification time of file.
-
- Example output: 213 19960301204320
- """
-
- def cmd_mkd(args):
- """Make a directory. Write access required.
- """
-
- def cmd_mode(args):
- """Set file transfer mode. No read access required. Obselete.
- """
-
- def cmd_nlst(args):
- """Give name list of files in directory.
- """
-
- def cmd_noop(args):
- """Do nothing. No read access required.
- """
-
- def cmd_pass(args):
- """Specify password.
- """
-
- def cmd_pasv(args):
- """Prepare for server-to-server transfer. No read access required.
- """
-
- def cmd_port(args):
- """Specify data connection port. No read access required.
- """
-
- def cmd_pwd(args):
- """Print the current working directory.
- """
-
- def cmd_quit(args):
- """Terminate session. No read access required.
- """
-
- def cmd_rest(args):
- """Restart incomplete transfer.
- """
-
- def cmd_retr(args):
- """Retrieve a file.
- """
-
- def cmd_rmd(args):
- """Remove a directory. Write access required.
- """
-
- def cmd_rnfr(args):
- """Specify rename-from file name. Write access required.
- """
-
- def cmd_rnto(args):
- """Specify rename-to file name. Write access required.
- """
-
- def cmd_size(args):
- """Return size of file.
- """
-
- def cmd_stat(args):
- """Return status of server. No read access required.
- """
-
- def cmd_stor(args):
- """Store a file. Write access required.
- """
-
- def cmd_stru(args):
- """Set file transfer structure. Obselete."""
-
- def cmd_syst(args):
- """Show operating system type of server system.
-
- No read access required.
-
- Replying to this command is of questionable utility,
- because this server does not behave in a predictable way
- w.r.t. the output of the LIST command. We emulate Unix ls
- output, but on win32 the pathname can contain drive
- information at the front Currently, the combination of
- ensuring that os.sep == '/' and removing the leading slash
- when necessary seems to work. [cd'ing to another drive
- also works]
-
- This is how wuftpd responds, and is probably the most
- expected. The main purpose of this reply is so that the
- client knows to expect Unix ls-style LIST output.
-
- one disadvantage to this is that some client programs
- assume they can pass args to /bin/ls. a few typical
- responses:
-
- 215 UNIX Type: L8 (wuftpd)
- 215 Windows_NT version 3.51
- 215 VMS MultiNet V3.3
- 500 'SYST': command not understood. (SVR4)
- """
-
- def cmd_type(args):
- """Specify data transfer type. No read access required.
- """
-
- def cmd_user(args):
- """Specify user name. No read access required.
- """
-
-
-
-# this is the command list from the wuftpd man page
-# '!' requires write access
-#
-not_implemented_commands = {
- 'acct': 'specify account (ignored)',
- 'allo': 'allocate storage (vacuously)',
- 'site': 'non-standard commands (see next section)',
- 'stou': 'store a file with a unique name', #!
- 'xcup': 'change to parent of current working directory (deprecated)',
- 'xcwd': 'change working directory (deprecated)',
- 'xmkd': 'make a directory (deprecated)', #!
- 'xpwd': 'print the current working directory (deprecated)',
- 'xrmd': 'remove a directory (deprecated)', #!
-}
+
+
+from Interface import Interface
+
+class IFTPCommandHandler(Interface):
+ """This interface defines all the FTP commands that are supported by the
+ server.
+
+ Every command takes the command line as first arguments, since it is
+ responsible
+ """
+
+ def cmd_abor(args):
+ """Abort operation. No read access required.
+ """
+
+ def cmd_appe(args):
+ """Append to a file. Write access required.
+ """
+
+ def cmd_cdup(args):
+ """Change to parent of current working directory.
+ """
+
+ def cmd_cwd(args):
+ """Change working directory.
+ """
+
+ def cmd_dele(args):
+ """Delete a file. Write access required.
+ """
+
+ def cmd_help(args):
+ """Give help information. No read access required.
+ """
+
+ def cmd_list(args):
+ """Give list files in a directory.
+ """
+
+ def cmd_mdtm(args):
+ """Show last modification time of file.
+
+ Example output: 213 19960301204320
+ """
+
+ def cmd_mkd(args):
+ """Make a directory. Write access required.
+ """
+
+ def cmd_mode(args):
+ """Set file transfer mode. No read access required. Obselete.
+ """
+
+ def cmd_nlst(args):
+ """Give name list of files in directory.
+ """
+
+ def cmd_noop(args):
+ """Do nothing. No read access required.
+ """
+
+ def cmd_pass(args):
+ """Specify password.
+ """
+
+ def cmd_pasv(args):
+ """Prepare for server-to-server transfer. No read access required.
+ """
+
+ def cmd_port(args):
+ """Specify data connection port. No read access required.
+ """
+
+ def cmd_pwd(args):
+ """Print the current working directory.
+ """
+
+ def cmd_quit(args):
+ """Terminate session. No read access required.
+ """
+
+ def cmd_rest(args):
+ """Restart incomplete transfer.
+ """
+
+ def cmd_retr(args):
+ """Retrieve a file.
+ """
+
+ def cmd_rmd(args):
+ """Remove a directory. Write access required.
+ """
+
+ def cmd_rnfr(args):
+ """Specify rename-from file name. Write access required.
+ """
+
+ def cmd_rnto(args):
+ """Specify rename-to file name. Write access required.
+ """
+
+ def cmd_size(args):
+ """Return size of file.
+ """
+
+ def cmd_stat(args):
+ """Return status of server. No read access required.
+ """
+
+ def cmd_stor(args):
+ """Store a file. Write access required.
+ """
+
+ def cmd_stru(args):
+ """Set file transfer structure. Obselete."""
+
+ def cmd_syst(args):
+ """Show operating system type of server system.
+
+ No read access required.
+
+ Replying to this command is of questionable utility,
+ because this server does not behave in a predictable way
+ w.r.t. the output of the LIST command. We emulate Unix ls
+ output, but on win32 the pathname can contain drive
+ information at the front Currently, the combination of
+ ensuring that os.sep == '/' and removing the leading slash
+ when necessary seems to work. [cd'ing to another drive
+ also works]
+
+ This is how wuftpd responds, and is probably the most
+ expected. The main purpose of this reply is so that the
+ client knows to expect Unix ls-style LIST output.
+
+ one disadvantage to this is that some client programs
+ assume they can pass args to /bin/ls. a few typical
+ responses:
+
+ 215 UNIX Type: L8 (wuftpd)
+ 215 Windows_NT version 3.51
+ 215 VMS MultiNet V3.3
+ 500 'SYST': command not understood. (SVR4)
+ """
+
+ def cmd_type(args):
+ """Specify data transfer type. No read access required.
+ """
+
+ def cmd_user(args):
+ """Specify user name. No read access required.
+ """
+
+
+
+# this is the command list from the wuftpd man page
+# '!' requires write access
+#
+not_implemented_commands = {
+ 'acct': 'specify account (ignored)',
+ 'allo': 'allocate storage (vacuously)',
+ 'site': 'non-standard commands (see next section)',
+ 'stou': 'store a file with a unique name', #!
+ 'xcup': 'change to parent of current working directory (deprecated)',
+ 'xcwd': 'change working directory (deprecated)',
+ 'xmkd': 'make a directory (deprecated)', #!
+ 'xpwd': 'print the current working directory (deprecated)',
+ 'xrmd': 'remove a directory (deprecated)', #!
+}
=== Zope3/lib/python/Zope/Server/FTP/PassiveAcceptor.py 1.1.2.1 => 1.1.2.2 ===
-#
-# 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
-import socket
-
-
-class PassiveAcceptor(asyncore.dispatcher):
- """This socket accepts a data connection, used when the server has
- been placed in passive mode. Although the RFC implies that we
- ought to be able to use the same acceptor over and over again,
- this presents a problem: how do we shut it off, so that we are
- accepting connections only when we expect them? [we can't]
-
- wuftpd, and probably all the other servers, solve this by
- allowing only one connection to hit this acceptor. They then
- close it. Any subsequent data-connection command will then try
- for the default port on the client side [which is of course
- never there]. So the 'always-send-PORT/PASV' behavior seems
- required.
-
- Another note: wuftpd will also be listening on the channel as
- soon as the PASV command is sent. It does not wait for a data
- command first.
-
- --- we need to queue up a particular behavior:
- 1) xmit : queue up producer[s]
- 2) recv : the file object
-
- It would be nice if we could make both channels the same.
- Hmmm.."""
-
- __implements__ = asyncore.dispatcher.__implements__
-
- ready = None
-
- def __init__ (self, control_channel):
- asyncore.dispatcher.__init__ (self)
- self.control_channel = control_channel
- self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
- # bind to an address on the interface that the
- # control connection is coming from.
- self.bind ( (self.control_channel.getsockname()[0], 0) )
- self.addr = self.getsockname()
- self.listen(1)
-
-
- def log (self, *ignore):
- pass
-
-
- def handle_accept (self):
- conn, addr = self.accept()
- dc = self.control_channel.client_dc
- if dc is not None:
- dc.set_socket(conn)
- dc.addr = addr
- dc.connected = 1
- self.control_channel.passive_acceptor = None
- else:
- self.ready = conn, addr
- self.close()
+##############################################################################
+#
+# 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
+import socket
+
+
+class PassiveAcceptor(asyncore.dispatcher):
+ """This socket accepts a data connection, used when the server has
+ been placed in passive mode. Although the RFC implies that we
+ ought to be able to use the same acceptor over and over again,
+ this presents a problem: how do we shut it off, so that we are
+ accepting connections only when we expect them? [we can't]
+
+ wuftpd, and probably all the other servers, solve this by
+ allowing only one connection to hit this acceptor. They then
+ close it. Any subsequent data-connection command will then try
+ for the default port on the client side [which is of course
+ never there]. So the 'always-send-PORT/PASV' behavior seems
+ required.
+
+ Another note: wuftpd will also be listening on the channel as
+ soon as the PASV command is sent. It does not wait for a data
+ command first.
+
+ --- we need to queue up a particular behavior:
+ 1) xmit : queue up producer[s]
+ 2) recv : the file object
+
+ It would be nice if we could make both channels the same.
+ Hmmm.."""
+
+ __implements__ = asyncore.dispatcher.__implements__
+
+ ready = None
+
+ def __init__ (self, control_channel):
+ asyncore.dispatcher.__init__ (self)
+ self.control_channel = control_channel
+ self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
+ # bind to an address on the interface that the
+ # control connection is coming from.
+ self.bind ( (self.control_channel.getsockname()[0], 0) )
+ self.addr = self.getsockname()
+ self.listen(1)
+
+
+ def log (self, *ignore):
+ pass
+
+
+ def handle_accept (self):
+ conn, addr = self.accept()
+ dc = self.control_channel.client_dc
+ if dc is not None:
+ dc.set_socket(conn)
+ dc.addr = addr
+ dc.connected = 1
+ self.control_channel.passive_acceptor = None
+ else:
+ self.ready = conn, addr
+ self.close()
=== Zope3/lib/python/Zope/Server/FTP/PublisherFTPServer.py 1.1.2.1 => 1.1.2.2 ===
# 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.
-#
+#
##############################################################################
"""
=== Zope3/lib/python/Zope/Server/FTP/PublisherFTPTask.py 1.1.2.1 => 1.1.2.2 ===
-#
-# 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$
-"""
-
-from FTPTask import FTPTask
-from Zope.Publisher.Publish import publish
-
-
-class PublisherFTPTask(FTPTask):
- """ """
-
- __implements__ = FTPTask.__implements__
-
-
- def execute(self):
- """ """
- server = self.channel.server
- env = self.create_environment()
- instream = self.request_data.getBodyStream()
-
- request = server.request_factory(instream, self, env)
- publish(request)
-
-
- def create_environment(self):
- request_data = self.request_data
- channel = self.channel
- server = channel.server
-
- # This should probably change to reflect calling the FileSystem
- # methods
- env = {'command': request_data.command
- 'args': request_data.args
- }
-
-
- return env
+##############################################################################
+#
+# 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$
+"""
+
+from FTPTask import FTPTask
+from Zope.Publisher.Publish import publish
+
+
+class PublisherFTPTask(FTPTask):
+ """ """
+
+ __implements__ = FTPTask.__implements__
+
+
+ def execute(self):
+ """ """
+ server = self.channel.server
+ env = self.create_environment()
+ instream = self.request_data.getBodyStream()
+
+ request = server.request_factory(instream, self, env)
+ publish(request)
+
+
+ def create_environment(self):
+ request_data = self.request_data
+ channel = self.channel
+ server = channel.server
+
+ # This should probably change to reflect calling the FileSystem
+ # methods
+ env = {'command': request_data.command
+ 'args': request_data.args
+ }
+
+
+ return env
=== Zope3/lib/python/Zope/Server/FTP/RecvChannel.py 1.1.2.2 => 1.1.2.3 ===
-#
-# 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 Zope.Server.Counter import Counter
-
-class RecvChannel(asyncore.dispatcher):
- """ """
-
- def __init__ (self, channel, client_addr, fd):
- self.channel = channel
- self.client_addr = client_addr
- self.fd = fd
- asyncore.dispatcher.__init__ (self)
- self.bytes_in = Counter()
-
-
- def log (self, *ignore):
- pass
-
-
- def handle_connect (self):
- pass
-
-
- def writable (self):
- return 0
-
-
- def recv (*args):
- result = apply (asyncore.dispatcher.recv, args)
- self = args[0]
- self.bytes_in.increment(len(result))
- return result
-
-
- buffer_size = 8192
-
-
- def handle_read (self):
- block = self.recv (self.buffer_size)
- if block:
- try:
- self.fd.write (block)
- except IOError:
- self.log_info ('got exception writing block...', 'error')
-
-
- def handle_close (self):
- s = self.channel.server
- s.total_files_in.increment()
- s.total_bytes_in.increment(self.bytes_in.as_long())
- self.fd.close()
- self.channel.reply(226, 1)
- self.close()
+##############################################################################
+#
+# 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 Zope.Server.Counter import Counter
+
+class RecvChannel(asyncore.dispatcher):
+ """ """
+
+ def __init__ (self, channel, client_addr, fd):
+ self.channel = channel
+ self.client_addr = client_addr
+ self.fd = fd
+ asyncore.dispatcher.__init__ (self)
+ self.bytes_in = Counter()
+
+
+ def log (self, *ignore):
+ pass
+
+
+ def handle_connect (self):
+ pass
+
+
+ def writable (self):
+ return 0
+
+
+ def recv (*args):
+ result = apply (asyncore.dispatcher.recv, args)
+ self = args[0]
+ self.bytes_in.increment(len(result))
+ return result
+
+
+ buffer_size = 8192
+
+
+ def handle_read (self):
+ block = self.recv (self.buffer_size)
+ if block:
+ try:
+ self.fd.write (block)
+ except IOError:
+ self.log_info ('got exception writing block...', 'error')
+
+
+ def handle_close (self):
+ s = self.channel.server
+ s.total_files_in.increment()
+ s.total_bytes_in.increment(self.bytes_in.as_long())
+ self.fd.close()
+ self.channel.reply(226, 1)
+ self.close()
=== Zope3/lib/python/Zope/Server/FTP/XmitChannel.py 1.1.2.1 => 1.1.2.2 ===
-#
-# 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 asynchat
-
-
-class XmitChannel(asynchat.async_chat, object):
-
- # for an ethernet, you want this to be fairly large, in fact, it
- # _must_ be large for performance comparable to an ftpd. [64k] we
- # ought to investigate automatically-sized buffers...
- ac_out_buffer_size = 16384
-
- bytes_out = 0
-
- def __init__ (self, channel, client_addr=None):
- self.channel = channel
- self.client_addr = client_addr
- super(XmitChannel, self).__init__()
-
-
- def log (*args):
- pass
-
-
- def readable (self):
- return not self.connected
-
-
- def writable (self):
- return 1
-
-
- def send (self, data):
- result = super(XmitChannel, self).send(data)
- self.bytes_out = self.bytes_out + result
- return result
-
-
- def handle_error (self):
- # usually this is to catch an unexpected disconnect.
- # XXX: Helpfule for debugging
- import traceback
- traceback.print_exc()
- self.log_info ('unexpected disconnect on data xmit channel', 'error')
- try:
- self.close()
- except:
- pass
-
- # TODO: there's a better way to do this. we need to be able to
- # put 'events' in the producer fifo. to do this cleanly we need
- # to reposition the 'producer' fifo as an 'event' fifo.
-
- # dummy function to suppress warnings caused by some FTP clients
- def handle_connect(self):
- pass
-
-
- def close (self):
- c = self.channel
- s = c.server
- c.client_dc = None
- s.total_files_out.increment()
- s.total_bytes_out.increment (self.bytes_out)
- if not len(self.producer_fifo):
- c.reply(226, 1)
- elif not c.closed:
- c.reply(426)
- del c
- del s
- del self.channel
- asynchat.async_chat.close(self)
+##############################################################################
+#
+# 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 asynchat
+
+
+class XmitChannel(asynchat.async_chat, object):
+
+ # for an ethernet, you want this to be fairly large, in fact, it
+ # _must_ be large for performance comparable to an ftpd. [64k] we
+ # ought to investigate automatically-sized buffers...
+ ac_out_buffer_size = 16384
+
+ bytes_out = 0
+
+ def __init__ (self, channel, client_addr=None):
+ self.channel = channel
+ self.client_addr = client_addr
+ super(XmitChannel, self).__init__()
+
+
+ def log (*args):
+ pass
+
+
+ def readable (self):
+ return not self.connected
+
+
+ def writable (self):
+ return 1
+
+
+ def send (self, data):
+ result = super(XmitChannel, self).send(data)
+ self.bytes_out = self.bytes_out + result
+ return result
+
+
+ def handle_error (self):
+ # usually this is to catch an unexpected disconnect.
+ # XXX: Helpfule for debugging
+ import traceback
+ traceback.print_exc()
+ self.log_info ('unexpected disconnect on data xmit channel', 'error')
+ try:
+ self.close()
+ except:
+ pass
+
+ # TODO: there's a better way to do this. we need to be able to
+ # put 'events' in the producer fifo. to do this cleanly we need
+ # to reposition the 'producer' fifo as an 'event' fifo.
+
+ # dummy function to suppress warnings caused by some FTP clients
+ def handle_connect(self):
+ pass
+
+
+ def close (self):
+ c = self.channel
+ s = c.server
+ c.client_dc = None
+ s.total_files_out.increment()
+ s.total_bytes_out.increment (self.bytes_out)
+ if not len(self.producer_fifo):
+ c.reply(226, 1)
+ elif not c.closed:
+ c.reply(426)
+ del c
+ del s
+ del self.channel
+ asynchat.async_chat.close(self)
=== Zope3/lib/python/Zope/Server/FTP/__init__.py 1.1.2.1 => 1.1.2.2 ===
-#
-# 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$
-"""
+##############################################################################
+#
+# 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$
+"""