/usr/share/pyshared/zope/server/serverbase.py is in python-zope.server 3.8.6-0ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | ##############################################################################
#
# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
#
##############################################################################
"""Server Base Class
This module provides a base implementation for a channel-based server. It can
only be used as a mix-in to actual server implementations.
"""
import asyncore
import logging
import socket
from zope.server.adjustments import default_adj
from zope.server.interfaces import IServer
from zope.interface import implements
class ServerBase(asyncore.dispatcher, object):
"""Async. server base for launching derivatives of ServerChannelBase."""
implements(IServer)
# See zope.server.interfaces.IServer
channel_class = None # Override with a channel class.
SERVER_IDENT = 'zope.server.serverbase' # Override.
def __init__(self, ip, port, task_dispatcher=None, adj=None, start=1,
hit_log=None, verbose=0):
if adj is None:
adj = default_adj
self.adj = adj
asyncore.dispatcher.__init__(self)
self.port = port
self.task_dispatcher = task_dispatcher
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind((ip, port))
self.verbose = verbose
self.hit_log = hit_log
self.logger = logging.getLogger(self.__class__.__name__)
self.server_name = self.computeServerName(ip)
if start:
self.accept_connections()
def log(self, message):
"""See zope.server.interfaces.IDispatcherLogging"""
# Override asyncore's default log()
self.logger.info(message)
level_mapping = {
'info': logging.INFO,
'error': logging.ERROR,
'warning': logging.WARN,
}
def log_info(self, message, type='info'):
"""See zope.server.interfaces.IDispatcherLogging"""
self.logger.log(self.level_mapping.get(type, logging.INFO), message)
def computeServerName(self, ip=''):
"""Given an IP, try to determine the server name."""
if ip:
server_name = str(ip)
else:
server_name = str(socket.gethostname())
# Convert to a host name if necessary.
is_hostname = 0
for c in server_name:
if c != '.' and not c.isdigit():
is_hostname = 1
break
if not is_hostname:
if self.verbose:
self.log_info('Computing hostname', 'info')
try:
server_name = socket.gethostbyaddr(server_name)[0]
except socket.error:
if self.verbose:
self.log_info('Cannot do reverse lookup', 'info')
return server_name
def accept_connections(self):
self.accepting = 1
self.socket.listen(self.adj.backlog) # Circumvent asyncore's NT limit
if self.verbose:
self.log_info('%s started.\n'
'\tHostname: %s\n\tPort: %d%s' % (
self.SERVER_IDENT,
self.server_name,
self.port,
self.getExtraLogMessage()
))
def getExtraLogMessage(self):
r"""Additional information to be logged on startup.
If not empty, should start with '\n\t', and every line break should
be followed by a '\t'.
"""
return ''
def addTask(self, task):
"""See zope.server.interfaces.ITaskDispatcher"""
td = self.task_dispatcher
if td is not None:
td.addTask(task)
else:
task.service()
def readable(self):
"""See zope.server.interfaces.IDispatcher"""
return (self.accepting and
len(asyncore.socket_map) < self.adj.connection_limit)
def writable(self):
"""See zope.server.interfaces.IDispatcher"""
return 0
def handle_read(self):
"""See zope.server.interfaces.IDispatcherEventHandler"""
pass
def handle_connect(self):
"""See zope.server.interfaces.IDispatcherEventHandler"""
pass
def handle_accept(self):
"""See zope.server.interfaces.IDispatcherEventHandler"""
try:
v = self.accept()
if v is None:
return
conn, addr = v
except socket.error:
# Linux: On rare occasions we get a bogus socket back from
# accept. socketmodule.c:makesockaddr complains that the
# address family is unknown. We don't want the whole server
# to shut down because of this.
if self.adj.log_socket_errors:
self.log_info ('warning: server accept() threw an exception',
'warning')
return
for (level, optname, value) in self.adj.socket_options:
conn.setsockopt(level, optname, value)
self.channel_class(self, conn, addr, self.adj)
|