Add additional_headers to session and adapter
Allow clients and services to set additional_headers that will be sent with all requests made by the session. Change-Id: Idbd2e5159de5790c7db65c806b964f220bb6628e
This commit is contained in:
parent
6b7db34f68
commit
1045a147dd
@ -45,13 +45,18 @@ class Adapter(object):
|
||||
:type logger: logging.Logger
|
||||
:param dict allow: Extra filters to pass when discovering API versions.
|
||||
(optional)
|
||||
:param dict additional_headers: Additional headers that should be attached
|
||||
to every request passing through the
|
||||
adapter. Headers of the same name specified
|
||||
per request will take priority.
|
||||
"""
|
||||
|
||||
@positional()
|
||||
def __init__(self, session, service_type=None, service_name=None,
|
||||
interface=None, region_name=None, endpoint_override=None,
|
||||
version=None, auth=None, user_agent=None,
|
||||
connect_retries=None, logger=None, allow={}):
|
||||
connect_retries=None, logger=None, allow={},
|
||||
additional_headers=None):
|
||||
# NOTE(jamielennox): when adding new parameters to adapter please also
|
||||
# add them to the adapter call in httpclient.HTTPClient.__init__ as
|
||||
# well as to load_adapter_from_argparse below if the argument is
|
||||
@ -69,6 +74,7 @@ class Adapter(object):
|
||||
self.connect_retries = connect_retries
|
||||
self.logger = logger
|
||||
self.allow = allow
|
||||
self.additional_headers = additional_headers or {}
|
||||
|
||||
def _set_endpoint_filter_kwargs(self, kwargs):
|
||||
if self.service_type:
|
||||
@ -100,6 +106,9 @@ class Adapter(object):
|
||||
if self.allow:
|
||||
kwargs.setdefault('allow', self.allow)
|
||||
|
||||
for k, v in self.additional_headers.items():
|
||||
kwargs.setdefault('headers', {}).setdefault(k, v)
|
||||
|
||||
return self.session.request(url, method, **kwargs)
|
||||
|
||||
def get_token(self, auth=None):
|
||||
|
@ -200,6 +200,10 @@ class Session(object):
|
||||
can be followed by a request. Either an integer
|
||||
for a specific count or True/False for
|
||||
forever/never. (optional, default to 30)
|
||||
:param dict additional_headers: Additional headers that should be attached
|
||||
to every request passing through the
|
||||
session. Headers of the same name specified
|
||||
per request will take priority.
|
||||
"""
|
||||
|
||||
user_agent = None
|
||||
@ -211,7 +215,7 @@ class Session(object):
|
||||
@positional(2)
|
||||
def __init__(self, auth=None, session=None, original_ip=None, verify=True,
|
||||
cert=None, timeout=None, user_agent=None,
|
||||
redirect=_DEFAULT_REDIRECT_LIMIT):
|
||||
redirect=_DEFAULT_REDIRECT_LIMIT, additional_headers=None):
|
||||
|
||||
self.auth = auth
|
||||
self.session = _construct_session(session)
|
||||
@ -220,6 +224,7 @@ class Session(object):
|
||||
self.cert = cert
|
||||
self.timeout = None
|
||||
self.redirect = redirect
|
||||
self.additional_headers = additional_headers or {}
|
||||
|
||||
if timeout is not None:
|
||||
self.timeout = float(timeout)
|
||||
@ -501,6 +506,9 @@ class Session(object):
|
||||
headers['Content-Type'] = 'application/json'
|
||||
kwargs['data'] = self._json.encode(json)
|
||||
|
||||
for k, v in self.additional_headers.items():
|
||||
headers.setdefault(k, v)
|
||||
|
||||
kwargs.setdefault('verify', self.verify)
|
||||
|
||||
if requests_auth:
|
||||
|
@ -930,6 +930,56 @@ class AdapterTest(utils.TestCase):
|
||||
self.TEST_URL,
|
||||
'GET')
|
||||
|
||||
def test_additional_headers(self):
|
||||
session_key = uuid.uuid4().hex
|
||||
session_val = uuid.uuid4().hex
|
||||
adapter_key = uuid.uuid4().hex
|
||||
adapter_val = uuid.uuid4().hex
|
||||
request_key = uuid.uuid4().hex
|
||||
request_val = uuid.uuid4().hex
|
||||
text = uuid.uuid4().hex
|
||||
|
||||
url = 'http://keystone.test.com'
|
||||
self.requests_mock.get(url, text=text)
|
||||
|
||||
sess = client_session.Session(
|
||||
additional_headers={session_key: session_val})
|
||||
adap = adapter.Adapter(session=sess,
|
||||
additional_headers={adapter_key: adapter_val})
|
||||
resp = adap.get(url, headers={request_key: request_val})
|
||||
|
||||
request = self.requests_mock.last_request
|
||||
|
||||
self.assertEqual(resp.text, text)
|
||||
self.assertEqual(session_val, request.headers[session_key])
|
||||
self.assertEqual(adapter_val, request.headers[adapter_key])
|
||||
self.assertEqual(request_val, request.headers[request_key])
|
||||
|
||||
def test_additional_headers_overrides(self):
|
||||
header = uuid.uuid4().hex
|
||||
session_val = uuid.uuid4().hex
|
||||
adapter_val = uuid.uuid4().hex
|
||||
request_val = uuid.uuid4().hex
|
||||
|
||||
url = 'http://keystone.test.com'
|
||||
self.requests_mock.get(url)
|
||||
|
||||
sess = client_session.Session(additional_headers={header: session_val})
|
||||
adap = adapter.Adapter(session=sess)
|
||||
|
||||
adap.get(url)
|
||||
self.assertEqual(session_val,
|
||||
self.requests_mock.last_request.headers[header])
|
||||
|
||||
adap.additional_headers[header] = adapter_val
|
||||
adap.get(url)
|
||||
self.assertEqual(adapter_val,
|
||||
self.requests_mock.last_request.headers[header])
|
||||
|
||||
adap.get(url, headers={header: request_val})
|
||||
self.assertEqual(request_val,
|
||||
self.requests_mock.last_request.headers[header])
|
||||
|
||||
|
||||
class TCPKeepAliveAdapterTest(utils.TestCase):
|
||||
|
||||
|
10
releasenotes/notes/additional-headers-f2d16f85f5abe942.yaml
Normal file
10
releasenotes/notes/additional-headers-f2d16f85f5abe942.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
prelude: >
|
||||
Allow specifying additional_headers to the session and the adapter to add
|
||||
headers to all requests that pass through these objects.
|
||||
features:
|
||||
- Add the ability to provide additional_headers to the session and adapter
|
||||
object. This will allow clients particularly to provide additional ways to
|
||||
identify their requests. It will also hopefully provide an intermediate way
|
||||
to handle setting microversions until we support them directly with
|
||||
keystoneauth.
|
Loading…
Reference in New Issue
Block a user