[Zope3-checkins] CVS: Zope3/src/zope/server/linereceiver - __init__.py:1.2 linecommandparser.py:1.2 lineserverchannel.py:1.2 linetask.py:1.2
Jim Fulton
jim@zope.com
Wed, 25 Dec 2002 09:15:57 -0500
Update of /cvs-repository/Zope3/src/zope/server/linereceiver
In directory cvs.zope.org:/tmp/cvs-serv20790/src/zope/server/linereceiver
Added Files:
__init__.py linecommandparser.py lineserverchannel.py
linetask.py
Log Message:
Grand renaming:
- Renamed most files (especially python modules) to lower case.
- Moved views and interfaces into separate hierarchies within each
project, where each top-level directory under the zope package
is a separate project.
- Moved everything to src from lib/python.
lib/python will eventually go away. I need access to the cvs
repository to make this happen, however.
There are probably some bits that are broken. All tests pass
and zope runs, but I haven't tried everything. There are a number
of cleanups I'll work on tomorrow.
=== Zope3/src/zope/server/linereceiver/__init__.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:15:57 2002
+++ Zope3/src/zope/server/linereceiver/__init__.py Wed Dec 25 09:15:26 2002
@@ -0,0 +1,2 @@
+#
+# This file is necessary to make this directory a package.
=== Zope3/src/zope/server/linereceiver/linecommandparser.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:15:57 2002
+++ Zope3/src/zope/server/linereceiver/linecommandparser.py Wed Dec 25 09:15:26 2002
@@ -0,0 +1,70 @@
+##############################################################################
+#
+# 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.interfaces import IStreamConsumer
+
+
+class LineCommandParser:
+ """Line Command parser. Arguments are left alone for now."""
+
+ __implements__ = IStreamConsumer
+
+ # See 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
+
+
+ def received(self, data):
+ 'See 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/src/zope/server/linereceiver/lineserverchannel.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:15:57 2002
+++ Zope3/src/zope/server/linereceiver/lineserverchannel.py Wed Dec 25 09:15:26 2002
@@ -0,0 +1,120 @@
+##############################################################################
+#
+# 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 sys
+
+from zope.server.serverchannelbase import ServerChannelBase
+from zope.server.linereceiver.linecommandparser import LineCommandParser
+from zope.server.linereceiver.linetask import LineTask
+
+
+DEBUG = os.environ.get('ZOPE_SERVER_DEBUG')
+
+
+class LineServerChannel(ServerChannelBase):
+ """The Line Server Channel represents a connection to a particular
+ client. We can therefore store information here."""
+
+ __implements__ = ServerChannelBase.__implements__
+
+ # Wrapper class that is used to execute a command in a different thread
+ task_class = LineTask
+
+ # Class that is being initialized to parse the input
+ parser_class = LineCommandParser
+
+ # List of commands that are always available
+ special_commands = ('cmd_quit')
+
+ # Commands that are run in a separate thread
+ thread_commands = ()
+
+ # Define the authentication status of the channel. Note that only the
+ # "special commands" can be executed without having authenticated.
+ authenticated = 0
+
+ # Define the reply code for non-authenticated responses
+ not_auth_reply = 'LOGIN_REQUIRED'
+
+ # Define the reply code for an unrecognized command
+ unknown_reply = 'CMD_UNKNOWN'
+
+ # Define the error message that occurs, when the reply code was not found.
+ reply_error = '500 Unknown Reply Code: %s.'
+
+ # Define the status messages
+ status_messages = {
+ 'CMD_UNKNOWN' : "500 '%s': command not understood.",
+ 'INTERNAL_ERROR' : "500 Internal error: %s",
+ 'LOGIN_REQUIRED' : '530 Please log in with USER and PASS',
+ }
+
+
+ def process_request(self, command):
+ """Processes a command.
+
+ Some commands use an alternate thread.
+ """
+ assert isinstance(command, LineCommandParser)
+ cmd = command.cmd
+ method = 'cmd_' + cmd.lower()
+ if ( not self.authenticated and method not in self.special_commands):
+ # The user is not logged in, therefore don't allow anything
+ self.reply(self.not_auth_reply)
+
+ elif method in self.thread_commands:
+ # Process in another thread.
+ return self.task_class(self, command, method)
+
+ elif hasattr(self, method):
+ try:
+ getattr(self, method)(command.args)
+ except:
+ self.exception()
+ else:
+ self.reply(self.unknown_reply, cmd.upper())
+ return None
+
+
+ def reply(self, code, args=(), flush=1):
+ """ """
+ try:
+ msg = self.status_messages[code] %args
+ except:
+ msg = self.reply_error %code
+
+ self.write('%s\r\n' %msg)
+
+ if flush:
+ self.flush(0)
+
+ # XXX: Some logging should go on here.
+
+
+ def exception(self):
+ if DEBUG:
+ import traceback
+ traceback.print_exc()
+ t, v = sys.exc_info()[:2]
+ try:
+ info = '%s: %s' % (getattr(t, '__name__', t), v)
+ except:
+ info = str(t)
+ self.reply('INTERNAL_ERROR', info)
+ self.handle_error()
=== Zope3/src/zope/server/linereceiver/linetask.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:15:57 2002
+++ Zope3/src/zope/server/linereceiver/linetask.py Wed Dec 25 09:15:26 2002
@@ -0,0 +1,74 @@
+##############################################################################
+#
+# 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.interfaces import ITask
+
+
+class LineTask:
+ """This is a generic task that can be used with command line
+ protocols to handle commands in a separate thread.
+ """
+
+ __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
+
+ 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
+ except:
+ self.channel.exception()
+ finally:
+ self.channel.end_task(self.close_on_finish)
+
+
+ def cancel(self):
+ 'See ITask'
+ self.channel.close_when_done()
+
+
+ def defer(self):
+ 'See 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)