diff --git a/src/httpx2/httpx2/_config.py b/src/httpx2/httpx2/_config.py index 46a6e6ec..6228f8c3 100644 --- a/src/httpx2/httpx2/_config.py +++ b/src/httpx2/httpx2/_config.py @@ -55,16 +55,24 @@ def create_ssl_context( else: ctx = verify - if cert: # pragma: nocover + if cert is not None: # pragma: nocover + cert_chain: tuple[str, ...] + if isinstance(cert, str): + cert_chain = (cert,) + elif isinstance(cert, tuple) and len(cert) in (2, 3): + cert_chain = cert + else: + raise TypeError( + "cert must be a path to a certificate file or a tuple of " + "(certfile, keyfile) or (certfile, keyfile, password)" + ) + message = ( "`cert=...` is deprecated. Use `verify=` instead," "with `.load_cert_chain()` to configure the certificate chain." ) warnings.warn(message, DeprecationWarning) - if isinstance(cert, str): - ctx.load_cert_chain(cert) - else: - ctx.load_cert_chain(*cert) + ctx.load_cert_chain(*cert_chain) return ctx diff --git a/tests/httpx2/test_config.py b/tests/httpx2/test_config.py index ef47844e..2bfaa558 100644 --- a/tests/httpx2/test_config.py +++ b/tests/httpx2/test_config.py @@ -77,6 +77,14 @@ def test_load_ssl_config_cert_without_key_raises(cert_pem_file: str) -> None: context.load_cert_chain(cert_pem_file) +@pytest.mark.parametrize( + "cert", [Path("/path/to/cert.pem"), (), ("cert.pem",), ("cert.pem", "key.pem", "password", "extra")] +) +def test_load_ssl_config_invalid_cert_type_raises(cert: object) -> None: + with pytest.raises(TypeError, match="cert must be a path to a certificate file"): + httpx2.create_ssl_context(cert=cert) # type: ignore[arg-type] + + def test_load_ssl_config_no_verify() -> None: context = httpx2.create_ssl_context(verify=False) assert context.verify_mode == ssl.VerifyMode.CERT_NONE