Python BaseHTTPServer.HTTPServer - callback for start and stop event

。_饼干妹妹 提交于 2019-12-06 03:45:31

It would be excellent to configure the http server with the following callbacks:

  • before starting the server
  • after starting the server
  • before stopping the server
  • after stopping the server

Bear in mind that the OS will start accepting and queuing TCP connections the moment the socket starts listening, which is done in the constructor of BaseHTTPServer, so if you want to perform lengthy tasks before starting the server, it's probably better to do them before the OS starts accepting connections.

There's a server_activate() method which makes the call to socket.listen(), so it's probably best to override that.

Similarly, the OS will continue to accept connections until the call to socket.close(), so if you want to be able to define a 'pre-stop' handler which has the capacity to prevent itself from being shutdown, it's probably better to use the server_close() method, rather than calling socket.close() directly.

I've put together a simple example, using class methods on the request handler to handle the four new events, although you can move them somewhere else...

from BaseHTTPServer import HTTPServer
from BaseHTTPServer import BaseHTTPRequestHandler

# Subclass HTTPServer with some additional callbacks
class CallbackHTTPServer(HTTPServer):

    def server_activate(self):
        self.RequestHandlerClass.pre_start()
        HTTPServer.server_activate(self)
        self.RequestHandlerClass.post_start()

    def server_close(self):
        self.RequestHandlerClass.pre_stop()
        HTTPServer.server_close(self)
        self.RequestHandlerClass.post_stop()


# HTTP request handler
class HttpHandler(BaseHTTPRequestHandler):

    @classmethod
    def pre_start(cls):
        print 'Before calling socket.listen()'

    @classmethod
    def post_start(cls):
        print 'After calling socket.listen()'

    @classmethod
    def pre_stop(cls):
        print 'Before calling socket.close()'

    @classmethod
    def post_stop(cls):
        print 'After calling socket.close()'

    def do_POST(self):
        print "I have just received an HTTP POST request"


def main():

    # Create server
    try:
        print "Creating server"
        server = CallbackHTTPServer(('', 8000), HttpHandler)
    except KeyboardInterrupt:
        print "Server creation aborted"
        return

    # Start serving
    try:
        print "Calling serve_forever()"
        server.serve_forever()
    except KeyboardInterrupt:
        print "Calling server.server_close()"
        server.server_close()


if __name__ == '__main__':
    main()

Note that I've also moved the call to the constructor into its own try...except block, since the server variable won't exist if you hit CTRL-C during its construction.

You have to subclass HTTPServer and use your class instead HTTPServer

from __future__ import print_function
from BaseHTTPServer import HTTPServer
from BaseHTTPServer import BaseHTTPRequestHandler


class MyHTTPServer(HTTPServer):


    def __init__(self, *args, **kwargs):

        self.on_before_serve = kwargs.pop('on_before_serve', None)
        HTTPServer.__init__(self, *args, **kwargs)

    def serve_forever(self, poll_interval=0.5):

        if self.on_before_serve:
            self.on_before_serve(self)
        HTTPServer.serve_forever(self, poll_interval)


# http request handler
class HttpHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        print("I have just received a HTTP request through POST")

try:
    server = MyHTTPServer(('0.0.0.0', 8080), HttpHandler,
                          on_before_serve = lambda server: print('Server will start to serve in the moment...'))

    # wait forever for incoming http requests!
    server.serve_forever()

except KeyboardInterrupt:
    server.socket.close()
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!