Fixes for Unicode characters in python 2 requests

urljoin() util function uses str() which will trigger an exception on
Unicode characters in python 2, use string type from six to support both
versions

Furthermore, HttpException would trigger an exception when logging an
error, as __unicode__() may call super().__str__() with Unicode
characters. Replace the call with similar code (returning the message)

Sample command to trigger both errors in current code:
openstack port delete does_not_exist™

Change-Id: Iedc47fa74e89f70e6f5e846f8a564bf1db40228a
Story: 2004356
Task: 29066
This commit is contained in:
Bernard Cafarelli 2019-01-28 11:05:22 +01:00
parent 92889d9f24
commit c7bbaf32f3
No known key found for this signature in database
GPG Key ID: D148244A3C2462BD
4 changed files with 27 additions and 2 deletions

View File

@ -94,7 +94,7 @@ class HttpException(SDKException, _rex.HTTPError):
# and we should use it. If it is 'Error', then we should construct a
# better message from the information we do have.
if not self.url or self.message == 'Error':
return super(HttpException, self).__str__()
return self.message
if self.url:
remote_error = "{source} Error for url: {url}".format(
source=self.source, url=self.url)

View File

@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
@ -60,6 +62,14 @@ class Test_HttpException(base.TestCase):
self.assertEqual(self.message, exc.message)
self.assertEqual(http_status, exc.status_code)
def test_unicode_message(self):
unicode_message = u"Event: No item found for does_not_exist©"
http_exception = exceptions.HttpException(message=unicode_message)
try:
http_exception.__unicode__()
except Exception:
self.fail("HttpException unicode message error")
class TestRaiseFromResponse(base.TestCase):

View File

@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
@ -115,6 +117,17 @@ class Test_urljoin(base.TestCase):
result = utils.urljoin(root, *leaves)
self.assertEqual(result, "http://www.example.com/foo/")
def test_unicode_strings(self):
root = "http://www.example.com"
leaves = u"ascii", u"extra_chars-™"
try:
result = utils.urljoin(root, *leaves)
except Exception:
self.fail("urljoin failed on unicode strings")
self.assertEqual(result, u"http://www.example.com/ascii/extra_chars-™")
class TestMaximumSupportedMicroversion(base.TestCase):
def setUp(self):

View File

@ -13,6 +13,8 @@
import string
import time
import six
import keystoneauth1
from keystoneauth1 import discover
@ -27,7 +29,7 @@ def urljoin(*args):
like /path this should be joined to http://host/path as it is an anchored
link. We generally won't care about that in client.
"""
return '/'.join(str(a or '').strip('/') for a in args)
return '/'.join(six.text_type(a or '').strip('/') for a in args)
def iterate_timeout(timeout, message, wait=2):