async def test_start_tls_on_socket_stream(https_server): """ See that the backend can make a connection without TLS then start TLS on an existing connection. """ backend = AsyncioBackend() ctx = SSLConfig().load_ssl_context_no_verify(HTTPVersionConfig()) timeout = TimeoutConfig(5) stream = await backend.open_tcp_stream( https_server.url.host, https_server.url.port, None, timeout ) try: assert stream.is_connection_dropped() is False assert stream.stream_writer.get_extra_info("cipher", default=None) is None stream = await backend.start_tls(stream, https_server.url.host, ctx, timeout) assert stream.is_connection_dropped() is False assert stream.stream_writer.get_extra_info("cipher", default=None) is not None await stream.write(b"GET / HTTP/1.1\r\n\r\n") assert (await stream.read(8192, timeout)).startswith(b"HTTP/1.1 200 OK\r\n") finally: await stream.close()
async def test_start_tls_on_socket_stream(https_server, backend, get_cipher): """ See that the concurrency backend can make a connection without TLS then start TLS on an existing connection. """ if isinstance(backend, AsyncioBackend) and sys.version_info < (3, 7): pytest.xfail( reason="Requires Python 3.7+ for AbstractEventLoop.start_tls()") ctx = SSLConfig().load_ssl_context_no_verify(HTTPVersionConfig()) timeout = TimeoutConfig(5) stream = await backend.open_tcp_stream(https_server.url.host, https_server.url.port, None, timeout) try: assert stream.is_connection_dropped() is False assert get_cipher(stream) is None stream = await stream.start_tls(https_server.url.host, ctx, timeout) assert stream.is_connection_dropped() is False assert get_cipher(stream) is not None await stream.write(b"GET / HTTP/1.1\r\n\r\n") assert (await stream.read(8192, timeout)).startswith(b"HTTP/1.1 200 OK\r\n") finally: await stream.close()
async def test_connect_timeout(server, backend): timeout = TimeoutConfig(connect_timeout=1e-6) async with Client(timeout=timeout, backend=backend) as client: with pytest.raises(ConnectTimeout): # See https://stackoverflow.com/questions/100841/ await client.get("http://10.255.255.1/")
async def test_write_timeout(server): timeout = TimeoutConfig(write_timeout=0.000001) async with AsyncClient(timeout=timeout) as client: with pytest.raises(WriteTimeout): data = b"*" * 1024 * 1024 * 100 await client.put("http://127.0.0.1:8000/slow_response", data=data)
async def test_start_tls_on_uds_socket_stream(https_uds_server, backend, get_cipher): ctx = SSLConfig().load_ssl_context_no_verify() timeout = TimeoutConfig(5) stream = await backend.open_uds_stream(https_uds_server.config.uds, https_uds_server.url.host, None, timeout) try: assert stream.is_connection_dropped() is False assert get_cipher(stream) is None stream = await stream.start_tls(https_uds_server.url.host, ctx, timeout) assert stream.is_connection_dropped() is False assert get_cipher(stream) is not None await stream.write(b"GET / HTTP/1.1\r\n\r\n") response = await read_response(stream, timeout, should_contain=b"Hello, world") assert response.startswith(b"HTTP/1.1 200 OK\r\n") finally: await stream.close()
async def test_write_timeout(server, backend): timeout = TimeoutConfig(write_timeout=1e-6) async with Client(timeout=timeout, backend=backend) as client: with pytest.raises(WriteTimeout): data = b"*" * 1024 * 1024 * 100 await client.put(server.url.copy_with(path="/slow_response"), data=data)
async def test_pool_timeout(server, backend): pool_limits = PoolLimits(hard_limit=1) timeout = TimeoutConfig(pool_timeout=1e-4) async with Client(pool_limits=pool_limits, timeout=timeout, backend=backend) as client: response = await client.get(server.url, stream=True) with pytest.raises(PoolTimeout): await client.get("http://localhost:8000/") await response.read()
async def test_concurrent_read(server, backend): """ Regression test for: https://github.com/encode/httpx/issues/527 """ stream = await backend.open_tcp_stream(server.url.host, server.url.port, ssl_context=None, timeout=TimeoutConfig(5)) try: await stream.write(b"GET / HTTP/1.1\r\n\r\n") await run_concurrently(backend, lambda: stream.read(10), lambda: stream.read(10)) finally: await stream.close()
async def test_start_tls_on_socket_stream(https_server, https_uds_server, backend, get_cipher, use_uds): """ See that the concurrency backend can make a connection without TLS then start TLS on an existing connection. """ ctx = SSLConfig().load_ssl_context_no_verify(HTTPVersionConfig()) timeout = TimeoutConfig(5) if use_uds: assert https_uds_server.config.uds is not None stream = await backend.open_uds_stream(https_uds_server.config.uds, https_uds_server.url.host, None, timeout) else: stream = await backend.open_tcp_stream(https_server.url.host, https_server.url.port, None, timeout) try: assert stream.is_connection_dropped() is False assert get_cipher(stream) is None stream = await stream.start_tls(https_server.url.host, ctx, timeout) assert stream.is_connection_dropped() is False assert get_cipher(stream) is not None await stream.write(b"GET / HTTP/1.1\r\n\r\n") # stream.read() only gives us *up to* as much data as we ask for. In order to # cleanly close the stream, we must read until the end of the HTTP response. read = b"" ended = False for _ in range(5): # Try read some (not too large) number of times... read += await stream.read(8192, timeout) # We know we're at the end of the response when we've received the body plus # the terminating CRLFs. if b"Hello, world!" in read and read.endswith(b"\r\n\r\n"): ended = True break assert ended assert read.startswith(b"HTTP/1.1 200 OK\r\n") finally: await stream.close()
async def test_read_timeout(server, backend): timeout = TimeoutConfig(read_timeout=1e-6) async with Client(timeout=timeout, backend=backend) as client: with pytest.raises(ReadTimeout): await client.get(server.url.copy_with(path="/slow_response"))
async def test_read_timeout(server): timeout = TimeoutConfig(read_timeout=0.000001) async with AsyncClient(timeout=timeout) as client: with pytest.raises(ReadTimeout): await client.get("http://127.0.0.1:8000/slow_response")