From: Sam Roberts Date: 2005-03-23T00:35:20+09:00 Subject: Re: can WEBrick bind to port 0, and then tell me what port was allocated? Quoting gotoyuzo@notwork.org, on Tue, Mar 22, 2005 at 06:45:13PM +0900: > In message <20050321143558.GA569@ensemble.local>, > `Sam Roberts ' wrote: > > It is very sensitive to error, it is very common to pass nil when you > > failed to initialize something correctly, and now it will silently do > > something unexpected, and the caller will waste time trying to figure > > out why every port is different, and having to ask on ruby-talk, where > > you will tell him he probably passed nil... and everybody will waste > > time. > > Hmm, ok. I understand what you mean. I rewrote a patch again > using port 0. (please forget my last post;-) I think that you didn't notice that if nil is passed, it also causes a port to be chosen, just like 0: TCPServer.new('localhost', nil).addr => ["AF_INET6", 49505, "localhost", "::1"] So you need to look for that, too, I modified the patch, below. > > Personally, I would prefer :auto. You don't accidently pass a symbol in > > as a port number, doing so is a pretty clear indication to WEBrick, and > > to readers of the code that the port is special. > > :auto seems that it could be used for other parameters. > I hesitate to introduce if it isn't useful for elsewhere. > How do you think? I wasn't thinking of a new parameter, but of a new value for the :Port parameter, current this is true: :Port => 80 # http :Port => 'www' # http :Port => 0 # dynamic :Port => nil # dynamic I would prefer to see: :Port => 80 # http :Port => 'www' # http :Port => :auto # dynamic :Port => 0 # raise ArgumentError :Port => nil # raise ArgumentError Its just a small suggestion. I worry that people will do this: :Port => ARGV[1] which may result in: :Port => nil and nil will be treated as 0, and it might surprise people. If you apply your patch to report each TCPServer that is made and the port that it is assigned, it will be easier to debug, though. So, that is how I think. Thanks for the help. Sam > -- > gotoyuzo > > --- lib/webrick/server.rb 7 Mar 2005 12:32:07 -0000 1.9 > +++ lib/webrick/server.rb 22 Mar 2005 09:34:10 -0000 > @@ -61,6 +61,9 @@ def initialize(config={}, default=Co > warn(":Listen option is deprecated; use GenericServer#listen") > end > listen(@config[:BindAddress], @config[:Port]) > + if @config[:Port] == 0 || @config[:Port] == nil > + @config[:Port] = @listeners[0].addr[1] > + end > end > end > > --- lib/webrick/utils.rb 28 Sep 2003 17:50:52 -0000 1.3 > +++ lib/webrick/utils.rb 22 Mar 2005 09:34:10 -0000 > @@ -58,8 +58,9 @@ def create_listeners(address, port, > sockets = [] > res.each{|ai| > begin > - logger.debug("TCPServer.new(#{ai[3]}, #{ai[1]})") if logger > - sock = TCPServer.new(ai[3], ai[1]) > + logger.debug("TCPServer.new(#{ai[3]}, #{port})") if logger > + sock = TCPServer.new(ai[3], port) > + port = sock.addr[1] if port == 0 || port == nil > Utils::set_close_on_exec(sock) > sockets << sock > rescue => ex >