Skip to content
This repository was archived by the owner on May 6, 2026. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/latest/.buildinfo
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: b911398855f7668d2aa125e82024376d
config: 476de7aba2e9373b12d01844d1987590
tags: 645f666f9bcd5a90fca523b33c5a78b7
2 changes: 1 addition & 1 deletion docs/latest/_static/documentation_options.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '0.4.0',
VERSION: '0.4.1',
LANGUAGE: 'None',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
Expand Down
4 changes: 2 additions & 2 deletions docs/latest/genindex.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Index &mdash; google-resumable-media 0.4.0 documentation</title>
<title>Index &mdash; google-resumable-media 0.4.1 documentation</title>



Expand Down Expand Up @@ -59,7 +59,7 @@


<div class="version">
0.4.0
0.4.1
</div>


Expand Down
4 changes: 2 additions & 2 deletions docs/latest/google.resumable_media.common.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>google.resumable_media.common &mdash; google-resumable-media 0.4.0 documentation</title>
<title>google.resumable_media.common &mdash; google-resumable-media 0.4.1 documentation</title>



Expand Down Expand Up @@ -60,7 +60,7 @@


<div class="version">
0.4.0
0.4.1
</div>


Expand Down
4 changes: 2 additions & 2 deletions docs/latest/google.resumable_media.requests.download.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>google.resumable_media.requests.download &mdash; google-resumable-media 0.4.0 documentation</title>
<title>google.resumable_media.requests.download &mdash; google-resumable-media 0.4.1 documentation</title>



Expand Down Expand Up @@ -60,7 +60,7 @@


<div class="version">
0.4.0
0.4.1
</div>


Expand Down
4 changes: 2 additions & 2 deletions docs/latest/google.resumable_media.requests.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>google.resumable_media.requests &mdash; google-resumable-media 0.4.0 documentation</title>
<title>google.resumable_media.requests &mdash; google-resumable-media 0.4.1 documentation</title>



Expand Down Expand Up @@ -60,7 +60,7 @@


<div class="version">
0.4.0
0.4.1
</div>


Expand Down
4 changes: 2 additions & 2 deletions docs/latest/google.resumable_media.requests.upload.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>google.resumable_media.requests.upload &mdash; google-resumable-media 0.4.0 documentation</title>
<title>google.resumable_media.requests.upload &mdash; google-resumable-media 0.4.1 documentation</title>



Expand Down Expand Up @@ -59,7 +59,7 @@


<div class="version">
0.4.0
0.4.1
</div>


Expand Down
4 changes: 2 additions & 2 deletions docs/latest/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>google.resumable_media &mdash; google-resumable-media 0.4.0 documentation</title>
<title>google.resumable_media &mdash; google-resumable-media 0.4.1 documentation</title>



Expand Down Expand Up @@ -59,7 +59,7 @@


<div class="version">
0.4.0
0.4.1
</div>


Expand Down
Binary file modified docs/latest/objects.inv
Binary file not shown.
4 changes: 2 additions & 2 deletions docs/latest/py-modindex.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Python Module Index &mdash; google-resumable-media 0.4.0 documentation</title>
<title>Python Module Index &mdash; google-resumable-media 0.4.1 documentation</title>



Expand Down Expand Up @@ -61,7 +61,7 @@


<div class="version">
0.4.0
0.4.1
</div>


Expand Down
4 changes: 2 additions & 2 deletions docs/latest/search.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Search &mdash; google-resumable-media 0.4.0 documentation</title>
<title>Search &mdash; google-resumable-media 0.4.1 documentation</title>



Expand Down Expand Up @@ -59,7 +59,7 @@


<div class="version">
0.4.0
0.4.1
</div>


Expand Down
40 changes: 26 additions & 14 deletions google/resumable_media/_download.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,24 +354,36 @@ def _process_response(self, response):
self._get_status_code,
callback=self._make_invalid,
)
content_length = _helpers.header_required(
response, u"content-length", self._get_headers, callback=self._make_invalid
)
num_bytes = int(content_length)
_, end_byte, total_bytes = get_range_info(
headers = self._get_headers(response)
response_body = self._get_body(response)

start_byte, end_byte, total_bytes = get_range_info(
response, self._get_headers, callback=self._make_invalid
)
response_body = self._get_body(response)
if len(response_body) != num_bytes:
self._make_invalid()
raise common.InvalidResponse(

transfer_encoding = headers.get(u"transfer-encoding")

if transfer_encoding is None:
content_length = _helpers.header_required(
response,
u"Response is different size than content-length",
u"Expected",
num_bytes,
u"Received",
len(response_body),
u"content-length",
self._get_headers,
callback=self._make_invalid,
)
num_bytes = int(content_length)
if len(response_body) != num_bytes:
self._make_invalid()
raise common.InvalidResponse(
response,
u"Response is different size than content-length",
u"Expected",
num_bytes,
u"Received",
len(response_body),
)
else:
# 'content-length' header not allowed with chunked encoding.
num_bytes = end_byte - start_byte + 1

# First update ``bytes_downloaded``.
self._bytes_downloaded += num_bytes
Expand Down
64 changes: 49 additions & 15 deletions tests/unit/test__download.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def test__process_response(self):

# Make sure **not finished** before.
assert not download.finished
response = mock.Mock(status_code=int(http_client.OK), spec=[u"status_code"])
response = mock.Mock(status_code=int(http_client.OK), spec=["status_code"])
ret_val = download._process_response(response)
assert ret_val is None
# Make sure **finished** after.
Expand All @@ -141,7 +141,7 @@ def test__process_response_bad_status(self):
# Make sure **not finished** before.
assert not download.finished
response = mock.Mock(
status_code=int(http_client.NOT_FOUND), spec=[u"status_code"]
status_code=int(http_client.NOT_FOUND), spec=["status_code"]
)
with pytest.raises(common.InvalidResponse) as exc_info:
download._process_response(response)
Expand Down Expand Up @@ -263,7 +263,7 @@ def _mock_response(
content=content,
headers=response_headers,
status_code=status_code,
spec=[u"content", u"headers", u"status_code"],
spec=["content", "headers", "status_code"],
)

def test__prepare_request_already_finished(self):
Expand Down Expand Up @@ -322,7 +322,8 @@ def test__make_invalid(self):
assert download.invalid

def test__process_response(self):
chunk_size = 333
data = b"1234xyztL" * 37 # 9 * 37 == 33
chunk_size = len(data)
stream = io.BytesIO()
download = _download.ChunkedDownload(EXAMPLE_URL, chunk_size, stream)
_fix_up_virtual(download)
Expand All @@ -336,7 +337,6 @@ def test__process_response(self):
assert download.bytes_downloaded == already
assert download.total_bytes is None
# Actually call the method to update.
data = b"1234xyztL" * 37 # 9 * 37 == 33
response = self._mock_response(
already,
already + chunk_size - 1,
Expand All @@ -351,9 +351,42 @@ def test__process_response(self):
assert download.total_bytes == total_bytes
assert stream.getvalue() == data

def test__process_response_transfer_encoding(self):
data = b"1234xyztL" * 37
chunk_size = len(data)
stream = io.BytesIO()
download = _download.ChunkedDownload(EXAMPLE_URL, chunk_size, stream)
_fix_up_virtual(download)

already = 22
download._bytes_downloaded = already
total_bytes = 4444

# Check internal state before.
assert not download.finished
assert download.bytes_downloaded == already
assert download.total_bytes is None
assert not download.invalid
# Actually call the method to update.
response = self._mock_response(
already,
already + chunk_size - 1,
total_bytes,
content=data,
status_code=int(http_client.PARTIAL_CONTENT),
)
response.headers[u"transfer-encoding"] = "chunked"
del response.headers[u"content-length"]
download._process_response(response)
# Check internal state after.
assert not download.finished
assert download.bytes_downloaded == already + chunk_size
assert download.total_bytes == total_bytes
assert stream.getvalue() == data

def test__process_response_bad_status(self):
chunk_size = 384
stream = mock.Mock(spec=[u"write"])
stream = mock.Mock(spec=["write"])
download = _download.ChunkedDownload(EXAMPLE_URL, chunk_size, stream)
_fix_up_virtual(download)

Expand Down Expand Up @@ -394,9 +427,10 @@ def test__process_response_missing_content_length(self):
assert not download.invalid
# Actually call the method to update.
response = mock.Mock(
headers={},
headers={u"content-range": u"bytes 0-99/99"},
status_code=int(http_client.PARTIAL_CONTENT),
spec=[u"headers", u"status_code"],
content=b"DEADBEEF",
spec=["headers", "status_code", "content"],
)
with pytest.raises(common.InvalidResponse) as exc_info:
download._process_response(response)
Expand Down Expand Up @@ -430,7 +464,7 @@ def test__process_response_bad_content_range(self):
content=data,
headers=headers,
status_code=int(http_client.PARTIAL_CONTENT),
spec=[u"content", u"headers", u"status_code"],
spec=["content", "headers", "status_code"],
)
with pytest.raises(common.InvalidResponse) as exc_info:
download._process_response(response)
Expand All @@ -447,7 +481,7 @@ def test__process_response_bad_content_range(self):

def test__process_response_body_wrong_length(self):
chunk_size = 10
stream = mock.Mock(spec=[u"write"])
stream = mock.Mock(spec=["write"])
download = _download.ChunkedDownload(EXAMPLE_URL, chunk_size, stream)
_fix_up_virtual(download)

Expand Down Expand Up @@ -544,15 +578,15 @@ def test__process_response_when_reaching_end(self):

def test__process_response_when_content_range_is_zero(self):
chunk_size = 10
stream = mock.Mock(spec=[u"write"])
stream = mock.Mock(spec=["write"])
download = _download.ChunkedDownload(EXAMPLE_URL, chunk_size, stream)
_fix_up_virtual(download)

content_range = _download._ZERO_CONTENT_RANGE_HEADER
headers = {u"content-range": content_range}
status_code = http_client.REQUESTED_RANGE_NOT_SATISFIABLE
response = mock.Mock(
headers=headers, status_code=status_code, spec=[u"headers", "status_code"]
headers=headers, status_code=status_code, spec=["headers", "status_code"]
)
download._process_response(response)
stream.write.assert_not_called()
Expand Down Expand Up @@ -604,7 +638,7 @@ class Test_get_range_info(object):
@staticmethod
def _make_response(content_range):
headers = {u"content-range": content_range}
return mock.Mock(headers=headers, spec=[u"headers"])
return mock.Mock(headers=headers, spec=["headers"])

def _success_helper(self, **kwargs):
content_range = u"Bytes 7-11/42"
Expand Down Expand Up @@ -644,7 +678,7 @@ def test_failure_with_callback(self):
callback.assert_called_once_with()

def _missing_header_helper(self, **kwargs):
response = mock.Mock(headers={}, spec=[u"headers"])
response = mock.Mock(headers={}, spec=["headers"])
with pytest.raises(common.InvalidResponse) as exc_info:
_download.get_range_info(response, _get_headers, **kwargs)

Expand All @@ -667,7 +701,7 @@ class Test__check_for_zero_content_range(object):
def _make_response(content_range, status_code):
headers = {u"content-range": content_range}
return mock.Mock(
headers=headers, status_code=status_code, spec=[u"headers", "status_code"]
headers=headers, status_code=status_code, spec=["headers", "status_code"]
)

def test_status_code_416_and_test_content_range_zero_both(self):
Expand Down