[MERGE] HTTP redirection
Aaron Bentley
aaron.bentley at utoronto.ca
Tue Feb 13 15:16:16 GMT 2007
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Vincent Ladeuil wrote:
> After discussions with Robert at NlSprint, John on IRC and Robert
> again on IRC, here is a new attempt at http redirections.
I think this is very close to mergeable.
> - By default http do not redirect silently but instead raise the
> RedirectedRequest exception,
I'm a little sad to see that removed, because I use transports elsewhere
(e.g. 'bzr patch' from bzrtools) and I'll have to manually handle
redirects now.
> There is one detail I didn't implement: when a redirection
> occurs, we get a new url from the http server. If the original
> transport have a qualifier (+urllib or +pycurl or chroot+ for
> example) and the redirected url use the same scheme that the
> original transport, we should apply it to the new transport. But
> I couldn't find a simple way to take into account all schemes,
> all qualifiers and all decorators.
I see your point here.
> """
> - format = BzrDirFormat.find_format(transport)
> + initial_base = transport.base
> + redirected = True # to enter the loop
> + redirections = 0
> + # If a loop occurs, there is little we can do. So we
> + # don't try to detect them, just getting out if too much
> + # redirections occurs. The solution is outside: where the
> + # loop is defined.
> + while redirected and redirections < BzrDir.MAX_REDIRECTIONS:
> + try:
> + format = BzrDirFormat.find_format(transport)
> + redirected = False
> + except errors.RedirectRequested, e:
> + qualified_source = e.get_source_url()
> + relpath = transport.relpath(qualified_source)
> + if not e.target.endswith(relpath):
> + # Not redirected to a branch-format, not a branch
> + raise errors.NotBranchError(path=e.target)
> + target = e.target[:-len(relpath)]
> + note('%s is%s redirected to %s',
> + transport.base, e.permanently, target)
> + # Let's try with a new transport
> + qualified_target = e.get_target_url()[:-len(relpath)]
> + # FIXME: If 'transport' have a qualifier, this
> + # should be applied again to the new transport
> + # *iff* the schemes used are the same. It's a bit
> + # tricky to verify, so I'll punt for now
> + # -- vila20070212
> + transport = get_transport(target)
> + redirections += 1
> + if redirected:
> + # Out of the loop and still redirected ? Either the
> + # user have kept a very very very old reference to a
> + # branch or a loop occured in the redirections.
> + # Nothing we can cure here: tell the user. Note that
> + # as the user have been informed about each
> + # redirection, there is no need to issue an
> + # additional error message.
> + raise errors.NotBranchError(path=initial_base)
I think this would be more clearly handled as a for..else loop:
for x in range(BzrDir.MAX_REDIRECTIONS):
try:
format = BzrDirFormat.find_format(transport)
break
except errors.RedirectRequested, e
qualified_source = e.get_source_url()
relpath = transport.relpath(qualified_source)
if not e.target.endswith(relpath):
# Not redirected to a branch-format, not a branch
raise errors.NotBranchError(path=e.target)
target = e.target[:-len(relpath)]
note('%s is%s redirected to %s',
transport.base, e.permanently, target)
# Let's try with a new transport
qualified_target = e.get_target_url()[:-len(relpath)]
# FIXME: If 'transport' have a qualifier, this
# should be applied again to the new transport
# *iff* the schemes used are the same. It's a bit
# tricky to verify, so I'll punt for now
# -- vila20070212
transport = get_transport(target)
else:
# Loop exited without resolving redirect ? Either the
# user has kept a very very very old reference to a
# branch or a loop occured in the redirections.
# Nothing we can cure here: tell the user. Note that
# as the user has been informed about each
# redirection, there is no need to issue an
# additional error message.
raise errors.NotBranchError(path=initial_base)
BzrDir._check_supported(format, _unsupported)
return format.open(transport, _found=True)
While this was exactly what for...else was designed for, you might just
exit early in the try clause.
> @@ -1086,7 +1128,8 @@
> def probe_transport(klass, transport):
> """Return the .bzrdir style transport present at URL."""
> try:
> - format_string = transport.get(".bzr/branch-format").read()
> + format_file = transport.get(".bzr/branch-format")
> + format_string = format_file.read()
^^^ I don't understand this change.
> -# register BzrDirFormat as a control format
> -BzrDirFormat.register_control_format(BzrDirFormat)
> -
> -
> class BzrDirFormat4(BzrDirFormat):
> """Bzr dir format 4.
>
> @@ -1475,6 +1514,11 @@
> repository_format = property(__return_repository_format, __set_repository_format)
>
>
> +# register BzrDirMetaFormat1 as a control format. Our only
> +# concrete control format (BzrDirFormat is an abstract one).
> +BzrDirFormat.register_control_format(BzrDirMetaFormat1)
> +
> +# Register bzr formats
> BzrDirFormat.register_format(BzrDirFormat4())
> BzrDirFormat.register_format(BzrDirFormat5())
> BzrDirFormat.register_format(BzrDirFormat6())
Comment ("our only concrete control format") seems to be contradicted by
registering BzrDirFormat4, 5, 6.
I think we should be testing that redirecting bzrdirs works with
BzrDir.open, i.e. that the resulting transport base takes the redirects
into account. It probably makes sense to test open,
open_from_transport, open_containing_from_transport, and open_containing.
We should make a clear statement about how open_containing works: does
it follow the initial redirect, or does it keep on altering the initial
url until BzrDir.open succeeds (by following a redirect to a real branch)?
Aaron
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFF0dZA0F+nu1YWqI0RAqP4AJ9D+JmODynM+8hSQ+ufz9+JLDWYqQCeO0zk
2220ZK7O9s+lW5hzdMvTzS8=
=9KfQ
-----END PGP SIGNATURE-----
More information about the bazaar
mailing list