# HG changeset patch # User Brodie Rao # Date 1301540495 25200 # Node ID d16894e29f9108051c3943d5e46b4fe1d9c50e7a # Parent bf6156bab41b3f1edc0cb34e3a7ddb06bc63f304 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 diff -r bf6156bab41b -r d16894e29f91 mercurial/httprepo.py --- 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) diff -r bf6156bab41b -r d16894e29f91 mercurial/sshrepo.py --- 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") diff -r bf6156bab41b -r d16894e29f91 mercurial/statichttprepo.py --- 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) diff -r bf6156bab41b -r d16894e29f91 mercurial/url.py --- 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):