1

In Python 2 and 3k, using wsgi.simple_server.make_server(host, port, app) does not raise an exception when the port is already in used. Instead, a call to .server_forever() or .handle_request() simply blocks until the other port closes and the next connection is incoming.

import wsgiref.simple_server as simple_server

def application(environ, start_response):
    start_response('200 OK', [('Content-type', 'text/html')])
    return ["<html><body><p>Hello!</p></body></html>".encode('utf-8')]

def main():
    server = simple_server.make_server('', 8901, application)
    server.serve_forever()

if __name__ == "__main__":
    main()

I would expect an Exception to be raised, since socket.socket.bind() also raises an exception in this case. Is there a way to determine if the returned HTTPServer did successfully bind to the specified port?

Niklas R
  • 16,299
  • 28
  • 108
  • 203

1 Answers1

1

I found the reason for this. The HTTPServer class source code in Python 2.7.8 is the following:

class HTTPServer(SocketServer.TCPServer):

    allow_reuse_address = 1    # Seems to make sense in testing environment

    def server_bind(self):
        """Override server_bind to store the server name."""
        import pdb; pdb.set_trace()
        SocketServer.TCPServer.server_bind(self)
        host, port = self.socket.getsockname()[:2]
        self.server_name = socket.getfqdn(host)
        self.server_port = port

And allow_reuse_address is used in SocketServer.TCPServer.server_bind() like this:

class TCPServer(BaseServer):

    # ...

    def server_bind(self):
        """Called by constructor to bind the socket.

        May be overridden.

        """
        if self.allow_reuse_address:
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.socket.bind(self.server_address)
        self.server_address = self.socket.getsockname()

Setting allow_reuse_address to False will cause self.socket.bind(self.server_address) to raise an exception. I wonder if this line in the HTTPServer class is intentional, since the comment says it's "makes sense in testing environments".

Niklas R
  • 16,299
  • 28
  • 108
  • 203
  • Do you find a way to unset this option, or easily let make_server raise an exception when the port is in use? Thank you! – leetom Aug 28 '17 at 09:48