Skip to content

Commit

Permalink
fix: MediaIoBaseDownload range header off-by-one
Browse files Browse the repository at this point in the history
Issue: It looks like Range header end value was constructed by adding chunk size to
current position. This leads into the request being one byte longer, and also
the received response body is one byte longer than anticipated.

Fix: adjust the end to be one byte earlier.

For example with `chunksize=1024` and current position being 0, the range header
should be set to `bytes=0-1023`.

See: https://httpwg.org/specs/rfc7233.html#rule.ranges-specifier

Resolves: #1593
  • Loading branch information
jvtm committed Nov 9, 2021
1 parent 5dcb723 commit d9777dc
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 1 deletion.
2 changes: 1 addition & 1 deletion googleapiclient/http.py
Expand Up @@ -733,7 +733,7 @@ def next_chunk(self, num_retries=0):
headers = self._headers.copy()
headers["range"] = "bytes=%d-%d" % (
self._progress,
self._progress + self._chunksize,
self._progress + self._chunksize - 1,
)
http = self._request.http

Expand Down
17 changes: 17 additions & 0 deletions tests/test_http.py
Expand Up @@ -488,6 +488,23 @@ def test_media_io_base_download(self):
self.assertEqual(5, download._progress)
self.assertEqual(5, download._total_size)

def test_media_io_base_download_range_request_header(self):
self.request.http = HttpMockSequence(
[
(
{"status": "200", "content-range": "0-2/5"},
"echo_request_headers_as_json",
),
]
)

download = MediaIoBaseDownload(fd=self.fd, request=self.request, chunksize=3)

status, done = download.next_chunk()
result = json.loads(self.fd.getvalue().decode("utf-8"))

self.assertEqual(result.get("range"), "bytes=0-2")

def test_media_io_base_download_custom_request_headers(self):
self.request.http = HttpMockSequence(
[
Expand Down

0 comments on commit d9777dc

Please sign in to comment.