Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A value of 0 for socket_port should cause CP to bind to an available unused port #645

ghost opened this issue Jan 16, 2007 · 6 comments


Copy link

ghost commented Jan 16, 2007

Originally reported by: Anonymous

When socket_port is specified as 0, an exception is thrown as follows:

line 69, in quickstart
line 95, in start
line 118, in _start_http
line 159, in wait
line 247, in wait_for_occupied_port
    raise IOError(msg)
IOError: Port 0 not bound on 'localhost'

I am using the latest code from the trunk. It appears to me that even though wsgiserver is properly passing 0 to socket.bind (and hence binding to an unused port), other parts of the code still use "configured" port which is 0.

Reported by

Copy link

ghost commented Jan 25, 2007

Original comment by Anonymous:

I am attaching a small patch that seems to work with port 0. My only intention in uploading the patch is to suggest it as a starting point. It will take more time for me to understand all its implications and suggest a more thorough solution.

The web server will update its bind_addr after doing socket.bind() so that correct port can be obtained. This port will obviously be different from the original port if the original port was 0. Unfortunately, the code that started the web server needs to wait for this setting before proceeding further. Right now, I just added time.sleep(5) as I don't know of a better solution.

Copy link

ghost commented Jan 26, 2007

Original comment by Robert Brewer (Bitbucket: fumanchu, GitHub: fumanchu):

That's a good start, but there's no API guarantee that a given httpserver will possess a "bind_addr" attribute. So we'd either need to add that to the API (which is fine, just needs to be decided) or use some other method of passing that information back up to the Server object.

If we ''did'' add a "bind_addr" requirement, that would mean we could stop using a dict for httpservers and use a list instead (and consumers could inspect [server.bind_addr for server in httpservers] if they cared). That might be the way to go.

Copy link

ghost commented Jul 17, 2012

Original comment by Anonymous:

The solution proposed above needs some tiny tweaks for current versions of CherryPy

Change HTTPServer.bind() to update self.bind_addr with the port used by calling self.socket.getsockname() and then in ServerAdapter.start() updating self.bind_addr after starting the thread.

It needs to be tested if socket.getsockname() works on all platforms. I've seen other comments saying it doesn't work on Windows but I can confirm that Windows 7 (64 bit) returns a tuple of host and port.

Copy link

jaraco commented May 1, 2016

I confirmed this issue still exists. Running this code:

import cherrypy

class Server:
    def run(cls):
        config = {
            'global': {
                'server.socket_port': 0,
        cherrypy.quickstart(cls(), config=config)

if __name__ == '__main__':

produces this output

[01/May/2016:15:31:00] ENGINE Listening for SIGHUP.
[01/May/2016:15:31:00] ENGINE Listening for SIGTERM.
[01/May/2016:15:31:00] ENGINE Listening for SIGUSR1.
[01/May/2016:15:31:00] ENGINE Bus STARTING
[01/May/2016:15:31:01] ENGINE Started monitor thread '_TimeoutMonitor'.
[01/May/2016:15:31:01] ENGINE Started monitor thread 'Autoreloader'.
[01/May/2016:15:31:51] ENGINE Error in 'start' listener <bound method Server.start of <cherrypy._cpserver.Server object at 0x101fd0828>>
Traceback (most recent call last):
  File "/Users/jaraco/Dropbox/code/public/cherrypy/cherrypy/process/", line 203, in publish
    output.append(listener(*args, **kwargs))
  File "/Users/jaraco/Dropbox/code/public/cherrypy/cherrypy/", line 168, in start
  File "/Users/jaraco/Dropbox/code/public/cherrypy/cherrypy/process/", line 177, in start
  File "/Users/jaraco/Dropbox/code/public/cherrypy/cherrypy/process/", line 232, in wait
    wait_for_occupied_port(host, port)
  File "/Users/jaraco/Dropbox/code/public/cherrypy/cherrypy/process/", line 458, in wait_for_occupied_port
    raise IOError("Port %r not bound on %r" % (port, host))
OSError: Port 0 not bound on ''

[01/May/2016:15:31:51] ENGINE Shutting down due to error in start listener:
Traceback (most recent call last):
  File "/Users/jaraco/Dropbox/code/public/cherrypy/cherrypy/process/", line 241, in start
  File "/Users/jaraco/Dropbox/code/public/cherrypy/cherrypy/process/", line 221, in publish
    raise exc
cherrypy.process.wspbus.ChannelFailures: OSError("Port 0 not bound on ''",)

[01/May/2016:15:31:51] ENGINE Bus STOPPING
[01/May/2016:15:31:51] ENGINE HTTP Server cherrypy._cpwsgi_server.CPWSGIServer(('', 0)) already shut down
[01/May/2016:15:31:51] ENGINE Stopped thread 'Autoreloader'.
[01/May/2016:15:31:51] ENGINE Stopped thread '_TimeoutMonitor'.
[01/May/2016:15:31:51] ENGINE Bus STOPPED
[01/May/2016:15:31:51] ENGINE Bus EXITING
[01/May/2016:15:31:51] ENGINE Bus EXITED

Note the 50 second timeout.

@webknjaz webknjaz self-assigned this Sep 26, 2016
Copy link

I think, I'll take a look at this issue.

@jaraco jaraco changed the title A value of 0 for socket_port should cause CP to bind to an avaibale unused port A value of 0 for socket_port should cause CP to bind to an available unused port Dec 29, 2016
@jaraco jaraco closed this as completed in c52bb19 Dec 29, 2016
@jaraco jaraco reopened this Dec 29, 2016
Copy link

jaraco commented Dec 29, 2016

I hadn't meant to push that commit to master. I've moved it to the feature/bind-ephemeral branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet

No branches or pull requests

2 participants