Allow discovery URLs to have trailing slashes
The _get_discovery_url_choices generator works by taking a starting URL, splitting it on '/', and working through the parts trying to get a matching discovery document from it. It makes assumptions about what the URL might look like: it might have a project ID on the end of it, and a version before that. If the starting URL has a trailing '/', splitting the URL results in an empty string at the end of the list of parts, which is then treated as a version. The real version is left on the URL while the generator assumes it has already trimmed the URL down to an unversioned endpoint. If that version does not match the version we're seeking, the resulting discovery document will be mismatched and the generator will fail to yield the right endpoint. This patch normalizes the starting URL by removing the trailing '/', if there is one. This way every part of the split URL will be meaningful. Closes-bug: #1709658 Change-Id: I28c48f78d6f07804d6ea228f163dd37b0fcfcd58
This commit is contained in:
parent
9130c4caf6
commit
88827a895f
|
@ -983,7 +983,7 @@ class EndpointData(object):
|
|||
min_version and max_version are already normalized, so will either be
|
||||
None or a tuple.
|
||||
"""
|
||||
url = urllib.parse.urlparse(self.url)
|
||||
url = urllib.parse.urlparse(self.url.rstrip('/'))
|
||||
url_parts = url.path.split('/')
|
||||
|
||||
# First, check to see if the catalog url ends with a project id
|
||||
|
|
|
@ -1119,6 +1119,8 @@ class CatalogHackTests(utils.TestCase):
|
|||
V2_URL = BASE_URL + 'v2.0'
|
||||
V3_URL = BASE_URL + 'v3'
|
||||
|
||||
PROJECT_ID = uuid.uuid4().hex
|
||||
|
||||
def test_getting_endpoints(self):
|
||||
disc = fixture.DiscoveryList(href=self.BASE_URL)
|
||||
self.stub_url('GET',
|
||||
|
@ -1176,6 +1178,43 @@ class CatalogHackTests(utils.TestCase):
|
|||
|
||||
self.assertEqual(self.V2_URL, endpoint)
|
||||
|
||||
def test_getting_endpoints_project_id_and_trailing_slash_in_disc_url(self):
|
||||
# Test that when requesting a v3 endpoint and having a project in the
|
||||
# session but only the v2 endpoint with a trailing slash in the
|
||||
# catalog, we can still discover the v3 endpoint.
|
||||
disc = fixture.DiscoveryList(href=self.BASE_URL)
|
||||
self.stub_url('GET',
|
||||
['/'],
|
||||
base_url=self.BASE_URL,
|
||||
json=disc)
|
||||
|
||||
# Create a project-scoped token. This will exercise the flow in the
|
||||
# discovery URL sequence where a project ID exists in the token but
|
||||
# there is no project ID in the URL.
|
||||
token = fixture.V3Token(project_id=self.PROJECT_ID)
|
||||
|
||||
# Add only a v2 endpoint with a trailing slash
|
||||
service = token.add_service(self.IDENTITY)
|
||||
service.add_endpoint('public', self.V2_URL + '/')
|
||||
service.add_endpoint('admin', self.V2_URL + '/')
|
||||
|
||||
# Auth with v3
|
||||
kwargs = {'headers': {'X-Subject-Token': self.TEST_TOKEN}}
|
||||
self.stub_url('POST',
|
||||
['auth', 'tokens'],
|
||||
base_url=self.V3_URL,
|
||||
json=token, **kwargs)
|
||||
v3_auth = identity.V3Password(self.V3_URL,
|
||||
username=uuid.uuid4().hex,
|
||||
password=uuid.uuid4().hex)
|
||||
sess = session.Session(auth=v3_auth)
|
||||
|
||||
# Try to get a v3 endpoint
|
||||
endpoint = sess.get_endpoint(service_type=self.IDENTITY,
|
||||
interface='public',
|
||||
version=(3, 0))
|
||||
self.assertEqual(self.V3_URL, endpoint)
|
||||
|
||||
def test_returns_original_skipping_discovery(self):
|
||||
token = fixture.V2Token()
|
||||
service = token.add_service(self.IDENTITY)
|
||||
|
|
Loading…
Reference in New Issue