Browse Source

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
Monty Taylor 1 year ago
parent
commit
ccbd20ed9c
No account linked to committer's email address

+ 9
- 2
keystoneauth1/discover.py View File

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

+ 4
- 1
keystoneauth1/tests/unit/identity/test_identity_common.py View File

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

Loading…
Cancel
Save