[Zope-Checkins] CVS: Zope3/lib/python/Zope/Server - HTTPServer.py:1.1.2.14
Shane Hathaway
shane@digicool.com
Mon, 7 Jan 2002 10:39:04 -0500
Update of /cvs-repository/Zope3/lib/python/Zope/Server
In directory cvs.zope.org:/tmp/cvs-serv31823
Modified Files:
Tag: Zope-3x-branch
HTTPServer.py
Log Message:
- Made next_channel_cleanup a list so that it can be more easily overridden
by subclasses.
- Changed the name "channel_type" to "channel_base_class" for clarity.
- Renamed the "tasks" parameter to "task_dispatcher".
- Separated out the default server name computation into a method.
- Removed comments that are better described in interfaces.
- Provided a way to use an alternate socket map.
=== Zope3/lib/python/Zope/Server/HTTPServer.py 1.1.2.13 => 1.1.2.14 ===
if SIMULT_MODE:
- from dual_mode_channel import simultaneous_mode_channel as channel_type
+ from dual_mode_channel import simultaneous_mode_channel as \
+ channel_base_class
else:
- from dual_mode_channel import dual_mode_channel as channel_type
+ from dual_mode_channel import dual_mode_channel as channel_base_class
-from dual_mode_channel import OverflowableBuffer
+from dual_mode_channel import AlternateSocketMapMixin, OverflowableBuffer
from Adjustments import default_adj
from IHeaderOutput import IHeaderOutput
from ITask import ITask
@@ -107,10 +108,6 @@
"""
self.channel.close_when_done()
- # setResponseStatus(), setResponseHeaders(), appendResponseHeaders(),
- # wroteResponseHeader(), and setAuthUserName() are part of the
- # IHeaderOutput interface used by Zope.Publisher.HTTP.HTTPResponse.
-
def setResponseStatus(self, status, reason):
self.status = status
self.reason = reason
@@ -412,27 +409,26 @@
-class http_channel (channel_type):
+class http_channel (channel_base_class):
# Note: this class is very reusable for other protocols like FTP
# and should probably be turned into an abstract base class
# when we approach FTP.
task_class = http_task
+ active_channels = {} # Class-specific channel tracker
+ next_channel_cleanup = [0] # Class-specific cleanup time
- active_channels = {} # Class-specific channel tracker
proto_request = None # An http_request_data instance
ready_requests = None # A list
last_activity = 0 # Time of last activity
running_tasks = 0 # boolean
- next_channel_cleanup = 0 # A class variable
-
#
# ASYNCHRONOUS METHODS (incl. __init__)
#
- def __init__(self, server, conn, addr, adj=None):
- channel_type.__init__(self, server, conn, addr, adj)
+ def __init__(self, server, conn, addr, adj=None, socket_map=None):
+ channel_base_class.__init__(self, server, conn, addr, adj, socket_map)
self.last_activity = t = self.creation_time
self.check_maintenance(t)
@@ -440,27 +436,26 @@
"""
This hook keeps track of opened HTTP channels.
"""
- channel_type.add_channel(self, map)
+ channel_base_class.add_channel(self, map)
self.active_channels[self._fileno] = self
def del_channel(self, map=None):
"""
This hook keeps track of closed HTTP channels.
"""
- channel_type.del_channel(self, map)
+ channel_base_class.del_channel(self, map)
ac = self.active_channels
fd = self._fileno
if ac.has_key(fd):
del ac[fd]
def check_maintenance(self, now):
- if now < http_channel.next_channel_cleanup:
+ if now < self.next_channel_cleanup[0]:
return
- http_channel.next_channel_cleanup = now + self.adj.cleanup_interval
+ self.next_channel_cleanup[0] = now + self.adj.cleanup_interval
self.maintenance()
def maintenance(self):
- # Note that this is an asynchronous call.
# Kill off dead connections.
self.kill_zombies()
@@ -540,7 +535,6 @@
#
def end_task(self, close):
- # Synchronous.
if close:
self.close_when_done()
return
@@ -647,47 +641,52 @@
)
-
-class http_server (asyncore.dispatcher):
+class http_server (AlternateSocketMapMixin, asyncore.dispatcher):
channel_class = http_channel
SERVER_IDENT = 'Zope.Server.HTTPServer.http_server'
- def __init__(self, ip, port, tasks=None, adj=None, start=1,
- hit_log=None, verbose=0, resolver=None):
- # Assumes sock is already bound.
+ def __init__(self, ip, port, task_dispatcher=None, adj=None, start=1,
+ hit_log=None, verbose=0, socket_map=None):
if adj is None:
adj = default_adj
self.adj = adj
- self.resolver = resolver
+ self.socket_map = socket_map
asyncore.dispatcher.__init__(self)
self.port = port
- self.tasks = tasks
+ 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
-
- #if hit_log is None:
- # hit_log = CommonHitLogger()
self.hit_log = hit_log
+ self.server_name = self.computeServerName(ip)
- host, port = self.socket.getsockname()
- if not ip:
- if verbose:
- self.log_info('Computing default hostname', 'info')
- ip = socket.gethostbyname (socket.gethostname())
- try:
- self.server_name = socket.gethostbyaddr (ip)[0]
- except socket.error:
- if verbose:
- self.log_info('Cannot do reverse lookup', 'info')
- self.server_name = ip # use the IP address as the "hostname"
-
if start:
self.accept_connections()
+ def computeServerName(self, ip=''):
+ 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
@@ -721,19 +720,20 @@
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.
- self.log_info ('warning: server accept() threw an exception',
- 'warning')
+ # 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
- self.channel_class(self, conn, addr, self.adj)
+ self.channel_class(self, conn, addr, self.adj, self.socket_map)
def addTask(self, task):
- tasks = self.tasks
- if tasks is not None:
- self.tasks.addTask(task)
+ td = self.task_dispatcher
+ if td is not None:
+ td.addTask(task)
else:
task.service()
@@ -744,13 +744,13 @@
if __name__ == '__main__':
from TaskThreads import ThreadedTaskDispatcher
- tasks = ThreadedTaskDispatcher()
- tasks.setThreadCount(4)
- http_server('', 8080, tasks=tasks)
+ td = ThreadedTaskDispatcher()
+ td.setThreadCount(4)
+ http_server('', 8080, task_dispatcher=td)
try:
while 1:
asyncore.poll(5)
#print http_channel.active_channels
except KeyboardInterrupt:
print 'shutting down...'
- tasks.shutdown()
+ td.shutdown()