diff options
| author | Tobias Diaz <tobias.deb@gmail.com> | 2016-08-23 17:13:24 +0200 |
|---|---|---|
| committer | Samuel de Medeiros Queiroz <samueldmq@gmail.com> | 2017-01-05 10:19:25 -0300 |
| commit | 3e56e0d7e5e1a76d806a3bc1f6d5ef9070f95771 (patch) | |
| tree | cf73b3ba11fab18e8d64d220366282e969f3a062 /keystoneclient/tests/unit/test_session.py | |
| parent | 39373aa40b085c3277fe393de0f638f12ac16d53 (diff) | |
| download | python-keystoneclient-3e56e0d7e5e1a76d806a3bc1f6d5ef9070f95771.tar.gz | |
Prevent MemoryError when logging response bodies
Response bodies are loaded into memory prior to
being logged.
Loading huge response bodies may result in a
MemoryError.
This patch proposes that only JSON and TEXT
responses be logged, i.e when the Content-Type
header is application/json or application/text.
Responses that do not include or have a different
Content-Type header will have their body omitted.
This is a sort of backport of the fix for
keystoneauth sessions, see
I93b6fff73368c4f58bdebf8566c4948b50980cee
Co-Authored-By: Samuel de Medeiros Queiroz <samueldmq@gmail.com>
Closes-bug: 1616105
Change-Id: I8f43eee3a0b35041c6cf672e476f8151cf2f8d14
Diffstat (limited to 'keystoneclient/tests/unit/test_session.py')
| -rw-r--r-- | keystoneclient/tests/unit/test_session.py | 56 |
1 files changed, 51 insertions, 5 deletions
diff --git a/keystoneclient/tests/unit/test_session.py b/keystoneclient/tests/unit/test_session.py index 8fb364a..168cbb7 100644 --- a/keystoneclient/tests/unit/test_session.py +++ b/keystoneclient/tests/unit/test_session.py @@ -149,7 +149,8 @@ class SessionTests(utils.TestCase): in order to redact secure headers while debug is true. """ session = client_session.Session(verify=False) - headers = {'HEADERA': 'HEADERVALB'} + headers = {'HEADERA': 'HEADERVALB', + 'Content-Type': 'application/json'} security_headers = {'Authorization': uuid.uuid4().hex, 'X-Auth-Token': uuid.uuid4().hex, 'X-Subject-Token': uuid.uuid4().hex, } @@ -183,12 +184,56 @@ class SessionTests(utils.TestCase): session = client_session.Session() body = uuid.uuid4().hex - self.stub_url('GET', text=body, status_code=400) + self.stub_url('GET', text=body, status_code=400, + headers={'Content-Type': 'application/text'}) resp = session.get(self.TEST_URL, raise_exc=False) self.assertEqual(resp.status_code, 400) self.assertIn(body, self.logger.output) + def test_logging_body_only_for_text_and_json_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. + """ + OMITTED_BODY = ('Omitted, Content-Type is set to %s. Only ' + 'application/json and application/text responses ' + 'have their bodies logged.') + session = client_session.Session(verify=False) + + # Content-Type is not set + body = jsonutils.dumps({'token': {'id': '...'}}) + self.stub_url('POST', text=body) + session.post(self.TEST_URL) + self.assertNotIn(body, self.logger.output) + self.assertIn(OMITTED_BODY % None, self.logger.output) + + # Content-Type is set to text/xml + body = '<token><id>...</id></token>' + self.stub_url('POST', text=body, headers={'Content-Type': 'text/xml'}) + session.post(self.TEST_URL) + self.assertNotIn(body, self.logger.output) + self.assertIn(OMITTED_BODY % 'text/xml', self.logger.output) + + # Content-Type is set to application/json + body = jsonutils.dumps({'token': {'id': '...'}}) + self.stub_url('POST', text=body, + headers={'Content-Type': 'application/json'}) + session.post(self.TEST_URL) + 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) @@ -315,7 +360,8 @@ class SessionTests(utils.TestCase): "auth_username": "verybadusername", "auth_method": "CHAP"}}} body_json = jsonutils.dumps(body) - response = mock.Mock(text=body_json, status_code=200, headers={}) + response = mock.Mock(text=body_json, status_code=200, + headers={'content-type': 'application/json'}) session._http_log_response(response, logger) self.assertEqual(1, logger.debug.call_count) @@ -772,7 +818,7 @@ class SessionAuthTests(utils.TestCase): self.stub_url('GET', text=response, - headers={'Content-Type': 'text/html'}) + headers={'Content-Type': 'application/json'}) resp = sess.get(self.TEST_URL, logger=logger) @@ -968,7 +1014,7 @@ class AdapterTest(utils.TestCase): response = uuid.uuid4().hex self.stub_url('GET', text=response, - headers={'Content-Type': 'text/html'}) + headers={'Content-Type': 'application/json'}) resp = adpt.get(self.TEST_URL, logger=logger) |
