Ensure constructed urls have trailing '/'s

The previous behavior in keystoneauth for constructing an unversioned
endpoint if there's a versioned endpoint in the catalog would result in
a trailing slash. Ensure that we end up with trailing slashses on
endpoints we construct.

On the other hand, do not add trailing slashes to urls we're actually
using. If someone wants a / the url they register with the catalog, they
can put one there.

Change-Id: I2798216b5b93d49fd5d3d865193cc0be6a1f6f0d
Closes-Bug: #1705770
This commit is contained in:
Monty Taylor 2017-07-22 12:15:23 +09:00
parent f6c9d042e3
commit ccbd20ed9c
No known key found for this signature in database
GPG Key ID: 7BAE94BC7141A594
2 changed files with 13 additions and 3 deletions

View File

@ -988,7 +988,7 @@ class EndpointData(object):
'/'.join(url_parts),
url.params,
url.query,
url.fragment).geturl()
url.fragment).geturl().rstrip('/') + '/'
# If we found a viable catalog endpoint and it's
# an exact match or matches the max, go ahead and give
@ -1002,13 +1002,20 @@ class EndpointData(object):
if allow_version_hack:
# If there were projects or versions in the url they are now gone.
# That means we're left with what should be the unversioned url.
yield urllib.parse.ParseResult(
hacked_url = urllib.parse.ParseResult(
url.scheme,
url.netloc,
'/'.join(url_parts),
url.params,
url.query,
url.fragment).geturl()
# Since this is potentially us constructing a base URL from the
# versioned URL - we need to make sure it has a trailing /. But
# we only want to do that if we have built a new URL - not if
# we're using the one from the catalog
if hacked_url != self.catalog_url:
hacked_url = hacked_url.strip('/') + '/'
yield hacked_url
# If we have a catalog discovery url, it either means we didn't
# return it earlier because it wasn't an exact enough match, or

View File

@ -709,7 +709,10 @@ class CommonIdentityTests(object):
resps = [{'json': disc}, {'status_code': 500}]
# We should only try to fetch the unversioned non-project_id url once
self.requests_mock.get(self.TEST_VOLUME.unversioned.public, resps)
# Because the catalog has the versioned endpoint but we constructed
# an unversioned endpoint, the url needs to have a trailing /
self.requests_mock.get(
self.TEST_VOLUME.unversioned.public + '/', resps)
# Fetch v2.0 first - since that doesn't match endpoint optimization,
# it should fetch the unversioned endpoint