changeset 12076:49463314c24f

mail/hgweb: support service names for ports (issue2350) This adds util.getport(port) which tries to parse port as an int, and failing that, looks it up using socket.getservbyname(). Thus, the following will work: [smtp] port = submission [web] port = http This does not apply to ports in URLs used in clone, pull, etc.
author Brodie Rao <brodie@bitheap.org>
date Sat, 28 Aug 2010 12:31:07 -0400
parents f585c9bb85c1
children ff6f5310ad92
files hgext/zeroconf/__init__.py mercurial/commands.py mercurial/hgweb/server.py mercurial/mail.py mercurial/util.py tests/test-serve tests/test-serve.out
diffstat 7 files changed, 35 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/zeroconf/__init__.py	Fri Aug 27 16:25:47 2010 +0200
+++ b/hgext/zeroconf/__init__.py	Sat Aug 28 12:31:07 2010 -0400
@@ -27,7 +27,7 @@
 import socket, time, os
 
 import Zeroconf
-from mercurial import ui, hg, encoding
+from mercurial import ui, hg, encoding, util
 from mercurial import extensions
 from mercurial.hgweb import hgweb_mod
 from mercurial.hgweb import hgwebdir_mod
@@ -107,7 +107,7 @@
         path = self.repo.ui.config("web", "prefix", "").strip('/')
         desc = self.repo.ui.config("web", "description", name)
         publish(name, desc, path,
-                int(self.repo.ui.config("web", "port", 8000)))
+                util.getport(self.repo.ui.config("web", "port", 8000)))
 
 class hgwebdirzc(hgwebdir_mod.hgwebdir):
     def __init__(self, conf, baseui=None):
@@ -119,7 +119,7 @@
             name = os.path.basename(repo)
             path = (prefix + repo).strip('/')
             desc = u.config('web', 'description', name)
-            publish(name, desc, path, int(u.config("web", "port", 8000)))
+            publish(name, desc, path, util.getport(u.config("web", "port", 8000)))
 
 # listen
 
--- a/mercurial/commands.py	Fri Aug 27 16:25:47 2010 +0200
+++ b/mercurial/commands.py	Sat Aug 28 12:31:07 2010 -0400
@@ -3332,7 +3332,7 @@
 
     # this way we can check if something was given in the command-line
     if opts.get('port'):
-        opts['port'] = int(opts.get('port'))
+        opts['port'] = util.getport(opts.get('port'))
 
     baseui = repo and repo.baseui or ui
     optlist = ("name templates style address port prefix ipv6"
--- a/mercurial/hgweb/server.py	Fri Aug 27 16:25:47 2010 +0200
+++ b/mercurial/hgweb/server.py	Sat Aug 28 12:31:07 2010 -0400
@@ -269,7 +269,7 @@
     import mimetypes; mimetypes.init()
 
     address = ui.config('web', 'address', '')
-    port = int(ui.config('web', 'port', 8000))
+    port = util.getport(ui.config('web', 'port', 8000))
     try:
         return cls(ui, app, (address, port), handler)
     except socket.error, inst:
--- a/mercurial/mail.py	Fri Aug 27 16:25:47 2010 +0200
+++ b/mercurial/mail.py	Sat Aug 28 12:31:07 2010 -0400
@@ -37,7 +37,7 @@
     mailhost = ui.config('smtp', 'host')
     if not mailhost:
         raise util.Abort(_('no [smtp]host in hgrc - cannot send mail'))
-    mailport = int(ui.config('smtp', 'port', 25))
+    mailport = util.getport(ui.config('smtp', 'port', 25))
     ui.note(_('sending mail: smtp host %s, port %s\n') %
             (mailhost, mailport))
     s.connect(host=mailhost, port=mailport)
--- a/mercurial/util.py	Fri Aug 27 16:25:47 2010 +0200
+++ b/mercurial/util.py	Sat Aug 28 12:31:07 2010 -0400
@@ -17,7 +17,7 @@
 import error, osutil, encoding
 import errno, re, shutil, sys, tempfile, traceback
 import os, stat, time, calendar, textwrap, unicodedata, signal
-import imp
+import imp, socket
 
 # Python compatibility
 
@@ -1414,3 +1414,19 @@
     r = re.compile(r'%s(%s)' % (prefix, '|'.join(mapping.keys())))
     return r.sub(lambda x: fn(mapping[x.group()[1:]]), s)
 
+def getport(port):
+    """Return the port for a given network service.
+
+    If port is an integer, it's returned as is. If it's a string, it's
+    looked up using socket.getservbyname(). If there's no matching
+    service, util.Abort is raised.
+    """
+    try:
+        return int(port)
+    except ValueError:
+        pass
+
+    try:
+        return socket.getservbyname(port)
+    except socket.error:
+        raise Abort(_("no port number associated with service '%s'") % port)
--- a/tests/test-serve	Fri Aug 27 16:25:47 2010 +0200
+++ b/tests/test-serve	Sat Aug 28 12:31:07 2010 -0400
@@ -10,7 +10,11 @@
     echo % errors
     cat errors.log
     sleep 1
-    kill `cat hg.pid`
+    if [ "$KILLQUIETLY" = "Y" ]; then
+        kill `cat hg.pid` 2>/dev/null
+    else
+        kill `cat hg.pid`
+    fi
     sleep 1
 }
 
@@ -36,6 +40,9 @@
 echo % With -v and -p HGPORT2
 hgserve -p "$HGPORT2"
 
+echo '% With -v and -p http (should fail)'
+KILLQUIETLY=Y hgserve -p http
+
 echo % With --prefix foo
 hgserve --prefix foo
 
--- a/tests/test-serve.out	Fri Aug 27 16:25:47 2010 +0200
+++ b/tests/test-serve.out	Sat Aug 28 12:31:07 2010 -0400
@@ -7,6 +7,10 @@
 % With -v and -p HGPORT2
 listening at http://localhost/ (bound to 127.0.0.1:HGPORT2)
 % errors
+% With -v and -p http (should fail)
+abort: cannot start server at 'localhost:80': Permission denied
+abort: child process failed to start
+% errors
 % With --prefix foo
 listening at http://localhost/foo/ (bound to 127.0.0.1:HGPORT1)
 % errors