149
143
user and passwords are not embedded in the path provided to the server.
151
relative = urlutils.unescape(relpath).encode('utf-8')
152
path = self._combine_paths(self._path, relative)
153
return self._unsplit_url(self._unqualified_scheme,
154
None, None, self._host, self._port, path)
145
url = self._parsed_url.clone(relpath)
146
url.user = url.quoted_user = None
147
url.password = url.quoted_password = None
148
url.scheme = self._unqualified_scheme
156
151
def _create_auth(self):
157
152
"""Returns a dict containing the credentials provided at build time."""
158
auth = dict(host=self._host, port=self._port,
159
user=self._user, password=self._password,
153
auth = dict(host=self._parsed_url.host, port=self._parsed_url.port,
154
user=self._parsed_url.user, password=self._parsed_url.password,
160
155
protocol=self._unqualified_scheme,
156
path=self._parsed_url.path)
164
159
def get_smart_medium(self):
518
512
:returns: A transport or None.
520
def relpath(abspath):
521
"""Returns the path relative to our base.
523
The constraints are weaker than the real relpath method because the
524
abspath is coming from the server and may slightly differ from our
525
base. We don't check the scheme, host, port, user, password parts,
526
relying on the caller to give us a proper url (i.e. one returned by
527
the server mirroring the one we sent).
532
path) = self._split_url(abspath)
534
return path[pl:].strip('/')
536
relpath = relpath(source)
537
if not target.endswith(relpath):
514
parsed_source = self._split_url(source)
515
parsed_target = self._split_url(target)
516
pl = len(self._parsed_url.path)
517
# determine the excess tail - the relative path that was in
518
# the original request but not part of this transports' URL.
519
excess_tail = parsed_source.path[pl:].strip("/")
520
if not target.endswith(excess_tail):
538
521
# The final part of the url has been renamed, we can't handle the
545
path) = self._split_url(target)
546
# Recalculate base path. This is needed to ensure that when the
547
# redirected tranport will be used to re-try whatever request was
548
# redirected, we end up with the same url
549
base_path = path[:-len(relpath)]
550
if scheme in ('http', 'https'):
525
target_path = parsed_target.path
527
# Drop the tail that was in the redirect but not part of
528
# the path of this transport.
529
target_path = target_path[:-len(excess_tail)]
531
if parsed_target.scheme in ('http', 'https'):
551
532
# Same protocol family (i.e. http[s]), we will preserve the same
552
533
# http client implementation when a redirection occurs from one to
553
534
# the other (otherwise users may be surprised that bzr switches
554
535
# from one implementation to the other, and devs may suffer
556
if (scheme == self._unqualified_scheme
557
and host == self._host
558
and port == self._port
559
and (user is None or user == self._user)):
537
if (parsed_target.scheme == self._unqualified_scheme
538
and parsed_target.host == self._parsed_url.host
539
and parsed_target.port == self._parsed_url.port
540
and (parsed_target.user is None or
541
parsed_target.user == self._parsed_url.user)):
560
542
# If a user is specified, it should match, we don't care about
561
543
# passwords, wrong passwords will be rejected anyway.
562
new_transport = self.clone(base_path)
544
return self.clone(target_path)
564
546
# Rebuild the url preserving the scheme qualification and the
565
547
# credentials (if they don't apply, the redirected to server
566
548
# will tell us, but if they do apply, we avoid prompting the
568
redir_scheme = scheme + '+' + self._impl_name
550
redir_scheme = parsed_target.scheme + '+' + self._impl_name
569
551
new_url = self._unsplit_url(redir_scheme,
570
self._user, self._password,
573
new_transport = transport.get_transport(new_url)
552
self._parsed_url.user,
553
self._parsed_url.password,
554
parsed_target.host, parsed_target.port,
556
return transport.get_transport_from_url(new_url)
575
558
# Redirected to a different protocol
576
new_url = self._unsplit_url(scheme,
580
new_transport = transport.get_transport(new_url)
559
new_url = self._unsplit_url(parsed_target.scheme,
561
parsed_target.password,
562
parsed_target.host, parsed_target.port,
564
return transport.get_transport_from_url(new_url)
584
567
# TODO: May be better located in smart/medium.py with the other