How to stop BaseHTTPServer.serve_forever() in a BaseHTTPRequestHandler subclass? How to stop BaseHTTPServer.serve_forever() in a BaseHTTPRequestHandler subclass? python python

How to stop BaseHTTPServer.serve_forever() in a BaseHTTPRequestHandler subclass?


I should start by saying that "I probably wouldn't do this myself, but I have in the past". The serve_forever (from SocketServer.py) method looks like this:

def serve_forever(self):    """Handle one request at a time until doomsday."""    while 1:        self.handle_request()

You could replace (in subclass) while 1 with while self.should_be_running, and modify that value from a different thread. Something like:

def stop_serving_forever(self):    """Stop handling requests"""    self.should_be_running = 0    # Make a fake request to the server, to really force it to stop.    # Otherwise it will just stop on the next request.    # (Exercise for the reader.)    self.make_a_fake_request_to_myself()

Edit: I dug up the actual code I used at the time:

class StoppableRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer):    stopped = False    allow_reuse_address = True    def __init__(self, *args, **kw):        SimpleXMLRPCServer.SimpleXMLRPCServer.__init__(self, *args, **kw)        self.register_function(lambda: 'OK', 'ping')    def serve_forever(self):        while not self.stopped:            self.handle_request()    def force_stop(self):        self.server_close()        self.stopped = True        self.create_dummy_request()    def create_dummy_request(self):        server = xmlrpclib.Server('http://%s:%s' % self.server_address)        server.ping()


Another way to do it, based on http://docs.python.org/2/library/basehttpserver.html#more-examples, is: instead of serve_forever(), keep serving as long as a condition is met, with the server checking the condition before and after each request. For example:

import CGIHTTPServerimport BaseHTTPServerKEEP_RUNNING = Truedef keep_running():    return KEEP_RUNNINGclass Handler(CGIHTTPServer.CGIHTTPRequestHandler):    cgi_directories = ["/cgi-bin"]httpd = BaseHTTPServer.HTTPServer(("", 8000), Handler)while keep_running():    httpd.handle_request()


In my python 2.6 installation, I can call it on the underlying TCPServer - it still there inside your HTTPServer:

TCPServer.shutdown>>> import BaseHTTPServer>>> h=BaseHTTPServer.HTTPServer(('',5555), BaseHTTPServer.BaseHTTPRequestHandler)>>> h.shutdown<bound method HTTPServer.shutdown of <BaseHTTPServer.HTTPServer instance at 0x0100D800>>>>>