diff --git a/manila/api/openstack/__init__.py b/manila/api/openstack/__init__.py index 040abc28fb..f73cf0f504 100644 --- a/manila/api/openstack/__init__.py +++ b/manila/api/openstack/__init__.py @@ -35,6 +35,15 @@ class APIMapper(routes.Mapper): return result[0], result[1] return routes.Mapper.routematch(self, url, environ) + def connect(self, *args, **kwargs): + # NOTE(inhye): 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. + kwargs.setdefault('requirements', {}) + if not kwargs['requirements'].get('format'): + kwargs['requirements']['format'] = 'json|xml' + return routes.Mapper.connect(self, *args, **kwargs) + class ProjectMapper(APIMapper): def resource(self, member_name, collection_name, **kwargs): diff --git a/manila/tests/api/test_extensions.py b/manila/tests/api/test_extensions.py index 6801760ca9..fa73f1e3d2 100644 --- a/manila/tests/api/test_extensions.py +++ b/manila/tests/api/test_extensions.py @@ -130,3 +130,58 @@ class ExtensionAuthorizeTestCase(test.TestCase): policy.enforce.assert_called_once_with( mock.ANY, mock.ANY, {'project_id': 'fake', 'user_id': 'fake'}) + + +class StubExtensionManager(object): + """Provides access to Tweedle Beetles.""" + + name = "Tweedle Beetle Extension" + alias = "TWDLBETL" + + def __init__(self, resource_ext=None, action_ext=None, request_ext=None, + controller_ext=None): + self.resource_ext = resource_ext + self.controller_ext = controller_ext + self.extra_resource_ext = None + + def get_resources(self): + resource_exts = [] + if self.resource_ext: + resource_exts.append(self.resource_ext) + if self.extra_resource_ext: + resource_exts.append(self.extra_resource_ext) + return resource_exts + + def get_controller_extensions(self): + controller_extensions = [] + if self.controller_ext: + controller_extensions.append(self.controller_ext) + return controller_extensions + + +class ExtensionControllerIdFormatTest(test.TestCase): + + def _bounce_id(self, test_id): + + class BounceController(object): + def show(self, req, id): + return id + res_ext = extensions.ResourceExtension('bounce', + BounceController()) + manager = StubExtensionManager(res_ext) + app = router.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('foo', result.decode('UTF-8')) + + def test_id_with_json_format(self): + result = self._bounce_id('foo.json') + self.assertEqual('foo', result.decode('UTF-8')) + + def test_id_with_bad_format(self): + result = self._bounce_id('foo.bad') + self.assertEqual('foo.bad', result.decode('UTF-8')) diff --git a/releasenotes/notes/fix_limit_formating_routes-1b0e1a475de6ac44.yaml b/releasenotes/notes/fix_limit_formating_routes-1b0e1a475de6ac44.yaml new file mode 100644 index 0000000000..9f71499814 --- /dev/null +++ b/releasenotes/notes/fix_limit_formating_routes-1b0e1a475de6ac44.yaml @@ -0,0 +1,4 @@ +--- +fixes: + - Fixed routes.mapper.Mapper.resource adds a bunch of formatted + routes that cannot accept something after a '.'.