async def test_premature_response_close(server): """ A premature close should close the connection. """ async with httpcore.ConnectionPool() as http: response = await http.request("GET", "http://127.0.0.1:8000/", stream=True) await response.close() assert len(http.active_connections) == 0 assert len(http.keepalive_connections) == 0
async def test_close_connections(server): """ Using a `Connection: close` header should close the connection. """ headers = [(b"connection", b"close")] async with httpcore.ConnectionPool() as http: response = await http.request("GET", "http://127.0.0.1:8000/", headers=headers) assert len(http.active_connections) == 0 assert len(http.keepalive_connections) == 0
async def test_standard_response_close(server): """ A standard close should keep the connection open. """ async with httpcore.ConnectionPool() as http: response = await http.request("GET", "http://127.0.0.1:8000/", stream=True) await response.read() await response.close() assert len(http.active_connections) == 0 assert len(http.keepalive_connections) == 1
async def test_keepalive_connections(server): """ Connections should default to staying in a keep-alive state. """ async with httpcore.ConnectionPool() as http: response = await http.request("GET", "http://127.0.0.1:8000/") assert len(http.active_connections) == 0 assert len(http.keepalive_connections) == 1 response = await http.request("GET", "http://127.0.0.1:8000/") assert len(http.active_connections) == 0 assert len(http.keepalive_connections) == 1
async def test_differing_connection_keys(server): """ Connnections to differing connection keys should result in multiple connections. """ async with httpcore.ConnectionPool() as http: response = await http.request("GET", "http://127.0.0.1:8000/") assert len(http.active_connections) == 0 assert len(http.keepalive_connections) == 1 response = await http.request("GET", "http://localhost:8000/") assert len(http.active_connections) == 0 assert len(http.keepalive_connections) == 2
async def test_streaming_response_holds_connection(server): """ A streaming request should hold the connection open until the response is read. """ async with httpcore.ConnectionPool() as http: response = await http.request("GET", "http://127.0.0.1:8000/", stream=True) assert len(http.active_connections) == 1 assert len(http.keepalive_connections) == 0 await response.read() assert len(http.active_connections) == 0 assert len(http.keepalive_connections) == 1
async def test_soft_limit(server): """ The soft_limit config should limit the maximum number of keep-alive connections. """ pool_limits = httpcore.PoolLimits(soft_limit=1) async with httpcore.ConnectionPool(pool_limits=pool_limits) as http: response = await http.request("GET", "http://127.0.0.1:8000/") assert len(http.active_connections) == 0 assert len(http.keepalive_connections) == 1 response = await http.request("GET", "http://localhost:8000/") assert len(http.active_connections) == 0 assert len(http.keepalive_connections) == 1
async def test_httpcore_request(url, port): async with MockRouter(using="httpcore") as router: router.get(url) % dict(text="foobar") request = httpcore.Request( b"GET", httpcore.URL(scheme=b"https", host=b"foo.bar", port=port, target=b"/"), ) with httpcore.ConnectionPool() as http: response = http.handle_request(request) body = response.read() assert body == b"foobar" async with httpcore.AsyncConnectionPool() as http: response = await http.handle_async_request(request) body = await response.aread() assert body == b"foobar"
def __init__( self, verify: VerifyTypes = True, cert: CertTypes = None, http1: bool = True, http2: bool = False, limits: Limits = DEFAULT_LIMITS, trust_env: bool = True, proxy: Proxy = None, uds: str = None, local_address: str = None, retries: int = 0, ) -> None: ssl_context = create_ssl_context(verify=verify, cert=cert, trust_env=trust_env) if proxy is None: self._pool = httpcore.ConnectionPool( ssl_context=ssl_context, max_connections=limits.max_connections, max_keepalive_connections=limits.max_keepalive_connections, keepalive_expiry=limits.keepalive_expiry, http1=http1, http2=http2, uds=uds, local_address=local_address, retries=retries, ) else: self._pool = httpcore.HTTPProxy( proxy_url=httpcore.URL( scheme=proxy.url.raw_scheme, host=proxy.url.raw_host, port=proxy.url.port, target=proxy.url.raw_path, ), proxy_headers=proxy.headers.raw, ssl_context=ssl_context, max_connections=limits.max_connections, max_keepalive_connections=limits.max_keepalive_connections, keepalive_expiry=limits.keepalive_expiry, )
async def test_multiple_concurrent_connections(server): """ Multiple conncurrent requests should open multiple conncurrent connections. """ async with httpcore.ConnectionPool() as http: response_a = await http.request("GET", "http://127.0.0.1:8000/", stream=True) assert len(http.active_connections) == 1 assert len(http.keepalive_connections) == 0 response_b = await http.request("GET", "http://127.0.0.1:8000/", stream=True) assert len(http.active_connections) == 2 assert len(http.keepalive_connections) == 0 await response_b.read() assert len(http.active_connections) == 1 assert len(http.keepalive_connections) == 1 await response_a.read() assert len(http.active_connections) == 0 assert len(http.keepalive_connections) == 2
def __init__( self, verify: VerifyTypes = True, cert: CertTypes = None, http1: bool = True, http2: bool = False, limits: Limits = DEFAULT_LIMITS, trust_env: bool = True, proxy: Proxy = None, uds: str = None, local_address: str = None, retries: int = 0, ) -> None: ssl_context = create_ssl_context(verify=verify, cert=cert, trust_env=trust_env) if proxy is None: self._pool = httpcore.ConnectionPool( ssl_context=ssl_context, max_connections=limits.max_connections, max_keepalive_connections=limits.max_keepalive_connections, keepalive_expiry=limits.keepalive_expiry, http1=http1, http2=http2, uds=uds, local_address=local_address, retries=retries, ) elif proxy.url.scheme in ("http", "https"): self._pool = httpcore.HTTPProxy( proxy_url=httpcore.URL( scheme=proxy.url.raw_scheme, host=proxy.url.raw_host, port=proxy.url.port, target=proxy.url.raw_path, ), proxy_auth=proxy.raw_auth, proxy_headers=proxy.headers.raw, ssl_context=ssl_context, max_connections=limits.max_connections, max_keepalive_connections=limits.max_keepalive_connections, keepalive_expiry=limits.keepalive_expiry, http1=http1, http2=http2, ) elif proxy.url.scheme == "socks5": try: import socksio # noqa except ImportError: # pragma: nocover raise ImportError( "Using SOCKS proxy, but the 'socksio' package is not installed. " "Make sure to install httpx using `pip install httpx[socks]`." ) from None self._pool = httpcore.SOCKSProxy( proxy_url=httpcore.URL( scheme=proxy.url.raw_scheme, host=proxy.url.raw_host, port=proxy.url.port, target=proxy.url.raw_path, ), proxy_auth=proxy.raw_auth, ssl_context=ssl_context, max_connections=limits.max_connections, max_keepalive_connections=limits.max_keepalive_connections, keepalive_expiry=limits.keepalive_expiry, http1=http1, http2=http2, ) else: # pragma: nocover raise ValueError( f"Proxy protocol must be either 'http', 'https', or 'socks5', but got {proxy.url.scheme!r}." )
def __init__(self): self.pool = httpcore.ConnectionPool()