enable xml error message response
return xml error message when Accept:application/xml request received. default to json response when none specified. Change-Id: Idd454c5bc76adb583bc0a9afce9f31659e7fe2ac
This commit is contained in:
parent
4abb407152
commit
31b88b87b9
@ -22,6 +22,12 @@ Based on pecan.middleware.errordocument
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import webob
|
||||||
|
from xml import etree as et
|
||||||
|
|
||||||
|
from ceilometer.openstack.common import log
|
||||||
|
|
||||||
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class ParsableErrorMiddleware(object):
|
class ParsableErrorMiddleware(object):
|
||||||
@ -61,12 +67,24 @@ class ParsableErrorMiddleware(object):
|
|||||||
|
|
||||||
app_iter = self.app(environ, replacement_start_response)
|
app_iter = self.app(environ, replacement_start_response)
|
||||||
if (state['status_code'] / 100) not in (2, 3):
|
if (state['status_code'] / 100) not in (2, 3):
|
||||||
# FIXME(dhellmann): Always returns errors as JSON,
|
req = webob.Request(environ)
|
||||||
# but should look at the environ to determine
|
if (req.accept.best_match(['application/json', 'application/xml'])
|
||||||
# the desired type.
|
== 'application/xml'):
|
||||||
body = [json.dumps({'error_message': '\n'.join(app_iter)})]
|
try:
|
||||||
|
# simple check xml is valid
|
||||||
|
body = [et.ElementTree.tostring(
|
||||||
|
et.ElementTree.fromstring('<error_message>'
|
||||||
|
+ '\n'.join(app_iter)
|
||||||
|
+ '</error_message>'))]
|
||||||
|
except et.ElementTree.ParseError as err:
|
||||||
|
LOG.error('Error parsing HTTP response: %s' % err)
|
||||||
|
body = ['<error_message>%s' % state['status_code']
|
||||||
|
+ '</error_message>']
|
||||||
|
state['headers'].append(('Content-Type', 'application/xml'))
|
||||||
|
else:
|
||||||
|
body = [json.dumps({'error_message': '\n'.join(app_iter)})]
|
||||||
|
state['headers'].append(('Content-Type', 'application/json'))
|
||||||
state['headers'].append(('Content-Length', len(body[0])))
|
state['headers'].append(('Content-Length', len(body[0])))
|
||||||
state['headers'].append(('Content-Type', 'application/json'))
|
|
||||||
else:
|
else:
|
||||||
body = app_iter
|
body = app_iter
|
||||||
return body
|
return body
|
||||||
|
@ -26,6 +26,7 @@ from oslo.config import cfg
|
|||||||
from ceilometer.api import app
|
from ceilometer.api import app
|
||||||
from ceilometer.api import acl
|
from ceilometer.api import acl
|
||||||
from ceilometer import service
|
from ceilometer import service
|
||||||
|
from .base import FunctionalTest
|
||||||
|
|
||||||
|
|
||||||
class TestApp(unittest.TestCase):
|
class TestApp(unittest.TestCase):
|
||||||
@ -50,3 +51,66 @@ class TestApp(unittest.TestCase):
|
|||||||
api_app = app.setup_app()
|
api_app = app.setup_app()
|
||||||
self.assertEqual(api_app.auth_protocol, 'barttp')
|
self.assertEqual(api_app.auth_protocol, 'barttp')
|
||||||
os.unlink(tmpfile)
|
os.unlink(tmpfile)
|
||||||
|
|
||||||
|
|
||||||
|
class TestApiMiddleware(FunctionalTest):
|
||||||
|
|
||||||
|
def test_json_parsable_error_middleware_404(self):
|
||||||
|
response = self.get_json('/invalid_path',
|
||||||
|
expect_errors=True,
|
||||||
|
headers={"Accept":
|
||||||
|
"application/json"}
|
||||||
|
)
|
||||||
|
self.assertEqual(response.status_int, 404)
|
||||||
|
self.assertEqual(response.content_type, "application/json")
|
||||||
|
self.assertTrue(response.json['error_message'])
|
||||||
|
response = self.get_json('/invalid_path',
|
||||||
|
expect_errors=True,
|
||||||
|
headers={"Accept":
|
||||||
|
"application/json,application/xml"}
|
||||||
|
)
|
||||||
|
self.assertEqual(response.status_int, 404)
|
||||||
|
self.assertEqual(response.content_type, "application/json")
|
||||||
|
self.assertTrue(response.json['error_message'])
|
||||||
|
response = self.get_json('/invalid_path',
|
||||||
|
expect_errors=True,
|
||||||
|
headers={"Accept":
|
||||||
|
"application/xml;q=0.8, \
|
||||||
|
application/json"}
|
||||||
|
)
|
||||||
|
self.assertEqual(response.status_int, 404)
|
||||||
|
self.assertEqual(response.content_type, "application/json")
|
||||||
|
self.assertTrue(response.json['error_message'])
|
||||||
|
response = self.get_json('/invalid_path',
|
||||||
|
expect_errors=True
|
||||||
|
)
|
||||||
|
self.assertEqual(response.status_int, 404)
|
||||||
|
self.assertEqual(response.content_type, "application/json")
|
||||||
|
self.assertTrue(response.json['error_message'])
|
||||||
|
response = self.get_json('/invalid_path',
|
||||||
|
expect_errors=True,
|
||||||
|
headers={"Accept":
|
||||||
|
"text/html,*/*"}
|
||||||
|
)
|
||||||
|
self.assertEqual(response.status_int, 404)
|
||||||
|
self.assertEqual(response.content_type, "application/json")
|
||||||
|
self.assertTrue(response.json['error_message'])
|
||||||
|
|
||||||
|
def test_xml_parsable_error_middleware_404(self):
|
||||||
|
response = self.get_json('/invalid_path',
|
||||||
|
expect_errors=True,
|
||||||
|
headers={"Accept":
|
||||||
|
"application/xml,*/*"}
|
||||||
|
)
|
||||||
|
self.assertEqual(response.status_int, 404)
|
||||||
|
self.assertEqual(response.content_type, "application/xml")
|
||||||
|
self.assertEqual(response.xml.tag, 'error_message')
|
||||||
|
response = self.get_json('/invalid_path',
|
||||||
|
expect_errors=True,
|
||||||
|
headers={"Accept":
|
||||||
|
"application/json;q=0.8 \
|
||||||
|
,application/xml"}
|
||||||
|
)
|
||||||
|
self.assertEqual(response.status_int, 404)
|
||||||
|
self.assertEqual(response.content_type, "application/xml")
|
||||||
|
self.assertEqual(response.xml.tag, 'error_message')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user