Example #1
0
async def test_aiter_raw():
    stream = AsyncIteratorStream(aiterator=async_streaming_body())
    response = httpx.Response(200, stream=stream, request=REQUEST)

    raw = b""
    async for part in response.aiter_raw():
        raw += part
    assert raw == b"Hello, world!"
Example #2
0
async def test_text_decoder(data, encoding):
    async def iterator():
        nonlocal data
        for chunk in data:
            yield chunk

    # Accessing `.text` on a read response.
    stream = AsyncIteratorStream(aiterator=iterator())
    response = httpx.Response(200, stream=stream, request=REQUEST)
    await response.aread()
    assert response.text == (b"".join(data)).decode(encoding)

    # Streaming `.aiter_text` iteratively.
    stream = AsyncIteratorStream(aiterator=iterator())
    response = httpx.Response(200, stream=stream, request=REQUEST)
    text = "".join([part async for part in response.aiter_text()])
    assert text == (b"".join(data)).decode(encoding)
Example #3
0
async def test_cannot_read_after_response_closed():
    stream = AsyncIteratorStream(aiterator=async_streaming_body())
    response = httpx.Response(200, stream=stream, request=REQUEST)

    await response.aclose()

    with pytest.raises(httpx.ResponseClosed):
        await response.aread()
Example #4
0
async def test_cannot_read_after_stream_consumed():
    stream = AsyncIteratorStream(aiterator=async_streaming_body())
    response = httpx.Response(200, stream=stream, request=REQUEST)

    content = b""
    async for part in response.aiter_bytes():
        content += part

    with pytest.raises(httpx.StreamConsumed):
        await response.aread()
Example #5
0
async def test_text_decoder(data, encoding):
    async def iterator():
        nonlocal data
        for chunk in data:
            yield chunk

    stream = AsyncIteratorStream(aiterator=iterator())
    response = httpx.Response(200, stream=stream, request=REQUEST)
    await response.aread()
    assert response.text == (b"".join(data)).decode(encoding)
Example #6
0
async def test_streaming_response():
    stream = AsyncIteratorStream(aiterator=async_streaming_body())
    response = httpx.Response(200, stream=stream, request=REQUEST)

    assert response.status_code == 200
    assert not response.is_closed

    content = await response.aread()

    assert content == b"Hello, world!"
    assert response.content == b"Hello, world!"
    assert response.is_closed
Example #7
0
async def test_streaming():
    body = b"test 123"
    compressor = zlib.compressobj(9, zlib.DEFLATED, zlib.MAX_WBITS | 16)

    async def compress(body):
        yield compressor.compress(body)
        yield compressor.flush()

    headers = [(b"Content-Encoding", b"gzip")]
    stream = AsyncIteratorStream(aiterator=compress(body))
    response = httpx.Response(200, headers=headers, stream=stream)
    assert not hasattr(response, "body")
    assert await response.read() == body
Example #8
0
async def test_text_decoder_known_encoding():
    async def iterator():
        yield b"\x83g"
        yield b"\x83"
        yield b"\x89\x83x\x83\x8b"

    stream = AsyncIteratorStream(aiterator=iterator())
    response = httpx.Response(
        200,
        headers=[(b"Content-Type", b"text/html; charset=shift-jis")],
        stream=stream,
    )

    await response.read()
    assert "".join(response.text) == "トラベル"
Example #9
0
async def test_cannot_aread_after_response_closed():
    is_closed = False

    async def close_func():
        nonlocal is_closed
        is_closed = True

    stream = AsyncIteratorStream(aiterator=async_streaming_body(),
                                 close_func=close_func)
    response = httpx.Response(200, stream=stream, request=REQUEST)

    await response.aclose()
    assert is_closed

    with pytest.raises(httpx.ResponseClosed):
        await response.aread()
Example #10
0
async def test_elapsed_not_available_until_closed():
    stream = AsyncIteratorStream(aiterator=async_streaming_body())
    response = httpx.Response(200, stream=stream, request=REQUEST)

    with pytest.raises(RuntimeError):
        response.elapsed
Example #11
0
    async def send(
        self,
        request: Request,
        verify: VerifyTypes = None,
        cert: CertTypes = None,
        timeout: TimeoutTypes = None,
    ) -> Response:
        if request.url.path == "/no_redirect":
            return Response(codes.OK, request=request)

        elif request.url.path == "/redirect_301":

            async def body():
                yield b"<a href='https://example.org/'>here</a>"

            status_code = codes.MOVED_PERMANENTLY
            headers = {"location": "https://example.org/"}
            stream = AsyncIteratorStream(aiterator=body())
            return Response(status_code,
                            stream=stream,
                            headers=headers,
                            request=request)

        elif request.url.path == "/redirect_302":
            status_code = codes.FOUND
            headers = {"location": "https://example.org/"}
            return Response(status_code, headers=headers, request=request)

        elif request.url.path == "/redirect_303":
            status_code = codes.SEE_OTHER
            headers = {"location": "https://example.org/"}
            return Response(status_code, headers=headers, request=request)

        elif request.url.path == "/relative_redirect":
            headers = {"location": "/"}
            return Response(codes.SEE_OTHER, headers=headers, request=request)

        elif request.url.path == "/malformed_redirect":
            headers = {"location": "https://:443/"}
            return Response(codes.SEE_OTHER, headers=headers, request=request)

        elif request.url.path == "/no_scheme_redirect":
            headers = {"location": "//example.org/"}
            return Response(codes.SEE_OTHER, headers=headers, request=request)

        elif request.url.path == "/multiple_redirects":
            params = parse_qs(request.url.query)
            count = int(params.get("count", "0")[0])
            redirect_count = count - 1
            code = codes.SEE_OTHER if count else codes.OK
            location = "/multiple_redirects"
            if redirect_count:
                location += "?count=" + str(redirect_count)
            headers = {"location": location} if count else {}
            return Response(code, headers=headers, request=request)

        if request.url.path == "/redirect_loop":
            headers = {"location": "/redirect_loop"}
            return Response(codes.SEE_OTHER, headers=headers, request=request)

        elif request.url.path == "/cross_domain":
            headers = {"location": "https://example.org/cross_domain_target"}
            return Response(codes.SEE_OTHER, headers=headers, request=request)

        elif request.url.path == "/cross_domain_target":
            headers = dict(request.headers.items())
            content = json.dumps({"headers": headers}).encode()
            return Response(codes.OK, content=content, request=request)

        elif request.url.path == "/redirect_body":
            body = b"".join([part async for part in request.stream])
            headers = {"location": "/redirect_body_target"}
            return Response(codes.PERMANENT_REDIRECT,
                            headers=headers,
                            request=request)

        elif request.url.path == "/redirect_no_body":
            content = b"".join([part async for part in request.stream])
            headers = {"location": "/redirect_body_target"}
            return Response(codes.SEE_OTHER, headers=headers, request=request)

        elif request.url.path == "/redirect_body_target":
            content = b"".join([part async for part in request.stream])
            headers = dict(request.headers.items())
            body = json.dumps({
                "body": content.decode(),
                "headers": headers
            }).encode()
            return Response(codes.OK, content=body, request=request)

        elif request.url.path == "/cross_subdomain":
            if request.headers["host"] != "www.example.org":
                headers = {
                    "location": "https://www.example.org/cross_subdomain"
                }
                return Response(codes.PERMANENT_REDIRECT,
                                headers=headers,
                                request=request)
            else:
                return Response(codes.OK,
                                content=b"Hello, world!",
                                request=request)

        return Response(codes.OK, content=b"Hello, world!", request=request)