Index: server/scgi_base.py =================================================================== --- server/scgi_base.py (revision 2347) +++ server/scgi_base.py (working copy) @@ -37,7 +37,7 @@ import datetime import os import warnings - +import traceback # Threads are required. If you want a non-threaded (forking) version, look at # SWAP . import thread @@ -198,18 +198,27 @@ handlerTime.seconds + handlerTime.microseconds / 1000000.0) +class TimeoutException(Exception): + pass class Connection(object): """ Represents a single client (web server) connection. A single request is handled, after which the socket is closed. """ - def __init__(self, sock, addr, server): + def __init__(self, sock, addr, server, timeout): self._sock = sock self._addr = addr self.server = server + self._timeout = timeout self.logger = logging.getLogger(LoggerName) + def timeout_handler(self, signum, frame): + self.logger.error('Timeout Exceeded') + self.logger.error("\n".join(traceback.format_stack(frame))) + + raise TimeoutException + def run(self): if len(self._addr) == 2: self.logger.debug('Connection starting up (%s:%d)', @@ -264,12 +273,23 @@ # Allocate Request req = Request(self, environ, input, output) + # If there is a timeout + if self._timeout: + old_alarm = signal.signal(signal.SIGALRM, self.timeout_handler) + signal.alarm(self._timeout) + # Run it. req.run() output.close() input.close() + # Restore old handler if timeout was given + if self._timeout: + signal.signal(signal.SIGALRM, old_alarm) + + + class BaseSCGIServer(object): # What Request class to use. requestClass = Request