Change Http action result content encoding

Sometimes action result is present not in "utf-8", it cases
to "UnicodeDecodeError: 'utf8' codec can't decode byte" so
need to pass proper encoding format in serialiser and deserialiser
if it is different from default, but it should be resolved in
general as a fix for another bug (#1676411).

As a hotfix for linked bug, encoding was changed in the
run Http action method directly.

Also default encoding value in the FakeHTTPResponse was changed
from 'utf8' to 'utf-8' like in official python request lib docs.

Change-Id: I0ab9ec84c0973f362b57ab82248f27768a984678
Closes-Bug: #1667415
This commit is contained in:
Anastasia Kuznetsova 2017-03-23 17:15:59 +04:00
parent 594818a5b3
commit a46dfbfb7b
3 changed files with 27 additions and 4 deletions

View File

@ -196,12 +196,19 @@ class HTTPAction(base.Action):
"HTTP action response:\n%s\n%s" % (resp.status_code, resp.content)
)
# TODO(akuznetsova): Need to refactor Mistral serialiser and
# deserializer to have an ability to pass needed encoding and work
# with it. Now it can process only default 'utf-8' encoding.
# Appropriate bug #1676411 was created.
# Represent important resp data as a dictionary.
try:
content = resp.json()
content = resp.json(encoding=resp.encoding)
except Exception as e:
LOG.debug("HTTP action response is not json.")
content = resp.content
if resp.encoding != 'utf-8':
content = content.decode(resp.encoding).encode('utf-8')
_result = {
'content': content,

View File

@ -81,7 +81,7 @@ def register_action_class(name, cls, attributes=None, desc=None):
class FakeHTTPResponse(object):
def __init__(self, text, status_code, reason=None, headers=None,
history=None, encoding='utf8', url='', cookies=None,
history=None, encoding='utf-8', url='', cookies=None,
elapsed=None):
self.text = text
self.content = text
@ -94,8 +94,8 @@ class FakeHTTPResponse(object):
self.cookies = cookies or {}
self.elapsed = elapsed or datetime.timedelta(milliseconds=123)
def json(self):
return json.loads(self.text)
def json(self, **kwargs):
return json.loads(self.text, **kwargs)
class BaseTest(base.BaseTestCase):

View File

@ -155,6 +155,22 @@ class ActionExecutionTestsV2(base.TestCase):
output = json.loads(body['output'])
self.assertEqual(404, output['result']['status'])
@test.attr(type='sanity')
@test.related_bug('1667415')
@decorators.idempotent_id('3c73de7a-4af0-4657-90d6-d7ebd3c7da18')
def test_run_action_std_http_non_utf8_response(self):
resp, body = self.client.create_action_execution(
{
'name': 'std.http',
'input':
'{"url": "https://www.google.co.il/search?q=testTest"}'
}
)
self.assertEqual(201, resp.status)
output = json.loads(body['output'])
self.assertEqual(200, output['result']['status'])
@test.attr(type='sanity')
@decorators.idempotent_id('d98586bf-fdc4-44f6-9837-700d35b5f889')
def test_create_action_execution(self):