Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0dc81bf

Browse files
authored
Respect custom headers set on the request supplied to MediaIoBaseDownload within each call to next_chunk (googleapis#546)
Closes googleapis#207
1 parent 3cf5e60 commit 0dc81bf

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

googleapiclient/http.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,14 @@ def __init__(self, fd, request, chunksize=DEFAULT_CHUNK_SIZE):
647647
self._sleep = time.sleep
648648
self._rand = random.random
649649

650+
self._headers = {}
651+
for k, v in six.iteritems(request.headers):
652+
# allow users to supply custom headers by setting them on the request
653+
# but strip out the ones that are set by default on requests generated by
654+
# API methods like Drive's files().get(fileId=...)
655+
if not k.lower() in ('accept', 'accept-encoding', 'user-agent'):
656+
self._headers[k] = v
657+
650658
@util.positional(1)
651659
def next_chunk(self, num_retries=0):
652660
"""Get the next chunk of the download.
@@ -666,10 +674,9 @@ def next_chunk(self, num_retries=0):
666674
googleapiclient.errors.HttpError if the response was not a 2xx.
667675
httplib2.HttpLib2Error if a transport error has occured.
668676
"""
669-
headers = {
670-
'range': 'bytes=%d-%d' % (
677+
headers = self._headers.copy()
678+
headers['range'] = 'bytes=%d-%d' % (
671679
self._progress, self._progress + self._chunksize)
672-
}
673680
http = self._request.http
674681

675682
resp, content = _retry_request(

tests/test_http.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from six.moves.urllib.parse import urlencode
3030

3131
# Do not remove the httplib2 import
32+
import json
3233
import httplib2
3334
import logging
3435
import mock
@@ -456,6 +457,41 @@ def test_media_io_base_download(self):
456457
self.assertEqual(5, download._progress)
457458
self.assertEqual(5, download._total_size)
458459

460+
def test_media_io_base_download_custom_request_headers(self):
461+
self.request.http = HttpMockSequence([
462+
({'status': '200',
463+
'content-range': '0-2/5'}, 'echo_request_headers_as_json'),
464+
({'status': '200',
465+
'content-range': '3-4/5'}, 'echo_request_headers_as_json'),
466+
])
467+
self.assertEqual(True, self.request.http.follow_redirects)
468+
469+
self.request.headers['Cache-Control'] = 'no-store'
470+
471+
download = MediaIoBaseDownload(
472+
fd=self.fd, request=self.request, chunksize=3)
473+
474+
self.assertEqual(download._headers, {'Cache-Control':'no-store'})
475+
476+
status, done = download.next_chunk()
477+
478+
result = self.fd.getvalue().decode('utf-8')
479+
480+
# we abuse the internals of the object we're testing, pay no attention
481+
# to the actual bytes= values here; we are just asserting that the
482+
# header we added to the original request is sent up to the server
483+
# on each call to next_chunk
484+
485+
self.assertEqual(json.loads(result),
486+
{"Cache-Control": "no-store", "range": "bytes=0-3"})
487+
488+
download._fd = self.fd = BytesIO()
489+
status, done = download.next_chunk()
490+
491+
result = self.fd.getvalue().decode('utf-8')
492+
self.assertEqual(json.loads(result),
493+
{"Cache-Control": "no-store", "range": "bytes=51-54"})
494+
459495
def test_media_io_base_download_handle_redirects(self):
460496
self.request.http = HttpMockSequence([
461497
({'status': '200',

0 commit comments

Comments
 (0)