hgweb: clarify which address and port can/cannot be bound at startup (bug 769)
authorStephen Deasey <sdeasey@gmail.com>
Mon, 10 Mar 2008 19:25:34 +0000
changeset 6262 de7256c82fad
parent 6261 7c8101b5ceb1
child 6263 573534c6b540
hgweb: clarify which address and port can/cannot be bound at startup (bug 769) The error message at startup when the address/port could not be bound was confusing: hg serve abort: cannot start server: Address already in use Be more explicit: $ hg serve -a localhost abort: cannot start server at 'localhost:8000': Address already in use Also be more explicit on success, showing hostname and ip address/port: $ hg -v serve -a localhost -p 80 listening at http://localhost/ (127.0.0.1:80) We are careful to handle a missconfigured machine whose hostname does not resolve, falling back to the address given at the command line. Remove a dead-code error message.
mercurial/commands.py
mercurial/hgweb/server.py
tests/test-http
tests/test-http.out
tests/test-serve
tests/test-serve.out
--- a/mercurial/commands.py	Fri Mar 14 22:12:50 2008 +0100
+++ b/mercurial/commands.py	Mon Mar 10 19:25:34 2008 +0000
@@ -2461,10 +2461,7 @@
     class service:
         def init(self):
             util.set_signal_handler()
-            try:
-                self.httpd = hgweb.server.create_server(parentui, repo)
-            except socket.error, inst:
-                raise util.Abort(_('cannot start server: ') + inst.args[1])
+            self.httpd = hgweb.server.create_server(parentui, repo)
 
             if not ui.verbose: return
 
@@ -2473,12 +2470,12 @@
             else:
                 prefix = ''
 
-            if self.httpd.port != 80:
-                ui.status(_('listening at http://%s:%d/%s\n') %
-                          (self.httpd.addr, self.httpd.port, prefix))
-            else:
-                ui.status(_('listening at http://%s/%s\n') %
-                          (self.httpd.addr, prefix))
+            port = ':%d' % self.httpd.port
+            if port == ':80':
+                port = ''
+
+            ui.status(_('listening at http://%s%s/%s (%s:%d)\n') %
+                      (self.httpd.fqaddr, port, prefix, self.httpd.addr, self.httpd.port))
 
         def run(self):
             self.httpd.serve_forever()
@@ -3115,8 +3112,8 @@
           ('d', 'daemon', None, _('run server in background')),
           ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
           ('E', 'errorlog', '', _('name of error log file to write to')),
-          ('p', 'port', 0, _('port to use (default: 8000)')),
-          ('a', 'address', '', _('address to use')),
+          ('p', 'port', 0, _('port to listen on (default: 8000)')),
+          ('a', 'address', '', _('address to listen on (default: all interfaces)')),
           ('', 'prefix', '', _('prefix path to serve from (default: server root)')),
           ('n', 'name', '',
            _('name to show in web pages (default: working dir)')),
--- a/mercurial/hgweb/server.py	Fri Mar 14 22:12:50 2008 +0100
+++ b/mercurial/hgweb/server.py	Mon Mar 10 19:25:34 2008 +0000
@@ -253,13 +253,6 @@
                 return hgwebobj
             self.application = make_handler()
 
-            addr = address
-            if addr in ('', '::'):
-                addr = socket.gethostname()
-
-            self.addr, self.port = addr, port
-            self.prefix = prefix
-
             if ssl_cert:
                 try:
                     from OpenSSL import SSL
@@ -273,6 +266,15 @@
                 self.server_bind()
                 self.server_activate()
 
+            self.addr, self.port = self.socket.getsockname()[0:2]
+            self.prefix = prefix
+
+            self.fqaddr = socket.getfqdn(address)
+            try:
+                socket.getaddrbyhost(self.fqaddr)
+            except:
+                fqaddr = address
+
     class IPv6HTTPServer(MercurialHTTPServer):
         address_family = getattr(socket, 'AF_INET6', None)
 
@@ -292,4 +294,5 @@
         else:
             return MercurialHTTPServer((address, port), handler)
     except socket.error, inst:
-        raise util.Abort(_('cannot start server: %s') % inst.args[1])
+        raise util.Abort(_("cannot start server at '%s:%d': %s")
+                         % (address, port, inst.args[1]))
--- a/tests/test-http	Fri Mar 14 22:12:50 2008 +0100
+++ b/tests/test-http	Mon Mar 10 19:25:34 2008 +0000
@@ -9,7 +9,7 @@
 hg --config server.uncompressed=True serve -p $HGPORT -d --pid-file=../hg1.pid
 hg serve -p $HGPORT1 -d --pid-file=../hg2.pid
 # Test server address cannot be reused
-hg serve -p $HGPORT1 2>&1 | sed -e 's/abort: cannot start server:.*/abort: cannot start server:/'
+hg serve -p $HGPORT1 2>&1 | sed -e "s/abort: cannot start server at ':$HGPORT1':.*/abort: cannot start server at ':$HGPORT1':/"
 cd ..
 cat hg1.pid hg2.pid >> $DAEMON_PIDS
 
--- a/tests/test-http.out	Fri Mar 14 22:12:50 2008 +0100
+++ b/tests/test-http.out	Mon Mar 10 19:25:34 2008 +0000
@@ -1,5 +1,5 @@
 adding foo
-abort: cannot start server:
+abort: cannot start server at ':20060':
 % clone via stream
 streaming all changes
 XXX files to transfer, XXX bytes of data
--- a/tests/test-serve	Fri Mar 14 22:12:50 2008 +0100
+++ b/tests/test-serve	Mon Mar 10 19:25:34 2008 +0000
@@ -14,33 +14,38 @@
 fi
 
 echo % With -v
-hg serve -a localhost -p $HGPORT1 -d --pid-file=hg.pid -v | sed -e 's,:[0-9][0-9]*/,/,'
+hg serve -a localhost -p $HGPORT1 -d --pid-file=hg.pid -v \
+    | sed -e 's/:[0-9][0-9]*//g' -e 's/localhost\.localdomain/localhost/'
 cat hg.pid >> "$DAEMON_PIDS"
 sleep 1
 kill `cat hg.pid`
 sleep 1
 
 echo % With --prefix foo
-hg serve -a localhost -p $HGPORT1 -d --pid-file=hg.pid -v --prefix foo | sed -e 's,:[0-9][0-9]*/,/,'
+hg serve -a localhost -p $HGPORT1 -d --pid-file=hg.pid -v --prefix foo \
+    | sed -e 's/:[0-9][0-9]*//g' -e 's/localhost\.localdomain/localhost/'
 cat hg.pid >> "$DAEMON_PIDS"
 sleep 1
 kill `cat hg.pid`
 sleep 1
 
 echo % With --prefix /foo
-hg serve -a localhost -p $HGPORT1 -d --pid-file=hg.pid -v --prefix /foo | sed -e 's,:[0-9][0-9]*/,/,'
+hg serve -a localhost -p $HGPORT1 -d --pid-file=hg.pid -v --prefix /foo \
+    | sed -e 's/:[0-9][0-9]*//g' -e 's/localhost\.localdomain/localhost/'
 cat hg.pid >> "$DAEMON_PIDS"
 sleep 1
 kill `cat hg.pid`
 sleep 1
 
 echo % With --prefix foo/
-hg serve -a localhost -p $HGPORT1 -d --pid-file=hg.pid -v --prefix foo/ | sed -e 's,:[0-9][0-9]*/,/,'
+hg serve -a localhost -p $HGPORT1 -d --pid-file=hg.pid -v --prefix foo/ \
+    | sed -e 's/:[0-9][0-9]*//g' -e 's/localhost\.localdomain/localhost/'
 cat hg.pid >> "$DAEMON_PIDS"
 sleep 1
 kill `cat hg.pid`
 sleep 1
 
 echo % With --prefix /foo/
-hg serve -a localhost -p $HGPORT1 -d --pid-file=hg.pid -v --prefix /foo/ | sed -e 's,:[0-9][0-9]*/,/,'
+hg serve -a localhost -p $HGPORT1 -d --pid-file=hg.pid -v --prefix /foo/ \
+    | sed -e 's/:[0-9][0-9]*//g' -e 's/localhost\.localdomain/localhost/'
 cat hg.pid >> "$DAEMON_PIDS"
--- a/tests/test-serve.out	Fri Mar 14 22:12:50 2008 +0100
+++ b/tests/test-serve.out	Mon Mar 10 19:25:34 2008 +0000
@@ -1,12 +1,12 @@
 % Without -v
 access log created - .hg/hgrc respected
 % With -v
-listening at http://localhost/
+listening at http://localhost/ (127.0.0.1)
 % With --prefix foo
-listening at http://localhost/foo/
+listening at http://localhost/foo/ (127.0.0.1)
 % With --prefix /foo
-listening at http://localhost/foo/
+listening at http://localhost/foo/ (127.0.0.1)
 % With --prefix foo/
-listening at http://localhost/foo/
+listening at http://localhost/foo/ (127.0.0.1)
 % With --prefix /foo/
-listening at http://localhost/foo/
+listening at http://localhost/foo/ (127.0.0.1)