Skip to content

Commit c8b0ff1

Browse files
authored
Merge pull request #3035 from dhermes/fix-3006
Adding ability to send version info header on HTTP requests.
2 parents cf807db + 89b7231 commit c8b0ff1

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

packages/google-cloud-core/google/cloud/_http.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
"""Shared implementation of connections to API servers."""
1616

1717
import json
18+
import platform
1819
from pkg_resources import get_distribution
20+
1921
import six
2022
from six.moves.urllib.parse import urlencode
2123

@@ -29,6 +31,10 @@
2931
get_distribution('google-cloud-core').version)
3032
"""The user agent for google-cloud-python requests."""
3133

34+
CLIENT_INFO_HEADER = 'X-Goog-API-Client'
35+
CLIENT_INFO_TEMPLATE = (
36+
'gl-python/' + platform.python_version() + ' gccl/{}')
37+
3238

3339
class Connection(object):
3440
"""A generic connection to Google Cloud Platform.
@@ -38,6 +44,11 @@ class Connection(object):
3844
"""
3945

4046
USER_AGENT = DEFAULT_USER_AGENT
47+
_EXTRA_HEADERS = {}
48+
"""Headers to be sent with every request.
49+
50+
Intended to be over-ridden by subclasses.
51+
"""
4152

4253
def __init__(self, client):
4354
self._client = client
@@ -147,7 +158,9 @@ def _make_request(self, method, url, data=None, content_type=None,
147158
:param content_type: The proper MIME type of the data provided.
148159
149160
:type headers: dict
150-
:param headers: A dictionary of HTTP headers to send with the request.
161+
:param headers: (Optional) A dictionary of HTTP headers to send with
162+
the request. If passed, will be modified directly
163+
here with added headers.
151164
152165
:type target_object: object
153166
:param target_object:
@@ -161,6 +174,7 @@ def _make_request(self, method, url, data=None, content_type=None,
161174
returned by :meth:`_do_request`.
162175
"""
163176
headers = headers or {}
177+
headers.update(self._EXTRA_HEADERS)
164178
headers['Accept-Encoding'] = 'gzip'
165179

166180
if data:

packages/google-cloud-core/unit_tests/test__http.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,44 @@ def test_api_request_w_headers(self):
287287
}
288288
self.assertEqual(http._called_with['headers'], expected_headers)
289289

290+
def test_api_request_w_extra_headers(self):
291+
from six.moves.urllib.parse import urlsplit
292+
293+
http = _Http(
294+
{'status': '200', 'content-type': 'application/json'},
295+
b'{}',
296+
)
297+
client = mock.Mock(_http=http, spec=['_http'])
298+
conn = self._make_mock_one(client)
299+
conn._EXTRA_HEADERS = {
300+
'X-Baz': 'dax-quux',
301+
'X-Foo': 'not-bar', # Collision with ``headers``.
302+
}
303+
self.assertEqual(
304+
conn.api_request('GET', '/', headers={'X-Foo': 'bar'}), {})
305+
self.assertEqual(http._called_with['method'], 'GET')
306+
uri = http._called_with['uri']
307+
scheme, netloc, path, qs, _ = urlsplit(uri)
308+
self.assertEqual('%s://%s' % (scheme, netloc), conn.API_BASE_URL)
309+
# Intended to emulate self.mock_template
310+
PATH = '/'.join([
311+
'',
312+
'mock',
313+
conn.API_VERSION,
314+
'',
315+
])
316+
self.assertEqual(path, PATH)
317+
self.assertEqual(qs, '')
318+
self.assertIsNone(http._called_with['body'])
319+
expected_headers = {
320+
'Accept-Encoding': 'gzip',
321+
'Content-Length': '0',
322+
'User-Agent': conn.USER_AGENT,
323+
'X-Foo': 'not-bar', # The one passed-in is overridden.
324+
'X-Baz': 'dax-quux',
325+
}
326+
self.assertEqual(http._called_with['headers'], expected_headers)
327+
290328
def test_api_request_w_data(self):
291329
import json
292330

0 commit comments

Comments
 (0)