Merge "Treat endpoints with trailing slashes the same way as without them"
This commit is contained in:
commit
d9c7af7c32
|
@ -172,8 +172,9 @@ def add_version_headers(res):
|
|||
def create_link_object(urls):
|
||||
links = []
|
||||
for url in urls:
|
||||
links.append({"rel": "self",
|
||||
"href": os.path.join(flask.request.url_root, url)})
|
||||
links.append({
|
||||
"rel": "self",
|
||||
"href": os.path.join(flask.request.url_root, url).rstrip('/')})
|
||||
return links
|
||||
|
||||
|
||||
|
@ -181,7 +182,7 @@ def generate_resource_data(resources):
|
|||
data = []
|
||||
for resource in resources:
|
||||
item = {}
|
||||
item['name'] = str(resource).split('/')[-1]
|
||||
item['name'] = str(resource).rstrip('/').split('/')[-1]
|
||||
item['links'] = create_link_object([str(resource)[1:]])
|
||||
data.append(item)
|
||||
return data
|
||||
|
@ -226,6 +227,11 @@ def api(path, is_public_api=False, rule=None, verb_to_rule_map=None,
|
|||
and strings to format the 'rule' string with
|
||||
:param kwargs: all the rest kwargs are passed to flask app.route
|
||||
"""
|
||||
# Force uniform behavior with regards to trailing slashes
|
||||
if not path.endswith('/'):
|
||||
path = path + '/'
|
||||
flask_kwargs['strict_slashes'] = False
|
||||
|
||||
def outer(func):
|
||||
@_app.route(path, **flask_kwargs)
|
||||
@convert_exceptions
|
||||
|
@ -264,7 +270,7 @@ def api_root():
|
|||
@api('/<version>', rule='introspection:version', is_public_api=True,
|
||||
methods=['GET'])
|
||||
def version_root(version):
|
||||
pat = re.compile(r'^\/%s\/[^\/]*?$' % version)
|
||||
pat = re.compile(r'^\/%s\/[^\/]*?/?$' % version)
|
||||
|
||||
resources = []
|
||||
for url in _app.url_map.iter_rules():
|
||||
|
@ -272,7 +278,7 @@ def version_root(version):
|
|||
resources.append(url)
|
||||
|
||||
if not resources:
|
||||
raise utils.Error(_('Version not found.'), code=404)
|
||||
raise utils.Error(_('Version %s not found.') % version, code=404)
|
||||
|
||||
return flask.jsonify(resources=generate_resource_data(resources))
|
||||
|
||||
|
@ -392,7 +398,7 @@ def api_introspection_reapply(node_id):
|
|||
def rule_repr(rule, short):
|
||||
result = rule.as_dict(short=short)
|
||||
result['links'] = [{
|
||||
'href': flask.url_for('api_rule', uuid=result['uuid']),
|
||||
'href': flask.url_for('api_rule', uuid=result['uuid']).rstrip('/'),
|
||||
'rel': 'self'
|
||||
}]
|
||||
return result
|
||||
|
|
|
@ -582,8 +582,8 @@ class TestApiVersions(BaseAPITest):
|
|||
@mock.patch.object(main._app.url_map, "iter_rules", autospec=True)
|
||||
def test_version_endpoint(self, mock_rules):
|
||||
mock_rules.return_value = ["/v1/endpoint1", "/v1/endpoint2/<uuid>",
|
||||
"/v1/endpoint1/<name>",
|
||||
"/v2/endpoint1", "/v1/endpoint3",
|
||||
"/v1/endpoint1/<name>/",
|
||||
"/v2/endpoint1", "/v1/endpoint3/",
|
||||
"/v1/endpoint2/<uuid>/subpoint"]
|
||||
endpoint = "/v1"
|
||||
res = self.app.get(endpoint)
|
||||
|
@ -606,6 +606,12 @@ class TestApiVersions(BaseAPITest):
|
|||
]}
|
||||
self.assertEqual(expected, json_data)
|
||||
|
||||
def test_version_endpoint_with_slash(self):
|
||||
endpoint = "/v1/"
|
||||
res = self.app.get(endpoint)
|
||||
self.assertEqual(200, res.status_code)
|
||||
self._check_version_present(res)
|
||||
|
||||
def test_version_endpoint_invalid(self):
|
||||
endpoint = "/v-1"
|
||||
res = self.app.get(endpoint)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
fixes:
|
||||
- |
|
||||
Fixes accessing API endpoints with trailing slashes. Now they're treated
|
||||
the same way as without slashes, although the latter remain canonical URLs.
|
Loading…
Reference in New Issue