diff options
author | Steve Martinelli <s.martinelli@gmail.com> | 2017-01-10 21:58:36 -0500 |
---|---|---|
committer | Steve Martinelli <s.martinelli@gmail.com> | 2017-01-10 22:35:14 -0500 |
commit | 51d16fa344829aadf454faf5e0c4535a8f96a7c8 (patch) | |
tree | 2c9bc0d73750bdb2d5273e863cb9c11c85049057 | |
parent | 56af8c90ecbb3cb5d29036151108b1e4e7a69bcc (diff) | |
download | python-keystoneclient-51d16fa344829aadf454faf5e0c4535a8f96a7c8.tar.gz |
Only log application/json in session to start3.9.0
When whitelisting content types to debug print from session we chose
application/json and application/text. application/text is not a real
mime type, text is typically text/plain.
Rather than guess at mime types only print application/json to start
with, but make it easy for additional types to be added later.
Adapted from keystoneauth: Ica5fee076cdab8b1d5167161d28af7313fad9477
Related-Bug: 1616105
Change-Id: Ieaa8fb3ea8d25e09b89498f23b70b18c0f6153f1
-rw-r--r-- | keystoneclient/session.py | 9 | ||||
-rw-r--r-- | keystoneclient/tests/unit/test_session.py | 55 | ||||
-rw-r--r-- | releasenotes/notes/bug-1616105-cc8b85eb056e99e2.yaml | 6 |
3 files changed, 34 insertions, 36 deletions
diff --git a/keystoneclient/session.py b/keystoneclient/session.py index 2501120..9b6d9b7 100644 --- a/keystoneclient/session.py +++ b/keystoneclient/session.py @@ -37,7 +37,10 @@ osprofiler_web = importutils.try_import("osprofiler.web") USER_AGENT = 'python-keystoneclient' -_LOG_CONTENT_TYPES = set(['application/json', 'application/text']) +# NOTE(jamielennox): Clients will likely want to print more than json. Please +# propose a patch if you have a content type you think is reasonable to print +# here and we'll add it to the list as required. +_LOG_CONTENT_TYPES = set(['application/json']) _logger = logging.getLogger(__name__) @@ -233,8 +236,8 @@ class Session(object): text = _remove_service_catalog(response.text) else: text = ('Omitted, Content-Type is set to %s. Only ' - 'application/json and application/text responses ' - 'have their bodies logged.') % content_type + '%s responses have their bodies logged.') + text = text % (content_type, ', '.join(_LOG_CONTENT_TYPES)) string_parts = [ 'RESP:', diff --git a/keystoneclient/tests/unit/test_session.py b/keystoneclient/tests/unit/test_session.py index 7294b70..5adc61f 100644 --- a/keystoneclient/tests/unit/test_session.py +++ b/keystoneclient/tests/unit/test_session.py @@ -157,8 +157,8 @@ class SessionTests(utils.TestCase): 'X-Auth-Token': uuid.uuid4().hex, 'X-Subject-Token': uuid.uuid4().hex, 'X-Service-Token': uuid.uuid4().hex} - body = 'BODYRESPONSE' - data = 'BODYDATA' + body = '{"a": "b"}' + data = '{"c": "d"}' all_headers = dict( itertools.chain(headers.items(), security_headers.items())) self.stub_url('POST', text=body, headers=all_headers) @@ -185,26 +185,25 @@ class SessionTests(utils.TestCase): def test_logs_failed_output(self): """Test that output is logged even for failed requests.""" session = client_session.Session() - body = uuid.uuid4().hex + body = {uuid.uuid4().hex: uuid.uuid4().hex} - self.stub_url('GET', text=body, status_code=400, - headers={'Content-Type': 'application/text'}) + self.stub_url('GET', json=body, status_code=400, + headers={'Content-Type': 'application/json'}) resp = session.get(self.TEST_URL, raise_exc=False) self.assertEqual(resp.status_code, 400) - self.assertIn(body, self.logger.output) + self.assertIn(list(body.keys())[0], self.logger.output) + self.assertIn(list(body.values())[0], self.logger.output) - def test_logging_body_only_for_text_and_json_content_types(self): + def test_logging_body_only_for_specified_content_types(self): """Verify response body is only logged in specific content types. Response bodies are logged only when the response's Content-Type header - is set to application/json or application/text. This prevents us to get - an unexpected MemoryError when reading arbitrary responses, such as - streams. + is set to application/json. This prevents us to get an unexpected + MemoryError when reading arbitrary responses, such as streams. """ OMITTED_BODY = ('Omitted, Content-Type is set to %s. Only ' - 'application/json and application/text responses ' - 'have their bodies logged.') + 'application/json responses have their bodies logged.') session = client_session.Session(verify=False) # Content-Type is not set @@ -229,14 +228,6 @@ class SessionTests(utils.TestCase): self.assertIn(body, self.logger.output) self.assertNotIn(OMITTED_BODY % 'application/json', self.logger.output) - # Content-Type is set to application/text - body = uuid.uuid4().hex - self.stub_url('POST', text=body, - headers={'Content-Type': 'application/text'}) - session.post(self.TEST_URL) - self.assertIn(body, self.logger.output) - self.assertNotIn(OMITTED_BODY % 'application/text', self.logger.output) - def test_unicode_data_in_debug_output(self): """Verify that ascii-encodable data is logged without modification.""" session = client_session.Session(verify=False) @@ -812,22 +803,24 @@ class SessionAuthTests(utils.TestCase): auth = AuthPlugin() sess = client_session.Session(auth=auth) - response = uuid.uuid4().hex + response = {uuid.uuid4().hex: uuid.uuid4().hex} self.stub_url('GET', - text=response, + json=response, headers={'Content-Type': 'application/json'}) resp = sess.get(self.TEST_URL, logger=logger) - self.assertEqual(response, resp.text) + self.assertEqual(response, resp.json()) output = io.getvalue() self.assertIn(self.TEST_URL, output) - self.assertIn(response, output) + self.assertIn(list(response.keys())[0], output) + self.assertIn(list(response.values())[0], output) self.assertNotIn(self.TEST_URL, self.logger.output) - self.assertNotIn(response, self.logger.output) + self.assertNotIn(list(response.keys())[0], self.logger.output) + self.assertNotIn(list(response.values())[0], self.logger.output) class AdapterTest(utils.TestCase): @@ -1009,21 +1002,23 @@ class AdapterTest(utils.TestCase): sess = client_session.Session(auth=auth) adpt = adapter.Adapter(sess, auth=auth, logger=logger) - response = uuid.uuid4().hex + response = {uuid.uuid4().hex: uuid.uuid4().hex} - self.stub_url('GET', text=response, + self.stub_url('GET', json=response, headers={'Content-Type': 'application/json'}) resp = adpt.get(self.TEST_URL, logger=logger) - self.assertEqual(response, resp.text) + self.assertEqual(response, resp.json()) output = io.getvalue() self.assertIn(self.TEST_URL, output) - self.assertIn(response, output) + self.assertIn(list(response.keys())[0], output) + self.assertIn(list(response.values())[0], output) self.assertNotIn(self.TEST_URL, self.logger.output) - self.assertNotIn(response, self.logger.output) + self.assertNotIn(list(response.keys())[0], self.logger.output) + self.assertNotIn(list(response.values())[0], self.logger.output) class ConfLoadingTests(utils.TestCase): diff --git a/releasenotes/notes/bug-1616105-cc8b85eb056e99e2.yaml b/releasenotes/notes/bug-1616105-cc8b85eb056e99e2.yaml index 91529c6..e9c1c9c 100644 --- a/releasenotes/notes/bug-1616105-cc8b85eb056e99e2.yaml +++ b/releasenotes/notes/bug-1616105-cc8b85eb056e99e2.yaml @@ -3,6 +3,6 @@ fixes: - > [`bug 1616105 <https://bugs.launchpad.net/keystoneauth/+bug/1616105>`_] Only log the response body when the ``Content-Type`` header is set to - ``application/json`` or ``application/text``. This avoids logging large - binary objects (such as images). Other ``Content-Type`` will not be - logged. + ``application/json``. This avoids logging large binary objects (such as + images). Other ``Content-Type`` will not be logged. Additional + ``Content-Type`` strings can be added as required. |