Skip to content

Commit 4b73b2e

Browse files
authored
fix: MediaIoBaseDownload range header off-by-one (#1595)
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 Fixes #1593 ---- Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: - [x] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/google-api-python-client/issues/new/choose) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea - [x] Ensure the tests and linter pass - [x] Code coverage does not decrease (if any source code was changed) - [ ] Appropriate docs were updated (if necessary) Fixes #1593 🦕
1 parent 2a718c3 commit 4b73b2e

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

googleapiclient/http.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,7 @@ def next_chunk(self, num_retries=0):
733733
headers = self._headers.copy()
734734
headers["range"] = "bytes=%d-%d" % (
735735
self._progress,
736-
self._progress + self._chunksize,
736+
self._progress + self._chunksize - 1,
737737
)
738738
http = self._request.http
739739

tests/test_http.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,23 @@ def test_media_io_base_download(self):
488488
self.assertEqual(5, download._progress)
489489
self.assertEqual(5, download._total_size)
490490

491+
def test_media_io_base_download_range_request_header(self):
492+
self.request.http = HttpMockSequence(
493+
[
494+
(
495+
{"status": "200", "content-range": "0-2/5"},
496+
"echo_request_headers_as_json",
497+
),
498+
]
499+
)
500+
501+
download = MediaIoBaseDownload(fd=self.fd, request=self.request, chunksize=3)
502+
503+
status, done = download.next_chunk()
504+
result = json.loads(self.fd.getvalue().decode("utf-8"))
505+
506+
self.assertEqual(result.get("range"), "bytes=0-2")
507+
491508
def test_media_io_base_download_custom_request_headers(self):
492509
self.request.http = HttpMockSequence(
493510
[

0 commit comments

Comments
 (0)