Make header Case Insensitive

In case of global-request-id request, Adapter
send two global request id header
 - "X-OpenStack-Request-ID"
 - "X-Openstack-Request-Id".

Example: https://zuul.opendev.org/t/openstack/build/c5b1debf78df4aa3bdda34f0b4c53c37/log/testrepository.subunit#2385

This is becasue of the header not being Case Insensitive
and end up with two different name of same header with difference
of cap 'D'.

Unit test for whether request global-request-id has precedence
over adapter fail many times because of how different python version
treat the dict. py3.6 and above are all good as dict maintain the
insertion ordered but py3.5 can fail it any time.

We can see consistent failure in py35 jobs:
- https://review.opendev.org/#/c/730687/

Let's make the headers always Case Insensitive which is
what RFC says.

Change-Id: Iba707dd0506d22e144aca4fdfc9b140c8e37ae02
Closes-Bug: #1881351
This commit is contained in:
Ghanshyam Mann 2020-05-29 16:04:47 -05:00
parent 1bffde3315
commit c00fca4a09
3 changed files with 20 additions and 3 deletions

View File

@ -13,6 +13,8 @@
import os
import warnings
import requests
from keystoneauth1 import _fair_semaphore
from keystoneauth1 import session
@ -198,7 +200,14 @@ class Adapter(object):
def request(self, url, method, **kwargs):
endpoint_filter = kwargs.setdefault('endpoint_filter', {})
self._set_endpoint_filter_kwargs(endpoint_filter)
# NOTE(gmann): Convert r initlize the headers to
# CaseInsensitiveDict to make sure headers are
# case insensitive.
if kwargs.get('headers'):
kwargs['headers'] = requests.structures.CaseInsensitiveDict(
kwargs['headers'])
else:
kwargs['headers'] = requests.structures.CaseInsensitiveDict()
if self.endpoint_override:
kwargs.setdefault('endpoint_override', self.endpoint_override)

View File

@ -753,6 +753,14 @@ class Session(object):
else:
split_loggers = None
logger = logger or utils.get_logger(__name__)
# NOTE(gmann): Convert r initlize the headers to
# CaseInsensitiveDict to make sure headers are
# case insensitive.
if kwargs.get('headers'):
kwargs['headers'] = requests.structures.CaseInsensitiveDict(
kwargs['headers'])
else:
kwargs['headers'] = requests.structures.CaseInsensitiveDict()
if connect_retries is None:
connect_retries = self._connect_retries
# HTTP 503 - Service Unavailable

View File

@ -1822,7 +1822,7 @@ class AdapterTest(utils.TestCase):
with mock.patch.object(sess, 'request') as m:
adapter.Adapter(sess, **adap_kwargs).get(url, **get_kwargs)
m.assert_called_once_with(url, 'GET', endpoint_filter={},
rate_semaphore=mock.ANY,
headers={}, rate_semaphore=mock.ANY,
**exp_kwargs)
# No default_microversion in Adapter, no microversion in get()
@ -1846,7 +1846,7 @@ class AdapterTest(utils.TestCase):
with mock.patch.object(sess, 'request') as m:
adapter.Adapter(sess, **adap_kwargs).get(url, **get_kwargs)
m.assert_called_once_with(url, 'GET', endpoint_filter={},
rate_semaphore=mock.ANY,
headers={}, rate_semaphore=mock.ANY,
**exp_kwargs)
# No raise_exc in Adapter or get()