From 8935c3bde9e9635f65522488c1aca5df5b03050d Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 7 Nov 2012 23:28:28 -0800 Subject: Limit formatting routes when adding resources By default, routes.mapper.Mapper.resource adds a bunch of formatted routes that accept anything after a '.'. Our spec says only .xml and .json are accepted so limit the formatting to those valuse. This allows identifiers with a '.' in urls. A few tests were added to the extensions test to prove that .xml and .json are stripped but other values are not. Change-Id: Ic888aa5d75050d6b14763c2a787ac8c8d5ab1f69 --- nova/api/openstack/__init__.py | 9 +++++++ .../tests/api/openstack/compute/test_extensions.py | 28 ++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index d27b018c2..67ea6e1b5 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -90,6 +90,15 @@ class APIMapper(routes.Mapper): return result[0], result[1] return routes.Mapper.routematch(self, url, environ) + def connect(self, *args, **kargs): + # NOTE(vish): Default the format part of a route to only accept json + # and xml so it doesn't eat all characters after a '.' + # in the url. + kargs.setdefault('requirements', {}) + if not kargs['requirements'].get('format'): + kargs['requirements']['format'] = 'json|xml' + return routes.Mapper.connect(self, *args, **kargs) + class ProjectMapper(APIMapper): def resource(self, member_name, collection_name, **kwargs): diff --git a/nova/tests/api/openstack/compute/test_extensions.py b/nova/tests/api/openstack/compute/test_extensions.py index 466fd3636..ceb90d24c 100644 --- a/nova/tests/api/openstack/compute/test_extensions.py +++ b/nova/tests/api/openstack/compute/test_extensions.py @@ -666,3 +666,31 @@ class ExtensionsXMLSerializerTest(test.TestCase): self.assertEqual(link_nodes[i].get(key), value) xmlutil.validate_schema(root, 'extensions') + + +class ExtensionControllerIdFormatTest(test.TestCase): + + def _bounce_id(self, test_id): + + class BounceController(object): + def show(self, req, id): + return id + res_ext = base_extensions.ResourceExtension('bounce', + BounceController()) + manager = StubExtensionManager(res_ext) + app = compute.APIRouter(manager) + request = webob.Request.blank("/fake/bounce/%s" % test_id) + response = request.get_response(app) + return response.body + + def test_id_with_xml_format(self): + result = self._bounce_id('foo.xml') + self.assertEqual(result, 'foo') + + def test_id_with_json_format(self): + result = self._bounce_id('foo.json') + self.assertEqual(result, 'foo') + + def test_id_with_bad_format(self): + result = self._bounce_id('foo.bad') + self.assertEqual(result, 'foo.bad') -- cgit