From cc1d2d5d0fe7f7ebb5368bc1f5d5cbbdec2c541f Mon Sep 17 00:00:00 2001 From: Anastasia Kuznetsova Date: Mon, 17 Jul 2017 14:06:31 +0400 Subject: [PATCH] Handle empty response content during its decoding in std.http If resp.content is empty and resp.encoding is not utf-8 then it can't be properly decoded, that's why additional check was added. Change-Id: Ie1bab1eff209e88552d4c9979ecec233ba041be4 Closes-Bug: #1700608 --- mistral/actions/std_actions.py | 2 +- .../unit/actions/test_std_http_action.py | 65 +++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/mistral/actions/std_actions.py b/mistral/actions/std_actions.py index ef9e41b67..a779ccdd8 100644 --- a/mistral/actions/std_actions.py +++ b/mistral/actions/std_actions.py @@ -206,7 +206,7 @@ class HTTPAction(actions.Action): except Exception as e: LOG.debug("HTTP action response is not json.") content = resp.content - if resp.encoding != 'utf-8': + if content and resp.encoding != 'utf-8': content = content.decode(resp.encoding).encode('utf-8') _result = { diff --git a/mistral/tests/unit/actions/test_std_http_action.py b/mistral/tests/unit/actions/test_std_http_action.py index f45569a8f..af6fe6e0a 100644 --- a/mistral/tests/unit/actions/test_std_http_action.py +++ b/mistral/tests/unit/actions/test_std_http_action.py @@ -49,6 +49,14 @@ def get_error_fake_response(): ) +def get_fake_response(content, code, **kwargs): + return base.FakeHTTPResponse( + content, + code, + **kwargs + ) + + class HTTPActionTest(base.BaseTest): @mock.patch.object(requests, 'request') def test_http_action(self, mocked_method): @@ -207,3 +215,60 @@ class HTTPActionTest(base.BaseTest): proxies=None, verify=None ) + + @mock.patch.object(requests, 'request') + def test_http_action_empty_resp(self, mocked_method): + action = std.HTTPAction( + url=URL, + method='GET', + timeout=20, + allow_redirects=True + ) + + self.assertEqual(URL, action.url) + + mocked_method.return_value = get_fake_response( + content=None, code=200, encoding=None + ) + mock_ctx = mock.Mock() + result = action.run(mock_ctx) + + self.assertIsNone(result['content']) + self.assertEqual(200, result['status']) + + mocked_method.assert_called_with( + 'GET', + URL, + headers=None, + cookies=None, + params=None, + data=None, + timeout=20, + auth=None, + allow_redirects=True, + proxies=None, + verify=None + ) + + mocked_method.return_value = get_fake_response( + content='', code=204, encoding=None + ) + mock_ctx = mock.Mock() + result = action.run(mock_ctx) + + self.assertEqual('', result['content']) + self.assertEqual(204, result['status']) + + mocked_method.assert_called_with( + 'GET', + URL, + headers=None, + cookies=None, + params=None, + data=None, + timeout=20, + auth=None, + allow_redirects=True, + proxies=None, + verify=None + )