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?
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".