Skip to content

Commit

Permalink
Ensure that iter_bytes does not ever yield any zero-length chunks (#2068
Browse files Browse the repository at this point in the history
)
  • Loading branch information
tomchristie committed Feb 7, 2022
1 parent 0088253 commit 420911b
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 3 deletions.
2 changes: 1 addition & 1 deletion httpx/_decoders.py
Expand Up @@ -172,7 +172,7 @@ def __init__(self, chunk_size: int = None) -> None:

def decode(self, content: bytes) -> typing.List[bytes]:
if self._chunk_size is None:
return [content]
return [content] if content else []

self._buffer.write(content)
if self._buffer.tell() >= self._chunk_size:
Expand Down
4 changes: 2 additions & 2 deletions httpx/_models.py
Expand Up @@ -1585,7 +1585,7 @@ def iter_bytes(self, chunk_size: int = None) -> typing.Iterator[bytes]:
yield chunk
decoded = decoder.flush()
for chunk in chunker.decode(decoded):
yield chunk
yield chunk # pragma: nocover
for chunk in chunker.flush():
yield chunk

Expand Down Expand Up @@ -1683,7 +1683,7 @@ async def aiter_bytes(self, chunk_size: int = None) -> typing.AsyncIterator[byte
yield chunk
decoded = decoder.flush()
for chunk in chunker.decode(decoded):
yield chunk
yield chunk # pragma: nocover
for chunk in chunker.flush():
yield chunk

Expand Down
26 changes: 26 additions & 0 deletions tests/models/test_responses.py
Expand Up @@ -396,6 +396,19 @@ def test_iter_raw_with_chunksize():
assert parts == [b"Hello, world!"]


def test_iter_raw_doesnt_return_empty_chunks():
def streaming_body_with_empty_chunks():
yield b"Hello, "
yield b""
yield b"world!"
yield b""

response = httpx.Response(200, content=streaming_body_with_empty_chunks())

parts = [part for part in response.iter_raw()]
assert parts == [b"Hello, ", b"world!"]


def test_iter_raw_on_iterable():
response = httpx.Response(
200,
Expand Down Expand Up @@ -526,6 +539,19 @@ def test_iter_bytes_with_empty_response():
assert parts == []


def test_iter_bytes_doesnt_return_empty_chunks():
def streaming_body_with_empty_chunks():
yield b"Hello, "
yield b""
yield b"world!"
yield b""

response = httpx.Response(200, content=streaming_body_with_empty_chunks())

parts = [part for part in response.iter_bytes()]
assert parts == [b"Hello, ", b"world!"]


@pytest.mark.asyncio
async def test_aiter_bytes():
response = httpx.Response(
Expand Down

0 comments on commit 420911b

Please sign in to comment.