[Zope-Checkins] CVS: Zope/ZServer - DebugLogger.py:1.8 FCGIServer.py:1.20 FTPRequest.py:1.14 FTPResponse.py:1.11 FTPServer.py:1.23 HTTPResponse.py:1.41 HTTPServer.py:1.41 ICPServer.py:1.2 PCGIServer.py:1.24 Producers.py:1.7 WebDAVSrcHandler.py:1.8 ZService.py:1.14 __init__.py:1.27
Martijn Pieters
mj@zope.com
Wed, 14 Aug 2002 17:16:51 -0400
Update of /cvs-repository/Zope/ZServer
In directory cvs.zope.org:/tmp/cvs-serv7904
Modified Files:
DebugLogger.py FCGIServer.py FTPRequest.py FTPResponse.py
FTPServer.py HTTPResponse.py HTTPServer.py ICPServer.py
PCGIServer.py Producers.py WebDAVSrcHandler.py ZService.py
__init__.py
Log Message:
Clean up indentation and trailing whitespace.
=== Zope/ZServer/DebugLogger.py 1.7 => 1.8 ===
--- Zope/ZServer/DebugLogger.py:1.7 Tue Jun 11 18:02:47 2002
+++ Zope/ZServer/DebugLogger.py Wed Aug 14 17:16:50 2002
@@ -1,14 +1,14 @@
##############################################################################
#
# Copyright (c) 2001 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
-#
+#
##############################################################################
import time, thread
@@ -17,27 +17,27 @@
"""
Logs debugging information about how ZServer is handling requests
and responses. This log can be used to help locate troublesome requests.
-
+
The format is:
-
+
<code> <request id> <time> <data>
-
+
where:
-
+
'code' is B for begin, I for received input, A for received output,
E for sent output.
-
+
'request id' is a unique request id.
-
+
'time' is the time in localtime ISO format.
-
+
'data' is the HTTP method and the PATH INFO for B, the size of the input
for I, the HTTP status code and the size of the output for A, or
nothing for E.
-
+
Note: This facility will be probably be adapted to the zLOG framework.
"""
-
+
def __init__(self, filename):
self.filename = filename
self.file=open(filename, 'a+b')
@@ -45,7 +45,7 @@
self._acquire=l.acquire
self._release=l.release
self.log('U', '000000000', 'System startup')
-
+
def reopen(self):
self.file.close()
self.file=open(self.filename, 'a+b')
@@ -64,4 +64,3 @@
def log(*args): pass
-
=== Zope/ZServer/FCGIServer.py 1.19 => 1.20 ===
--- Zope/ZServer/FCGIServer.py:1.19 Wed Aug 14 14:24:23 2002
+++ Zope/ZServer/FCGIServer.py Wed Aug 14 17:16:50 2002
@@ -1,14 +1,14 @@
##############################################################################
#
# Copyright (c) 2001 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
-#
+#
##############################################################################
"""
@@ -271,7 +271,7 @@
"""
closed=0
using_temp_stdin=None
-
+
def __init__(self, server, sock, addr):
self.server = server
self.addr = addr
@@ -361,7 +361,7 @@
# Read some name-value pairs (the CGI environment)
elif rec.recType == FCGI_PARAMS:
if rec.contentLength == 0: # end of the stream
-
+
if self.env.has_key('REQUEST_METHOD'):
method=self.env['REQUEST_METHOD']
else:
@@ -370,8 +370,8 @@
path=self.env['PATH_INFO']
else:
path=''
- DebugLogger.log('B', id(self), '%s %s' % (method, path))
-
+ DebugLogger.log('B', id(self), '%s %s' % (method, path))
+
self.remainingRecs = self.remainingRecs - 1
self.content_length=string.atoi(self.env.get(
'CONTENT_LENGTH','0'))
@@ -383,7 +383,7 @@
if rec.contentLength == 0: # end of the stream
self.remainingRecs = self.remainingRecs - 1
else:
- # see if stdin is getting too big, and
+ # see if stdin is getting too big, and
# replace it with a tempfile if necessary
if len(rec.content) + self.stdin.tell() > 1048576 and \
not self.using_temp_stdin:
@@ -392,7 +392,7 @@
self.stdin=t
self.using_temp_stdin=1
self.stdin.write(rec.content)
-
+
# read some filter data
elif rec.recType == FCGI_DATA:
@@ -435,7 +435,7 @@
def log_request(self, bytes):
-
+
DebugLogger.log('E', id(self))
if self.env.has_key('HTTP_USER_AGENT'):
@@ -446,7 +446,7 @@
referer=self.env['HTTP_REFERER']
else:
referer=''
-
+
if self.env.has_key('PATH_INFO'):
path=self.env['PATH_INFO']
else:
@@ -525,7 +525,7 @@
hdr = string.join(map(chr, hdr), '')
self.push(hdr, 0)
self.push(p, 0)
- self.push(padLen * '\000', 0)
+ self.push(padLen * '\000', 0)
def sendStreamTerminator(self, recType):
rec = FCGIRecord()
@@ -545,7 +545,7 @@
def push(self, producer, send=1):
# this is thread-safe when send is false
- # note, that strings are not wrapped in
+ # note, that strings are not wrapped in
# producers by default
if self.closed:
return
@@ -660,17 +660,17 @@
#----------------------------------------------------------------------
class FCGIResponse(HTTPResponse):
-
+
_tempfile=None
_templock=None
_tempstart=0
-
+
def setChannel(self, channel):
self.channel = channel
def write(self, data):
stdout=self.stdout
-
+
if not self._wrote:
l=self.headers.get('content-length', None)
if l is not None:
@@ -680,7 +680,7 @@
self._tempfile=TemporaryFile()
self._templock=thread.allocate_lock()
except: pass
-
+
stdout.write(str(self))
self._wrote=1
@@ -709,10 +709,10 @@
def _finish(self):
self.channel.reply_code=self.status
-
+
DebugLogger.log('A', id(self.channel), '%d %d' % (
self.status, self.stdout.length))
-
+
t=self._tempfile
if t is not None:
self.stdout.write((file_close_producer(t), 0))
@@ -764,6 +764,3 @@
#----------------------------------------------------------------------
-
-
-
=== Zope/ZServer/FTPRequest.py 1.13 => 1.14 ===
--- Zope/ZServer/FTPRequest.py:1.13 Wed Nov 28 10:50:50 2001
+++ Zope/ZServer/FTPRequest.py Wed Aug 14 17:16:50 2002
@@ -1,14 +1,14 @@
##############################################################################
#
# Copyright (c) 2001 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
-#
+#
##############################################################################
"""
FTP Request class for FTP server.
@@ -30,18 +30,18 @@
environ=None,globbing=None,recursive=0):
# we need to store the globbing information to pass it
- # to the ZPublisher and the manage_FTPlist function
+ # to the ZPublisher and the manage_FTPlist function
# (ajung)
self.globbing = globbing
self.recursive= recursive
-
+
if stdin is None: stdin=StringIO()
if environ is None:
environ=self._get_env(path, command, channel, stdin)
self._orig_env=environ
HTTPRequest.__init__(self, stdin, environ, response, clean=1)
-
+
# support for cookies and cookie authentication
self.cookies=channel.cookies
if not self.cookies.has_key('__ac') and channel.userid != 'anonymous':
@@ -50,8 +50,8 @@
for k,v in self.cookies.items():
if not self.other.has_key(k):
self.other[k]=v
-
-
+
+
def retry(self):
self.retry_count=self.retry_count+1
r=self.__class__(stdin=self.stdin,
@@ -60,7 +60,7 @@
channel=self, # For my cookies
)
return r
-
+
def _get_env(self, path, command, channel, stdin):
"Returns a CGI style environment"
env={}
@@ -74,35 +74,35 @@
env['SERVER_PORT']=str(channel.server.port)
env['REMOTE_ADDR']=channel.client_addr[0]
env['GATEWAY_INTERFACE']='CGI/1.1' # that's stretching it ;-)
-
+
# FTP commands
#
if type(command)==type(()):
args=command[1:]
command=command[0]
if command in ('LST','CWD','PASS'):
- env['PATH_INFO']=self._join_paths(channel.path,
+ env['PATH_INFO']=self._join_paths(channel.path,
path, 'manage_FTPlist')
elif command in ('MDTM','SIZE'):
- env['PATH_INFO']=self._join_paths(channel.path,
+ env['PATH_INFO']=self._join_paths(channel.path,
path, 'manage_FTPstat')
elif command=='RETR':
- env['PATH_INFO']=self._join_paths(channel.path,
+ env['PATH_INFO']=self._join_paths(channel.path,
path, 'manage_FTPget')
elif command in ('RMD','DELE'):
- env['PATH_INFO']=self._join_paths(channel.path,
+ env['PATH_INFO']=self._join_paths(channel.path,
path, 'manage_delObjects')
env['QUERY_STRING']='ids=%s' % args[0]
elif command=='MKD':
- env['PATH_INFO']=self._join_paths(channel.path,
+ env['PATH_INFO']=self._join_paths(channel.path,
path, 'manage_addFolder')
env['QUERY_STRING']='id=%s' % args[0]
elif command=='RNTO':
- env['PATH_INFO']=self._join_paths(channel.path,
+ env['PATH_INFO']=self._join_paths(channel.path,
path, 'manage_renameObject')
env['QUERY_STRING']='id=%s&new_id=%s' % (args[0],args[1])
-
+
elif command=='STOR':
env['PATH_INFO']=self._join_paths(channel.path, path)
env['REQUEST_METHOD']='PUT'
@@ -110,22 +110,15 @@
else:
env['PATH_INFO']=self._join_paths(channel.path, path, command)
- # Fake in globbing information
+ # Fake in globbing information
env['GLOBBING'] = self.globbing
env['FTP_RECURSIVE'] = self.recursive
return env
-
+
def _join_paths(self,*args):
path=apply(os.path.join,args)
path=os.path.normpath(path)
if os.sep != '/':
path=path.replace(os.sep,'/')
return path
-
-
-
-
-
-
-
=== Zope/ZServer/FTPResponse.py 1.10 => 1.11 ===
--- Zope/ZServer/FTPResponse.py:1.10 Thu Feb 14 09:56:53 2002
+++ Zope/ZServer/FTPResponse.py Wed Aug 14 17:16:50 2002
@@ -1,14 +1,14 @@
##############################################################################
#
# Copyright (c) 2001 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
-#
+#
##############################################################################
"""
Response class for the FTP Server.
@@ -41,7 +41,7 @@
self.cookies[name]=self.cookies[name] + value
def expireCookie(self, name, **kw):
- if self.cookies.has_key(name):
+ if self.cookies.has_key(name):
del self.cookies[name]
def _cookie_list(self):
@@ -55,7 +55,7 @@
def getMessage(self):
return getattr(self, '_message', '')
-
+
class CallbackPipe:
"""
Sends response object to a callback. Doesn't write anything.
@@ -65,27 +65,27 @@
self._callback=callback
self._args=args
self._producers=[]
-
+
def close(self):
pass
-
+
def write(self, text, l=None):
if text:
self._producers.append(text)
-
+
def finish(self, response):
self._response=response
Wakeup(self.apply) # move callback to medusas thread
-
+
def apply(self):
result=apply(self._callback, self._args+(self._response,))
-
+
# break cycles
self._callback=None
self._response=None
self._args=None
-
- return result
+
+ return result
def make_response(channel, callback, *args):
# XXX should this be the FTPResponse constructor instead?
=== Zope/ZServer/FTPServer.py 1.22 => 1.23 ===
--- Zope/ZServer/FTPServer.py:1.22 Thu Mar 21 13:29:15 2002
+++ Zope/ZServer/FTPServer.py Wed Aug 14 17:16:50 2002
@@ -1,14 +1,14 @@
##############################################################################
#
# Copyright (c) 2001 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
-#
+#
##############################################################################
"""ZServer FTP Channel for use the medusa's ftp server.
@@ -84,10 +84,10 @@
class zope_ftp_channel(ftp_channel):
"Passes its commands to Zope, not a filesystem"
-
+
read_only=0
anonymous=1
-
+
def __init__ (self, server, conn, addr, module):
ftp_channel.__init__(self,server,conn,addr)
requestCloseOnExec(conn)
@@ -96,26 +96,26 @@
self.password=''
self.path='/'
self.cookies={}
-
+
def _join_paths(self,*args):
path=apply(os.path.join,args)
path=os.path.normpath(path)
if os.sep != '/':
path=path.replace(os.sep,'/')
return path
-
+
# Overriden async_chat methods
def push(self, producer, send=1):
# this is thread-safe when send is false
- # note, that strings are not wrapped in
+ # note, that strings are not wrapped in
# producers by default
self.producer_fifo.push(producer)
if send: self.initiate_send()
-
+
push_with_producer=push
-
-
+
+
# Overriden ftp_channel methods
def cmd_nlst (self, line):
@@ -124,12 +124,12 @@
def cmd_list (self, line):
'give list files in a directory'
-
+
# handles files as well as directories.
# XXX also should maybe handle globbing, yuck.
-
+
self.get_dir_list(line,1)
-
+
def get_dir_list(self, line, long=0):
self.globbing = None
self.recursive = 0
@@ -142,14 +142,14 @@
args =[]
path_args = []
- # Extract globbing information
+ # Extract globbing information
+
-
for i in range(len(args)):
x = args[i]
if x.find('*')!=-1 or x.find('?')!=-1:
self.globbing = x
- args[i] = '.'
+ args[i] = '.'
for arg in args:
if arg[0] != '-':
@@ -166,12 +166,12 @@
dir = path_args[0]
self.listdir(dir, long)
-
+
def listdir (self, path, long=0):
response=make_response(self, self.listdir_completion, long)
request=FTPRequest(path, 'LST', self, response,globbing=self.globbing,recursive=self.recursive)
- handle(self.module, request, response)
-
+ handle(self.module, request, response)
+
def listdir_completion(self, long, response):
status=response.getStatus()
if status==200:
@@ -180,7 +180,7 @@
dir_list=''
file_infos=response._marshalledBody()
if type(file_infos[0])==type(''):
- file_infos=(file_infos,)
+ file_infos=(file_infos,)
if long:
for id, stat_info in file_infos:
dir_list=dir_list+filesys.unix_longify(id,stat_info)+'\r\n'
@@ -189,12 +189,12 @@
dir_list=dir_list+id+'\r\n'
self.make_xmit_channel()
self.client_dc.push(dir_list)
- self.client_dc.close_when_done()
+ self.client_dc.close_when_done()
self.respond(
'150 Opening %s mode data connection for file list' % (
self.type_map[self.current_mode]
)
- )
+ )
elif status==401:
self.respond('530 Unauthorized.')
else:
@@ -202,10 +202,10 @@
def cmd_cwd (self, line):
'change working directory'
- response=make_response(self, self.cwd_completion,
+ response=make_response(self, self.cwd_completion,
self._join_paths(self.path,line[1]))
request=FTPRequest(line[1],'CWD',self,response)
- handle(self.module,request,response)
+ handle(self.module,request,response)
def cwd_completion(self,path,response):
'cwd completion callback'
@@ -239,9 +239,9 @@
self.path
)
)
-
+
cmd_xpwd=cmd_pwd
-
+
def cmd_mdtm(self, line):
'show last modification time of file'
if len (line) != 2:
@@ -249,8 +249,8 @@
return
response=make_response(self, self.mdtm_completion)
request=FTPRequest(line[1],'MDTM',self,response)
- handle(self.module,request,response)
-
+ handle(self.module,request,response)
+
def mdtm_completion(self, response):
status=response.getStatus()
if status==200:
@@ -265,10 +265,10 @@
mtime[5]
))
elif status==401:
- self.respond('530 Unauthorized.')
+ self.respond('530 Unauthorized.')
else:
- self.respond('550 Error getting file modification time.')
-
+ self.respond('550 Error getting file modification time.')
+
def cmd_size(self, line):
'return size of file'
if len (line) != 2:
@@ -276,17 +276,17 @@
return
response=make_response(self, self.size_completion)
request=FTPRequest(line[1],'SIZE',self,response)
- handle(self.module,request,response)
-
+ handle(self.module,request,response)
+
def size_completion(self,response):
status=response.getStatus()
if status==200:
self.respond('213 %d'% response._marshalledBody()[stat.ST_SIZE])
elif status==401:
- self.respond('530 Unauthorized.')
+ self.respond('530 Unauthorized.')
else:
- self.respond('550 Error getting file size.')
-
+ self.respond('550 Error getting file size.')
+
#self.client_dc.close_when_done()
def cmd_retr(self,line):
@@ -299,9 +299,9 @@
# Support download restarts if possible.
if self.restart_position > 0:
request.environ['HTTP_RANGE'] = 'bytes=%d-' % self.restart_position
- handle(self.module,request,response)
+ handle(self.module,request,response)
- def retr_completion(self, file, response):
+ def retr_completion(self, file, response):
status=response.getStatus()
if status==200:
self.make_xmit_channel()
@@ -320,7 +320,7 @@
elif status==401:
self.respond('530 Unauthorized.')
else:
- self.respond('550 Error opening file.')
+ self.respond('550 Error opening file.')
def cmd_stor (self, line, mode='wb'):
'store a file'
@@ -331,11 +331,11 @@
restart_position = 0
self.respond ('553 restart on STOR not yet supported')
return
-
+
# XXX Check for possible problems first?
# Right now we are limited in the errors we can issue, since
# we agree to accept the file before checking authorization
-
+
fd=ContentReceiver(self.stor_callback, line[1])
self.respond (
'150 Opening %s connection for %s' % (
@@ -344,13 +344,13 @@
)
)
self.make_recv_channel(fd)
-
+
def stor_callback(self,path,data):
'callback to do the STOR, after we have the input'
response=make_response(self, self.stor_completion)
request=FTPRequest(path,'STOR',self,response,stdin=data)
- handle(self.module,request,response)
-
+ handle(self.module,request,response)
+
def stor_completion(self,response):
status=response.getStatus()
message = response.getMessage()
@@ -382,9 +382,9 @@
patht,idt=os.path.split(line[1])
response=make_response(self, self.rnto_completion)
request=FTPRequest(pathf,('RNTO',idf,idt),self,response)
- handle(self.module,request,response)
+ handle(self.module,request,response)
- def rnto_completion(self,response):
+ def rnto_completion(self,response):
status=response.getStatus()
if status==200:
self.respond ('250 RNTO command successful.')
@@ -398,16 +398,16 @@
path,id=os.path.split(line[1])
response=make_response(self, self.dele_completion)
request=FTPRequest(path,('DELE',id),self,response)
- handle(self.module,request,response)
-
- def dele_completion(self,response):
+ handle(self.module,request,response)
+
+ def dele_completion(self,response):
status=response.getStatus()
if status==200 and response.body.find('Not Deletable')==-1:
self.respond('250 DELE command successful.')
elif status==401:
- self.respond('530 Unauthorized.')
+ self.respond('530 Unauthorized.')
else:
- self.respond('550 Error deleting file.')
+ self.respond('550 Error deleting file.')
def cmd_mkd(self, line):
if len (line) != 2:
@@ -416,10 +416,10 @@
path,id=os.path.split(line[1])
response=make_response(self, self.mkd_completion)
request=FTPRequest(path,('MKD',id),self,response)
- handle(self.module,request,response)
-
+ handle(self.module,request,response)
+
cmd_xmkd=cmd_mkd
-
+
def mkd_completion(self,response):
status=response.getStatus()
if status==200:
@@ -438,8 +438,8 @@
path,id=os.path.split(line[1])
response=make_response(self, self.rmd_completion)
request=FTPRequest(path,('RMD',id),self,response)
- handle(self.module,request,response)
-
+ handle(self.module,request,response)
+
cmd_xrmd=cmd_rmd
def rmd_completion(self,response):
@@ -447,9 +447,9 @@
if status==200 and response.body.find('Not Deletable')==-1:
self.respond('250 RMD command successful.')
elif status==401:
- self.respond('530 Unauthorized.')
+ self.respond('530 Unauthorized.')
else:
- self.respond('550 Error removing directory.')
+ self.respond('550 Error removing directory.')
def cmd_user(self, line):
'specify user name'
@@ -476,14 +476,14 @@
else:
self.respond('421 User limit reached. Closing connection.')
self.close_when_done()
- else:
+ else:
path=self.userid[i+1:]
self.userid=self.userid[:i]
self.anonymous=None
response=make_response(self, self.pass_completion,
self._join_paths('/',path))
request=FTPRequest(path,'PASS',self,response)
- handle(self.module,request,response)
+ handle(self.module,request,response)
def pass_completion(self,path,response):
@@ -491,7 +491,7 @@
if status==200:
if not self.server.limiter.check_limit(self):
self.close_when_done()
- self.respond('421 User limit reached. Closing connection.')
+ self.respond('421 User limit reached. Closing connection.')
return
listing=response._marshalledBody()
# check to see if we are cding to a non-foldoid object
@@ -502,17 +502,17 @@
self.authorized = 1
if self.userid=='anonymous':
self.anonymous=1
- self.log_info('Successful login.')
+ self.log_info('Successful login.')
self.respond('230 Login successful.')
else:
self.respond('530 Unauthorized.')
-
+
def cmd_appe(self, line):
self.respond('502 Command not implemented.')
-# Override ftp server receive channel reponse mechanism
+# Override ftp server receive channel reponse mechanism
# XXX hack alert, this should probably be redone in a more OO way.
def handle_close (self):
@@ -525,18 +525,18 @@
recv_channel.handle_close=handle_close
-
+
class ContentReceiver:
"Write-only file object used to receive data from FTP"
-
+
def __init__(self,callback,*args):
self.data=StringIO()
self.callback=callback
self.args=args
-
+
def write(self,data):
self.data.write(data)
-
+
def close(self):
self.data.seek(0)
args=self.args+(self.data,)
@@ -556,12 +556,12 @@
limit number of simultaneous connections. The total limit is the
maximum number of simultaneous connections of any sort. Do *not*
set the total limit lower than or equal to the anonymous limit."""
-
+
def __init__(self,anon_limit=10,user_limit=4,total_limit=25):
self.anon_limit=anon_limit
self.user_limit=user_limit
self.total_limit=total_limit
-
+
def check_limit(self,channel):
"""Check to see if the user has exhausted their limit or not.
Check for existing channels with the same userid and the same
@@ -577,7 +577,7 @@
class_total=class_total+1
if class_total > self.anon_limit:
return None
- else:
+ else:
for existing_channel in asyncore.socket_map.values():
if (hasattr(existing_channel,'server') and
existing_channel.server is channel.server):
@@ -589,10 +589,10 @@
if total <= self.total_limit:
return 1
-
+
class FTPServer(ftp_server):
"""FTP server for Zope."""
-
+
ftp_channel_class = zope_ftp_channel
limiter=FTPLimiter(10,1)
shutup=0
@@ -604,10 +604,10 @@
self.module=module
self.log_info('FTP server started at %s\n'
'\tHostname: %s\n\tPort: %d' % (
- time.ctime(time.time()),
- self.hostname,
- self.port
- ))
+ time.ctime(time.time()),
+ self.hostname,
+ self.port
+ ))
def log_info(self, message, type='info'):
if self.shutup: return
@@ -626,7 +626,7 @@
return
self.total_sessions.increment()
self.log_info('Incoming connection from %s:%d' % (addr[0], addr[1]))
- self.ftp_channel_class (self, conn, addr, self.module)
+ self.ftp_channel_class (self, conn, addr, self.module)
def readable(self):
return len(asyncore.socket_map) < CONNECTION_LIMIT
=== Zope/ZServer/HTTPResponse.py 1.40 => 1.41 ===
--- Zope/ZServer/HTTPResponse.py:1.40 Mon Apr 15 16:58:48 2002
+++ Zope/ZServer/HTTPResponse.py Wed Aug 14 17:16:50 2002
@@ -1,14 +1,14 @@
##############################################################################
#
# Copyright (c) 2001 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
-#
+#
##############################################################################
"""
ZServer HTTPResponse
@@ -39,7 +39,7 @@
# HTTP/1.1 should use chunked encoding
http_chunk=1
http_chunk_size=1024
-
+
# defaults
_http_version='1.0'
_http_connection='close'
@@ -75,16 +75,16 @@
not self._streaming:
self.setHeader('content-length',len(body))
-
+
content_length= headers.get('content-length', None)
- if content_length>0 :
+ if content_length>0 :
self.setHeader('content-length', content_length)
headersl=[]
append=headersl.append
-
+
status=headers.get('status', '200 OK')
-
+
# status header must come first.
append("HTTP/%s %s" % (self._http_version or '1.0' , status))
if headers.has_key('status'):
@@ -92,9 +92,9 @@
if not headers.has_key("Etag"):
self.setHeader('Etag','')
-
+
# add zserver headers
- append('Server: %s' % self._server_version)
+ append('Server: %s' % self._server_version)
append('Date: %s' % build_http_date(time.time()))
if self._http_version=='1.0':
@@ -103,7 +103,7 @@
self.setHeader('Connection','Keep-Alive')
else:
self.setHeader('Connection','close')
-
+
# Close the connection if we have been asked to.
# Use chunking if streaming output.
if self._http_version=='1.1':
@@ -114,8 +114,8 @@
self.setHeader('Transfer-Encoding','chunked')
self._chunking=1
else:
- self.setHeader('Connection','close')
-
+ self.setHeader('Connection','close')
+
for key, val in headers.items():
if key.lower()==key:
# only change non-literal header names
@@ -135,7 +135,7 @@
_tempfile=None
_templock=None
_tempstart=0
-
+
def write(self,data):
"""\
Return data as a stream
@@ -148,11 +148,11 @@
cookies on the response object.
Note that published objects must not generate any errors
- after beginning stream-oriented output.
+ after beginning stream-oriented output.
"""
stdout=self.stdout
-
+
if not self._wrote:
l=self.headers.get('content-length', None)
if l is not None:
@@ -173,7 +173,7 @@
data = '%x\r\n%s\r\n' % (len(data),data)
l=len(data)
-
+
t=self._tempfile
if t is None or l<200:
stdout.write(data)
@@ -188,7 +188,7 @@
self._templock.release()
self._tempstart=e
stdout.write(file_part_producer(t,self._templock,b,e), l)
-
+
_retried_response = None
def _finish(self):
@@ -204,10 +204,10 @@
if t is not None:
stdout.write(file_close_producer(t), 0)
self._tempfile=None
-
+
stdout.finish(self)
stdout.close()
-
+
self.stdout=None # need to break cycle?
self._request=None
@@ -239,7 +239,7 @@
self._shutdown=0
self._close=0
self._bytes=0
-
+
def write(self, text, l=None):
if self._channel.closed:
return
@@ -247,9 +247,9 @@
self._bytes=self._bytes + l
self._channel.push(text,0)
Wakeup()
-
+
def close(self):
- DebugLogger.log('A', id(self._request),
+ DebugLogger.log('A', id(self._request),
'%s %s' % (self._request.reply_code, self._bytes))
if not self._channel.closed:
self._channel.push(LoggingProducer(self._request, self._bytes), 0)
@@ -277,7 +277,7 @@
self._request=None
def flush(self): pass # yeah, whatever
-
+
def finish(self, response):
if response._shutdownRequested():
self._shutdown = 1
@@ -285,15 +285,15 @@
response.headers.get('Connection','') == 'close':
self._close=1
self._request.reply_code=response.status
-
+
is_proxying_match = re.compile(r'[^ ]* [^ \\]*:').match
proxying_connection_re = re.compile ('Proxy-Connection: (.*)', re.IGNORECASE)
-
+
def make_response(request, headers):
"Simple http response factory"
# should this be integrated into the HTTPResponse constructor?
-
+
response=ZServerHTTPResponse(stdout=ChannelPipe(request), stderr=StringIO())
response._http_version=request.version
if request.version=='1.0' and is_proxying_match(request.request):
@@ -308,4 +308,3 @@
request.header).lower()
response._server_version=request.channel.server.SERVER_IDENT
return response
-
=== Zope/ZServer/HTTPServer.py 1.40 => 1.41 ===
--- Zope/ZServer/HTTPServer.py:1.40 Fri Jun 7 09:48:25 2002
+++ Zope/ZServer/HTTPServer.py Wed Aug 14 17:16:50 2002
@@ -1,14 +1,14 @@
##############################################################################
#
# Copyright (c) 2001 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
-#
+#
##############################################################################
"""
@@ -18,7 +18,7 @@
Request Threads -- Requests are processed by threads from a thread
pool.
-
+
Output Handling -- Output is pushed directly into the producer
fifo by the request-handling thread. The HTTP server does not do
any post-processing such as chunking.
@@ -29,8 +29,8 @@
doesn't wait for the response before sending another request. The
server must ensure that responses are sent back in the same order
as requests are received.
-
-"""
+
+"""
import sys
import re
import os
@@ -105,17 +105,17 @@
"A medusa style handler for zhttp_server"
_force_connection_close = 0
-
+
def __init__ (self, module, uri_base=None, env=None):
"""Creates a zope_handler
-
+
module -- string, the name of the module to publish
uri_base -- string, the base uri of the published module
defaults to '/<module name>' if not given.
- env -- dictionary, environment variables to be overridden.
+ env -- dictionary, environment variables to be overridden.
Replaces standard variables with supplied ones.
"""
-
+
self.module_name=module
self.env_override=env or {}
self.hits = counter.counter()
@@ -128,9 +128,9 @@
uri_base='/'
else:
if uri_base[0] != '/':
- uri_base='/'+uri_base
+ uri_base='/'+uri_base
if uri_base[-1] == '/':
- uri_base=uri_base[:-1]
+ uri_base=uri_base[:-1]
self.uri_base=uri_base
uri_regex='%s.*' % self.uri_base
self.uri_regex = re.compile(uri_regex)
@@ -166,7 +166,7 @@
(path, params, query, fragment) = request.split_uri()
if params: path = path + params # undo medusa bug!
-
+
while path and path[0] == '/':
path = path[1:]
if '%' in path:
@@ -250,12 +250,12 @@
def continue_request(self, sin, request):
"continue handling request now that we have the stdin"
-
+
s=get_header(CONTENT_LENGTH, request.header)
if s:
s=int(s)
else:
- s=0
+ s=0
DebugLogger.log('I', id(request), s)
env=self.get_environment(request)
@@ -283,22 +283,22 @@
closed=0
zombie_timeout=100*60 # 100 minutes
-
+
def __init__(self, server, conn, addr):
http_channel.__init__(self, server, conn, addr)
requestCloseOnExec(conn)
self.queue=[]
self.working=0
-
+
def push(self, producer, send=1):
# this is thread-safe when send is false
- # note, that strings are not wrapped in
+ # note, that strings are not wrapped in
# producers by default
if self.closed:
return
self.producer_fifo.push(producer)
if send: self.initiate_send()
-
+
push_with_producer=push
def work(self):
@@ -337,11 +337,11 @@
channel.close()
-class zhttp_server(http_server):
+class zhttp_server(http_server):
"http server"
-
+
SERVER_IDENT='Zope/%s ZServer/%s' % (ZOPE_VERSION,ZSERVER_VERSION)
-
+
channel_class = zhttp_channel
shutup=0
@@ -351,10 +351,10 @@
self.shutup=0
self.log_info('HTTP server started at %s\n'
'\tHostname: %s\n\tPort: %d' % (
- time.ctime(time.time()),
- self.server_name,
- self.server_port
- ))
+ time.ctime(time.time()),
+ self.server_name,
+ self.server_port
+ ))
def log_info(self, message, type='info'):
if self.shutup: return
@@ -372,4 +372,3 @@
# override asyncore limits for nt's listen queue size
self.accepting = 1
return self.socket.listen (num)
-
=== Zope/ZServer/ICPServer.py 1.1 => 1.2 ===
--- Zope/ZServer/ICPServer.py:1.1 Wed Mar 13 10:23:49 2002
+++ Zope/ZServer/ICPServer.py Wed Aug 14 17:16:50 2002
@@ -33,7 +33,7 @@
class BaseICPServer(asyncore.dispatcher):
REQUESTS_PER_LOOP = 4
-
+
def __init__ (self,ip,port):
asyncore.dispatcher.__init__(self)
self.create_socket (socket.AF_INET, socket.SOCK_DGRAM)
@@ -44,7 +44,7 @@
else:
addr = ip
self.log_info('ICP server started\n\tAddress: %s\n\tPort: %s' % (addr,port) )
-
+
def handle_read(self):
for i in range(self.REQUESTS_PER_LOOP):
try:
@@ -90,7 +90,7 @@
url = url[:-1]
out_opcode = self.check_url(url)
return struct.pack('!BBHIIII',out_opcode,2,20,number,0,0,0)
-
+
def check_url(self,url):
# derived classes replace this with a more
# useful policy
@@ -103,7 +103,7 @@
# they must return an ICP_OP code from above or None. The first
# non-None return is used as the ICP response
hooks = []
-
+
def check_url(self,url):
for hook in self.hooks:
r = hook(url)
=== Zope/ZServer/PCGIServer.py 1.23 => 1.24 ===
--- Zope/ZServer/PCGIServer.py:1.23 Mon Apr 15 16:58:48 2002
+++ Zope/ZServer/PCGIServer.py Wed Aug 14 17:16:50 2002
@@ -1,14 +1,14 @@
##############################################################################
#
# Copyright (c) 2001 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
-#
+#
##############################################################################
"""
@@ -22,7 +22,7 @@
Why would you want to use it? Using PCGI to connect to ZServer from
another webserver is similar to using the web server as a proxy,
-with the difference, that the web server gets to control the
+with the difference, that the web server gets to control the
environment and headers completely.
Note that ZServer can operate multiple PCGI servers.
@@ -50,13 +50,13 @@
tz_for_log=compute_timezone_for_log()
-class PCGIChannel(asynchat.async_chat):
+class PCGIChannel(asynchat.async_chat):
"""Processes a PCGI request by collecting the env and stdin and
then passing them to ZPublisher. The result is wrapped in a
producer and sent back."""
closed=0
-
+
def __init__(self,server,sock,addr):
self.server = server
self.addr = addr
@@ -67,7 +67,7 @@
self.set_terminator(10)
self.size=None
self.done=None
-
+
def found_terminator(self):
if self.size is None:
# read the next size header
@@ -76,10 +76,10 @@
self.size=string.atoi(self.data.read())
self.set_terminator(self.size)
if self.size==0:
-
+
DebugLogger.log('I', id(self), 0)
-
- self.set_terminator('\r\n')
+
+ self.set_terminator('\r\n')
self.data=StringIO()
self.send_response()
elif self.size > 1048576:
@@ -98,7 +98,7 @@
except:
pass
# Hack around broken IIS PATH_INFO
- # maybe, this should go in ZPublisher...
+ # maybe, this should go in ZPublisher...
if self.env.has_key('SERVER_SOFTWARE') and \
string.find(self.env['SERVER_SOFTWARE'],
'Microsoft-IIS') != -1:
@@ -109,37 +109,37 @@
self.env['PATH_INFO'] = '/' + string.join(path[len(script):],'/')
self.data=StringIO()
- DebugLogger.log('B', id(self),
+ DebugLogger.log('B', id(self),
'%s %s' % (self.env['REQUEST_METHOD'],
self.env.get('PATH_INFO' ,'/')))
-
+
# now read the next size header
self.set_terminator(10)
else:
- DebugLogger.log('I', id(self), self.terminator)
-
+ DebugLogger.log('I', id(self), self.terminator)
+
# we're done, we've got both env and stdin
self.set_terminator('\r\n')
self.data.seek(0)
self.send_response()
-
+
def send_response(self):
# create an output pipe by passing request to ZPublisher,
# and requesting a callback of self.log with the module
# name and PATH_INFO as an argument.
- self.done=1
+ self.done=1
response=PCGIResponse(stdout=PCGIPipe(self), stderr=StringIO())
request=HTTPRequest(self.data, self.env, response)
handle(self.server.module, request, response)
-
+
def collect_incoming_data(self, data):
self.data.write(data)
def readable(self):
if not self.done:
return 1
-
+
def log_request(self, bytes):
if self.env.has_key('HTTP_USER_AGENT'):
user_agent=self.env['HTTP_USER_AGENT']
@@ -183,15 +183,15 @@
method, path, self.reply_code, bytes,
referer, user_agent
)
- )
+ )
def push(self, producer, send=1):
# this is thread-safe when send is false
- # note, that strings are not wrapped in
+ # note, that strings are not wrapped in
# producers by default
self.producer_fifo.push(producer)
if send: self.initiate_send()
-
+
def __repr__(self):
return "<PCGIChannel at %x>" % id(self)
@@ -202,13 +202,13 @@
if p is not None and type(p) != StringType:
p.more() # free up resources held by producer
self.producer_fifo.pop()
- asyncore.dispatcher.close(self)
+ asyncore.dispatcher.close(self)
class PCGIServer(asyncore.dispatcher):
"""Accepts PCGI requests and hands them off to the PCGIChannel for
handling.
-
+
PCGIServer can be configured with either a PCGI info file or by
directly specifying the module, pid_file, and either port (for
inet sockets) or socket_file (for unix domain sockets.)
@@ -217,7 +217,7 @@
the server will accept connections, '' indicates all addresses. If
you only want to accept connections from the localhost, set ip to
'127.0.0.1'."""
-
+
channel_class=PCGIChannel
def __init__ (self,
@@ -239,23 +239,23 @@
self.logger = logger.resolving_logger (resolver, logger_object)
else:
self.logger = logger.unresolving_logger (logger_object)
-
+
# get configuration
- self.module=module
+ self.module=module
self.port=port
self.pid_file=pid_file
self.socket_file=socket_file
if pcgi_file is not None:
self.read_info(pcgi_file)
-
+
# write pid file
try:
- f = open(self.pid_file, 'w')
- f.write(str(os.getpid()))
- f.close()
+ f = open(self.pid_file, 'w')
+ f.write(str(os.getpid()))
+ f.close()
except IOError:
self.log_info("Cannot write PID file.", 'error')
-
+
# setup sockets
if self.port:
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
@@ -278,7 +278,7 @@
except os.error:
pass
self.log_info(
- 'PCGI Server started at %s\n'
+ 'PCGI Server started at %s\n'
'\tUnix socket: %s' % (time.ctime(time.time()), self.socket_file)
)
self.listen(256)
@@ -300,7 +300,7 @@
directives[string.strip(k)]=string.strip(v)
except:
raise 'ParseError', 'Error parsing PCGI info file'
-
+
self.pid_file=directives.get('PCGI_PID_FILE',None)
self.socket_file=directives.get('PCGI_SOCKET_FILE',None)
if directives.has_key('PCGI_PORT'):
@@ -312,7 +312,7 @@
path,module=os.path.split(path)
module,ext=os.path.splitext(module)
self.module=module
-
+
def handle_accept (self):
self.count.increment()
try:
@@ -321,19 +321,19 @@
self.log_info('Server accept() threw an exception', 'warning')
return
self.channel_class(self, conn, addr)
-
+
def readable(self):
return len(asyncore.socket_map) < CONNECTION_LIMIT
-
+
def writable (self):
return 0
-
+
def listen(self, num):
# override asyncore limits for nt's listen queue size
self.accepting = 1
return self.socket.listen (num)
-
-
+
+
class PCGIResponse(HTTPResponse):
def write(self, data):
@@ -341,42 +341,42 @@
self.stdout.write(str(self))
self._wrote=1
self.stdout.write(data)
-
+
def _finish(self):
self.stdout.finish(self)
self.stdout.close()
self.stdout=None
self._request=None
-
-
+
+
class PCGIPipe:
"""
Formats a HTTP response in PCGI format
-
+
10 digits indicating len of STDOUT
STDOUT
10 digits indicating len of STDERR
STDERR
-
+
Note that this implementation never sends STDERR
"""
def __init__(self, channel):
self._channel=channel
self._data=StringIO()
self._shutdown=0
-
+
def write(self,text):
self._data.write(text)
-
+
def close(self):
if not self._channel.closed:
data=self._data.getvalue()
l=len(data)
- DebugLogger.log('A', id(self._channel),
+ DebugLogger.log('A', id(self._channel),
'%s %s' % (self._channel.reply_code, l))
self._channel.push('%010d%s%010d' % (l, data, 0), 0)
- self._channel.push(LoggingProducer(self._channel, l, 'log_request'), 0)
+ self._channel.push(LoggingProducer(self._channel, l, 'log_request'), 0)
self._channel.push(CallbackProducer(
lambda t=('E', id(self._channel)): apply(DebugLogger.log,t)), 0)
@@ -391,7 +391,7 @@
Wakeup()
self._data=None
self._channel=None
-
+
def finish(self, response):
if response._shutdownRequested():
self._shutdown = 1
=== Zope/ZServer/Producers.py 1.6 => 1.7 ===
--- Zope/ZServer/Producers.py:1.6 Wed Nov 28 10:50:50 2001
+++ Zope/ZServer/Producers.py Wed Aug 14 17:16:50 2002
@@ -1,14 +1,14 @@
##############################################################################
#
# Copyright (c) 2001 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
-#
+#
##############################################################################
"""
ZServer pipe utils. These producers basically function as callbacks.
@@ -19,14 +19,14 @@
class ShutdownProducer:
"shuts down medusa"
-
+
def more(self):
asyncore.close_all()
class LoggingProducer:
"logs request"
-
+
def __init__(self, logger, bytes, method='log'):
self.logger=logger
self.bytes=bytes
@@ -36,14 +36,14 @@
getattr(self.logger, self.method)(self.bytes)
self.logger=None
return ''
-
+
class CallbackProducer:
"Performs a callback in the channel's thread"
-
+
def __init__(self, callback):
self.callback=callback
-
+
def more(self):
self.callback()
self.callback=None
@@ -55,7 +55,7 @@
# match http_channel's outgoing buffer size
out_buffer_size = 1<<16
-
+
def __init__(self, file, lock, start, end):
self.file=file
self.lock=lock
@@ -79,7 +79,7 @@
data = file.read(size)
finally:
self.lock.release()
-
+
if data:
start=start+len(data)
if start < end:
@@ -102,4 +102,3 @@
file.close()
self.file=None
return ''
-
=== Zope/ZServer/WebDAVSrcHandler.py 1.7 => 1.8 ===
--- Zope/ZServer/WebDAVSrcHandler.py:1.7 Wed Nov 28 10:50:50 2001
+++ Zope/ZServer/WebDAVSrcHandler.py Wed Aug 14 17:16:50 2002
@@ -1,14 +1,14 @@
##############################################################################
#
# Copyright (c) 2001 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
-#
+#
##############################################################################
"""
@@ -34,7 +34,7 @@
# Set a flag to indicate this request came through the WebDAV source
# port server.
env['WEBDAV_SOURCE_PORT'] = 1
-
+
if env['REQUEST_METHOD'] == 'GET':
path_info = env['PATH_INFO']
path_info = os.path.join( path_info, 'manage_FTPget' )
@@ -51,9 +51,9 @@
if env.get("HTTP_USER_AGENT","").find("Microsoft Data Access Internet Publishing Provider")>-1:
if env["PATH_INFO"][-1]=='.':
- env["PATH_INFO"] = env["PATH_INFO"][:-1]
+ env["PATH_INFO"] = env["PATH_INFO"][:-1]
if env["PATH_TRANSLATED"][-1]=='.':
- env["PATH_TRANSLATED"] = env["PATH_TRANSLATED"][:-1]
+ env["PATH_TRANSLATED"] = env["PATH_TRANSLATED"][:-1]
return env
=== Zope/ZServer/ZService.py 1.13 => 1.14 ===
--- Zope/ZServer/ZService.py:1.13 Wed Nov 28 10:50:50 2001
+++ Zope/ZServer/ZService.py Wed Aug 14 17:16:50 2002
@@ -1,14 +1,14 @@
##############################################################################
#
# Copyright (c) 2001 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
-#
+#
##############################################################################
"""
ZServer as a NT service.
@@ -16,7 +16,7 @@
The serice starts up and monitors a ZServer process.
Features:
-
+
* When you start the service it starts ZServer
* When you stop the serivice it stops ZServer
* It monitors ZServer and restarts it if it exits abnormally
@@ -26,82 +26,82 @@
Usage:
Installation
-
+
The ZServer service should be installed by the Zope Windows
installer. You can manually install, uninstall the service from
the commandline.
-
+
ZService.py [options] install|update|remove|start [...]
|stop|restart [...]|debug [...]
Options for 'install' and 'update' commands only:
-
+
--username domain\username : The Username the service is to run
under
-
+
--password password : The password for the username
-
- --startup [manual|auto|disabled] : How the service starts,
+
+ --startup [manual|auto|disabled] : How the service starts,
default = manual
-
+
Commands
-
+
install : Installs the service
-
+
update : Updates the service, use this when you change
ZServer.py
-
+
remove : Removes the service
-
+
start : Starts the service, this can also be done from the
services control panel
-
+
stop : Stops the service, this can also be done from the
services control panel
-
+
restart : Restarts the service
-
+
debug : Runs the service in debug mode
-
+
You can view the usage options by running ZServer.py without any
arguments.
-
+
Note: you may have to register the Python service program first,
-
+
win32\pythonservice.exe /register
-
+
Starting Zope
-
+
Start Zope by clicking the 'start' button in the services control
panel. You can set Zope to automatically start at boot time by
choosing 'Auto' startup by clicking the 'statup' button.
-
+
Stopping Zope
-
+
Stop Zope by clicking the 'stop' button in the services control
panel. You can also stop Zope through the web by going to the
- Zope control panel and by clicking 'Shutdown'.
-
+ Zope control panel and by clicking 'Shutdown'.
+
Event logging
-
+
Zope events are logged to the NT application event log. Use the
event viewer to keep track of Zope events.
Registry Settings
-
+
You can change how the service starts ZServer by editing a registry
key.
-
+
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\
<Service Name>\Parameters\start
The value of this key is the command which the service uses to
start ZServer. For example:
-
+
"C:\Program Files\Zope\bin\python.exe"
"C:\Program Files\Zope\z2.py" -w 8888
-
+
TODO:
* Integrate it into the Windows installer.
@@ -168,15 +168,15 @@
file.close()
_svc_display_name_ = "Zope (%s)" % _svc_name_
-
+
restart_min_time=5 # if ZServer restarts before this many
# seconds then we have a problem, and
# need to stop the service.
-
+
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
-
+
def SvcDoRun(self):
self.start_zserver()
while 1:
@@ -186,12 +186,12 @@
break
else:
self.restart_zserver()
- self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING, 5000)
+ self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING, 5000)
def SvcStop(self):
- servicemanager.LogInfoMsg('Stopping Zope.')
+ servicemanager.LogInfoMsg('Stopping Zope.')
try:
- self.stop_zserver()
+ self.stop_zserver()
except:
pass
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
@@ -204,10 +204,10 @@
self.hZServer=result[0]
self.last_start_time=time.time()
servicemanager.LogInfoMsg('Starting Zope.')
-
+
def stop_zserver(self):
win32process.TerminateProcess(self.hZServer,0)
-
+
def restart_zserver(self):
if time.time() - self.last_start_time < self.restart_min_time:
servicemanager.LogErrorMsg('Zope died and could not be restarted.')
@@ -223,15 +223,15 @@
def get_start_command(self):
return win32serviceutil.GetServiceCustomOption(self,'start')
-
-
+
+
def set_start_command(value):
"sets the ZServer start command if the start command is not already set"
current=win32serviceutil.GetServiceCustomOption(ZServerService,
'start', None)
if current is None:
win32serviceutil.SetServiceCustomOption(ZServerService,'start',value)
-
+
if __name__=='__main__':
win32serviceutil.HandleCommandLine(ZServerService)
=== Zope/ZServer/__init__.py 1.26 => 1.27 ===
--- Zope/ZServer/__init__.py:1.26 Thu Jun 20 11:35:05 2002
+++ Zope/ZServer/__init__.py Wed Aug 14 17:16:50 2002
@@ -1,14 +1,14 @@
##############################################################################
#
# Copyright (c) 2001 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
-#
+#
##############################################################################
import sys, os
@@ -55,7 +55,7 @@
message == 'Computing default hostname':
LOG('ZServer', BLATHER, message)
else:
- LOG('ZServer', severity[type], message)
+ LOG('ZServer', severity[type], message)
import asyncore
asyncore.dispatcher.log_info=log_info