@@ -621,6 +621,15 @@
destrepo = destpeer.local()
if destrepo:
+ # Update for 301 redirects
+ endsrc = srcpeer.url()
+ if not islocal(endsrc):
+ abspath = endsrc
+
+ # statichttprepository never sees the 'static-' prefix, so that
+ # need to be accounted for here.
+ if origsource.startswith('static-http'):
+ abspath = 'static-' + abspath
template = uimod.samplehgrcs['cloned']
fp = destrepo.vfs("hgrc", "w", text=True)
u = util.url(abspath)
@@ -88,12 +88,12 @@
(u.query or u.fragment))
# urllib cannot handle URLs with embedded user or passwd
- self._url, authinfo = u.authinfo()
+ self._url, self._authinfo = u.authinfo()
self.ui = ui
self.ui.debug('using %s\n' % self._url)
- self.urlopener = url.opener(ui, authinfo)
+ self.urlopener = url.opener(ui, self._authinfo)
self.requestbuilder = urlreq.request
def __del__(self):
@@ -230,6 +230,16 @@
if self._url.rstrip('/') != resp_url.rstrip('/'):
if not self.ui.quiet:
self.ui.warn(_('real URL is %s\n') % resp_url)
+ if resp.status == httplib.MOVED_PERMANENTLY:
+ u = util.url(resp_url.rstrip('/'))
+
+ # The path has auth info on creation. Restore that here.
+ creds = self._authinfo
+ if creds:
+ u.user = creds[2]
+ u.passwd = creds[3] or None
+ self.path = str(u)
+
self._url = resp_url
try:
proto = resp.getheader('content-type')
@@ -227,6 +227,7 @@
"HTTPDigestAuthHandler",
"HTTPHandler",
"HTTPPasswordMgrWithDefaultRealm",
+ "HTTPRedirectHandler",
"HTTPSHandler",
"install_opener",
"ProxyHandler",
@@ -272,6 +272,30 @@
return False
+class httpredirecthandler(urlreq.httpredirecthandler):
+ def __init__(self):
+ self._permmoved = True
+
+ def redirect_request(self, req, fp, code, msg, hdrs, newurl):
+ '''Called by all http_error_3xx() to monitor redirect types seen'''
+ # Avoid treating 302 -> 301 -> 200 or 301 -> 302 -> 200 as permanent
+ # redirects.
+ self._permmoved = self._permmoved and code == httplib.MOVED_PERMANENTLY
+
+ impl = urlreq.httpredirecthandler.redirect_request
+ return impl(self, req, fp, code, msg, hdrs, newurl)
+
+ def http_error_301(self, req, fp, code, msg, headers):
+ '''Capture the permanent redirect status for later access'''
+ impl = urlreq.httpredirecthandler.http_error_301
+ result = impl(self, req, fp, code, msg, headers)
+
+ # For an unbroken chain of 301, indicate 301 in the status. Otherwise,
+ # keep the 200 status.
+ if self._permmoved:
+ result.status = code
+ return result
+
class httphandler(keepalive.HTTPHandler):
def http_open(self, req):
return self.do_open(httpconnection, req)
@@ -437,6 +461,7 @@
handlers.append(httpshandler(ui))
handlers.append(proxyhandler(ui))
+ handlers.append(httpredirecthandler())
passmgr = passwordmgr(ui, ui.httppasswordmgrdb)
if authinfo is not None:
@@ -84,20 +84,20 @@
adding sub2/ = $TESTTMP/main/sub1/sub2 (glob)
$ cat hg1.pid >> $DAEMON_PIDS
- $ hg clone http://localhost:$HGPORT/main httpclone --config progress.disable=True
+ $ hg clone http://user@localhost:$HGPORT/main httpclone --config progress.disable=True
requesting all changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 3 changes to 3 files
updating to branch default
- cloning subrepo sub1 from http://localhost:$HGPORT/sub1
+ cloning subrepo sub1 from http://user@localhost:$HGPORT/sub1
requesting all changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 3 changes to 3 files
- cloning subrepo sub1/sub2 from http://localhost:$HGPORT/sub2 (glob)
+ cloning subrepo sub1/sub2 from http://user@localhost:$HGPORT/sub2 (glob)
requesting all changes
adding changesets
adding manifests
@@ -105,6 +105,11 @@
added 1 changesets with 1 changes to 1 files
3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg -R httpclone showconfig paths.default
+ http://user@localhost:$HGPORT/main
+ $ hg -R httpclone/sub1 showconfig paths.default
+ http://user@localhost:$HGPORT/sub1
+
$ cat access.log
* "GET /main?cmd=capabilities HTTP/1.1" 200 - (glob)
* "GET /main?cmd=batch HTTP/1.1" 200 - * (glob)
@@ -263,20 +263,20 @@
adding repo/foo/bar/ = $TESTTMP/repo/foo/bar (glob)
$ cat hg1.pid >> $DAEMON_PIDS
- $ hg clone http://localhost:$HGPORT/repo clone --config progress.disable=True
+ $ hg clone http://user:pass@localhost:$HGPORT/repo clone --config progress.disable=True
requesting all changes
adding changesets
adding manifests
adding file changes
added 3 changesets with 5 changes to 3 files
updating to branch default
- cloning subrepo foo from http://localhost:$HGPORT/repo/foo
+ cloning subrepo foo from http://user@localhost:$HGPORT/repo/foo
requesting all changes
adding changesets
adding manifests
adding file changes
added 4 changesets with 7 changes to 3 files
- cloning subrepo foo/bar from http://localhost:$HGPORT/repo/foo/bar (glob)
+ cloning subrepo foo/bar from http://user@localhost:$HGPORT/repo/foo/bar (glob)
requesting all changes
adding changesets
adding manifests
@@ -284,6 +284,11 @@
added 3 changesets with 3 changes to 1 files
3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg -R clone showconfig paths.default
+ http://user@localhost:$HGPORT/repo
+ $ hg -R clone/foo showconfig paths.default
+ http://user@localhost:$HGPORT/repo/foo
+
$ cat clone/foo/bar/z.txt
z1
z2