changeset 13819:d16894e29f91

httprepo/sshrepo: use url.url Like the previous patch to getauthinfo(), this also makes username/password parsing more forgiving for SSH URLs. This also opens up the possibility of allowing non-numeric ports, since the URL parser has no problem handling them. Related issues: - issue851: @ in password in http url - issue2055: nonnumeric port bug with https protocol
author Brodie Rao <brodie@bitheap.org>
date Wed, 30 Mar 2011 20:01:35 -0700
parents bf6156bab41b
children 65b89e80f892
files mercurial/httprepo.py mercurial/sshrepo.py mercurial/statichttprepo.py mercurial/url.py
diffstat 4 files changed, 15 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/httprepo.py	Wed Mar 30 20:01:34 2011 -0700
+++ b/mercurial/httprepo.py	Wed Mar 30 20:01:35 2011 -0700
@@ -9,7 +9,7 @@
 from node import nullid
 from i18n import _
 import changegroup, statichttprepo, error, url, util, wireproto
-import os, urllib, urllib2, urlparse, zlib, httplib
+import os, urllib, urllib2, zlib, httplib
 import errno, socket
 
 def zgenerator(f):
@@ -28,13 +28,13 @@
         self.path = path
         self.caps = None
         self.handler = None
-        scheme, netloc, urlpath, query, frag = urlparse.urlsplit(path)
-        if query or frag:
+        u = url.url(path)
+        if u.query or u.fragment:
             raise util.Abort(_('unsupported URL component: "%s"') %
-                             (query or frag))
+                             (u.query or u.fragment))
 
         # urllib cannot handle URLs with embedded user or passwd
-        self._url, authinfo = url.getauthinfo(path)
+        self._url, authinfo = u.authinfo()
 
         self.ui = ui
         self.ui.debug('using %s\n' % self._url)
--- a/mercurial/sshrepo.py	Wed Mar 30 20:01:34 2011 -0700
+++ b/mercurial/sshrepo.py	Wed Mar 30 20:01:35 2011 -0700
@@ -6,8 +6,7 @@
 # GNU General Public License version 2 or any later version.
 
 from i18n import _
-import util, error, wireproto
-import re
+import util, error, wireproto, url
 
 class remotelock(object):
     def __init__(self, repo):
@@ -24,16 +23,16 @@
         self._url = path
         self.ui = ui
 
-        m = re.match(r'^ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?$', path)
-        if not m:
+        u = url.url(path, parse_query=False, parse_fragment=False)
+        if u.scheme != 'ssh' or not u.host or u.path is None:
             self._abort(error.RepoError(_("couldn't parse location %s") % path))
 
-        self.user = m.group(2)
-        if self.user and ':' in self.user:
+        self.user = u.user
+        if u.passwd is not None:
             self._abort(error.RepoError(_("password in URL not supported")))
-        self.host = m.group(3)
-        self.port = m.group(5)
-        self.path = m.group(7) or "."
+        self.host = u.host
+        self.port = u.port
+        self.path = u.path or "."
 
         sshcmd = self.ui.config("ui", "ssh", "ssh")
         remotecmd = self.ui.config("ui", "remotecmd", "hg")
--- a/mercurial/statichttprepo.py	Wed Mar 30 20:01:34 2011 -0700
+++ b/mercurial/statichttprepo.py	Wed Mar 30 20:01:35 2011 -0700
@@ -85,7 +85,8 @@
         self.ui = ui
 
         self.root = path
-        self.path, authinfo = url.getauthinfo(path.rstrip('/') + "/.hg")
+        u = url.url(path.rstrip('/') + "/.hg")
+        self.path, authinfo = u.authinfo()
 
         opener = build_opener(ui, authinfo)
         self.opener = opener(self.path)
--- a/mercurial/url.py	Wed Mar 30 20:01:34 2011 -0700
+++ b/mercurial/url.py	Wed Mar 30 20:01:35 2011 -0700
@@ -906,31 +906,6 @@
         return urllib2.HTTPBasicAuthHandler.http_error_auth_reqed(
                         self, auth_header, host, req, headers)
 
-def getauthinfo(path):
-    scheme, netloc, urlpath, query, frag = urlparse.urlsplit(path)
-    if not urlpath:
-        urlpath = '/'
-    if scheme != 'file':
-        # XXX: why are we quoting the path again with some smart
-        # heuristic here? Anyway, it cannot be done with file://
-        # urls since path encoding is os/fs dependent (see
-        # urllib.pathname2url() for details).
-        urlpath = quotepath(urlpath)
-    host, port, user, passwd = netlocsplit(netloc)
-
-    # urllib cannot handle URLs with embedded user or passwd
-    url = urlparse.urlunsplit((scheme, netlocunsplit(host, port),
-                              urlpath, query, frag))
-    if user:
-        netloc = host
-        if port:
-            netloc += ':' + port
-        # Python < 2.4.3 uses only the netloc to search for a password
-        authinfo = (None, (url, netloc), user, passwd or '')
-    else:
-        authinfo = None
-    return url, authinfo
-
 handlerfuncs = []
 
 def opener(ui, authinfo=None):