Welcome, guest | Sign In | My Account | Store | Cart

BaseHTTPServer blocks while waiting for a connection. This means that a script will not respond to anything until it receives a network connection, which may never come. By adding a timeout to the listening socket, the script will regain control every so often.

Python, 25 lines
 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
import socket
import BaseHTTPServer

class Server(BaseHTTPServer.HTTPServer):
    """HTTPServer class with timeout."""

    def get_request(self):
        """Get the request and client address from the socket."""
        # 10 second timeout
        self.socket.settimeout(10.0)
        result = None
        while result is None:
            try:
                result = self.socket.accept()
            except socket.timeout:
                pass
        # Reset timeout on the new socket
        result[0].settimeout(None)
        return result

if __name__ == '__main__':
    from SimpleHTTPServer import SimpleHTTPRequestHandler

    server = Server(('', 80), SimpleHTTPRequestHandler)
    server.serve_forever()

I use a small http server like this to quickly transfer files between computers without all the overhead of more advanced filesharing programs.

After starting a BaseHTTPServer with serve_forever(), I cannot use a KeyboardInterrupt to quit the server, unless I request another page. With a timeout I may only have to wait up to 10 seconds.

The timeout on the new socket must be reset, because the request handlers use socket operations that do not work on a non-blocking socket.

3 comments

Dirk Holtwick 17 years, 2 months ago  # | flag

Stoppable HTTP Server. Here is a similar example:

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/425210

Rogier Steehouder (author) 17 years, 2 months ago  # | flag

I did search, but your recipe didn't turn up (or it was somewhere way down on the list).

So all credits go to Dirk. He came up with it first.

Dirk Holtwick 17 years, 2 months ago  # | flag

Credits. Hi Rogier, thanks for the credits ;-) Your code is more compact than mine and I think it is a good variation for a solution over the same problem we both had with blocking servers.