[Zope3-checkins] CVS: Zope3/src/zope/server/linereceiver - __init__.py:1.1.2.1 linecommandparser.py:1.1.2.1 lineserverchannel.py:1.1.2.1 linetask.py:1.1.2.1
Jim Fulton
jim@zope.com
Mon, 23 Dec 2002 14:33:24 -0500
Update of /cvs-repository/Zope3/src/zope/server/linereceiver
In directory cvs.zope.org:/tmp/cvs-serv19908/zope/server/linereceiver
Added Files:
Tag: NameGeddon-branch
__init__.py linecommandparser.py lineserverchannel.py
linetask.py
Log Message:
Initial renaming before debugging
=== Added File Zope3/src/zope/server/linereceiver/__init__.py ===
#
# This file is necessary to make this directory a package.
=== Added File Zope3/src/zope/server/linereceiver/linecommandparser.py ===
##############################################################################
#
# 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: linecommandparser.py,v 1.1.2.1 2002/12/23 19:33:23 jim Exp $
"""
from zope.server.interfaces.interfaces import IStreamConsumer
class LineCommandParser:
"""Line 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]
=== Added File Zope3/src/zope/server/linereceiver/lineserverchannel.py ===
##############################################################################
#
# 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: lineserverchannel.py,v 1.1.2.1 2002/12/23 19:33:23 jim Exp $
"""
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()
=== Added File Zope3/src/zope/server/linereceiver/linetask.py ===
##############################################################################
#
# 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: linetask.py,v 1.1.2.1 2002/12/23 19:33:23 jim Exp $
"""
import socket
import time
from zope.server.interfaces.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
############################################################
# 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
except:
self.channel.exception()
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)