Skip to content

aiter_lines() doesn't return full lines that span multiple chunks #1033

Description

@scr-oath

https://gist.github.com/scr-oath/aa76d200222a0409d09a0d6feb1a13e2 shows an example setup using cherry.py as server that just outputs two lines - the json is big enough to be sent in two chunks; httpx aiter_lines() gets confused and sends data from the middle of the json line - seems to skip the starting part - which was most likely sent in a chunk without a newline

test-httpx.py

import asyncio
import json

import httpx


class TestHttpx:
    def __init__(self):
        pass

    async def __call__(self):
        http_client = httpx.AsyncClient()
        async with http_client.stream(method="GET", url='http://localhost:8080/lines') as response:
            is_message = True
            async for line in response.aiter_lines():
                is_message = not is_message
                if is_message:
                    message = json.loads(line)
                    print(message)


def main():
    test_httpx = TestHttpx()
    asyncio.run(test_httpx())


if __name__ == '__main__':
    main()

Activity

  1. scr-oath commented on Jun 24, 2020

    @scr-oath
    ContributorAuthor

    It seems like the LineDecoder needs to remember partial work when called again so that it can prepend the new text with the previous line.

  2. scr-oath commented on Jun 24, 2020

    @scr-oath
    ContributorAuthor

    Here's a really small test case:

        decoder = LineDecoder()
        assert decoder.decode("") == []
        assert decoder.decode("12345\r\n") == ["12345\n"]
        assert decoder.decode("foo ") == []
        assert decoder.decode("bar ") == []
        assert decoder.decode("baz\r\n") == ["foo bar baz\n"]
    FAILED                          [100%]
    tests/test_decoders.py:240 (test_line_decoder_crnl)
    ['bar baz
    '] != ['foo bar baz
    ']
    
  3. added a commit that references this issue on Jun 24, 2020
    fd1a124
  4. added 2 commits that reference this issue on Jul 21, 2020
    ad5e6eb
    20f4911
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions