summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Rosmaita <rosmaita.fossdev@gmail.com>2018-05-14 16:19:46 -0400
committerMonty Taylor <mordred@inaugust.com>2018-05-15 09:29:43 -0500
commit35de6ebe93b94076964f4250bf3fa9b8ff1f8463 (patch)
tree43f15fc8fe4335e7389f0003dd605c9020ce9036
parent0bebdaf0f90deef5121234ac98daa58e6f1f0f77 (diff)
Fix logging of encoded headers3.6.2
A change introduced in 3.5.0 sorts headers, but runs into a problem when the headers are bytes, such as the headers provided by the python-glanceclient. requests expects headers to be str type in both python2 and python3. This means in python2 we need to encode unicode objects as ASCII (the encoding that should be used for HTTP headers) and in python3 we need to decode bytes as ASCII into str. Change-Id: Ib81497c3a873616c22ba68256c596a6fb113e11e Closes-bug: #1766235
Notes
Notes (review): Code-Review+2: Colleen Murphy <colleen@gazlene.net> Code-Review+2: Morgan Fainberg <morgan.fainberg@gmail.com> Workflow+1: Monty Taylor <mordred@inaugust.com> Verified+2: Zuul Submitted-by: Zuul Submitted-at: Wed, 16 May 2018 20:45:07 +0000 Reviewed-on: https://review.openstack.org/568365 Project: openstack/keystoneauth Branch: refs/heads/master
-rw-r--r--keystoneauth1/session.py24
-rw-r--r--keystoneauth1/tests/unit/test_session.py9
-rw-r--r--releasenotes/notes/bug-1766235wq-0de60d0f996c6bfb.yaml6
3 files changed, 38 insertions, 1 deletions
diff --git a/keystoneauth1/session.py b/keystoneauth1/session.py
index 6ab1e14..d9e99d3 100644
--- a/keystoneauth1/session.py
+++ b/keystoneauth1/session.py
@@ -79,6 +79,26 @@ def _mv_legacy_headers_for_service(mv_service_type):
79 return headers 79 return headers
80 80
81 81
82def _sanitize_headers(headers):
83 """Ensure headers are strings and not bytes."""
84 str_dict = {}
85 for k, v in headers.items():
86 if six.PY3:
87 # requests expects headers to be str type in python3, which means
88 # if we get a bytes we need to decode it into a str
89 k = k.decode('ASCII') if isinstance(k, six.binary_type) else k
90 if v is not None:
91 v = v.decode('ASCII') if isinstance(v, six.binary_type) else v
92 else:
93 # requests expects headers to be str type in python2, which means
94 # if we get a unicode we need to encode it to ASCII into a str
95 k = k.encode('ASCII') if isinstance(k, six.text_type) else k
96 if v is not None:
97 v = v.encode('ASCII') if isinstance(v, six.text_type) else v
98 str_dict[k] = v
99 return str_dict
100
101
82class _JSONEncoder(json.JSONEncoder): 102class _JSONEncoder(json.JSONEncoder):
83 103
84 def default(self, o): 104 def default(self, o):
@@ -711,6 +731,10 @@ class Session(object):
711 for k, v in self.additional_headers.items(): 731 for k, v in self.additional_headers.items():
712 headers.setdefault(k, v) 732 headers.setdefault(k, v)
713 733
734 # Bug #1766235: some headers may be bytes
735 headers = _sanitize_headers(headers)
736 kwargs['headers'] = headers
737
714 kwargs.setdefault('verify', self.verify) 738 kwargs.setdefault('verify', self.verify)
715 739
716 if requests_auth: 740 if requests_auth:
diff --git a/keystoneauth1/tests/unit/test_session.py b/keystoneauth1/tests/unit/test_session.py
index 94cc7d1..a7165e1 100644
--- a/keystoneauth1/tests/unit/test_session.py
+++ b/keystoneauth1/tests/unit/test_session.py
@@ -17,6 +17,7 @@ import sys
17import uuid 17import uuid
18 18
19import mock 19import mock
20from oslo_utils import encodeutils
20import requests 21import requests
21import requests.auth 22import requests.auth
22import six 23import six
@@ -987,7 +988,12 @@ class SessionAuthTests(utils.TestCase):
987 'X-OpenStack-Request-ID': request_id, 988 'X-OpenStack-Request-ID': request_id,
988 }) 989 })
989 990
990 resp = sess.get(self.TEST_URL) 991 resp = sess.get(
992 self.TEST_URL,
993 headers={
994 encodeutils.safe_encode('x-bytes-header'):
995 encodeutils.safe_encode('bytes-value')
996 })
991 997
992 self.assertEqual(response, resp.json()) 998 self.assertEqual(response, resp.json())
993 999
@@ -998,6 +1004,7 @@ class SessionAuthTests(utils.TestCase):
998 1004
999 self.assertIn('curl -g -i -X GET {url}'.format(url=self.TEST_URL), 1005 self.assertIn('curl -g -i -X GET {url}'.format(url=self.TEST_URL),
1000 request_output) 1006 request_output)
1007 self.assertIn('-H "x-bytes-header: bytes-value"', request_output)
1001 self.assertEqual('[200] Content-Type: application/json ' 1008 self.assertEqual('[200] Content-Type: application/json '
1002 'X-OpenStack-Request-ID: ' 1009 'X-OpenStack-Request-ID: '
1003 '{id}'.format(id=request_id), response_output) 1010 '{id}'.format(id=request_id), response_output)
diff --git a/releasenotes/notes/bug-1766235wq-0de60d0f996c6bfb.yaml b/releasenotes/notes/bug-1766235wq-0de60d0f996c6bfb.yaml
new file mode 100644
index 0000000..1c45aed
--- /dev/null
+++ b/releasenotes/notes/bug-1766235wq-0de60d0f996c6bfb.yaml
@@ -0,0 +1,6 @@
1---
2fixes:
3 - |
4 [`bug 1766235 <https://bugs.launchpad.net/keystoneauth/+bug/1766235>`_]
5 Fixed an issue where passing headers in as bytes rather than strings
6 would cause a sorting issue.