Skip to content

Commit 30996bf

Browse files
committed
Default ssl contexts per http versions.
1 parent 2763690 commit 30996bf

File tree

3 files changed

+22
-4
lines changed

3 files changed

+22
-4
lines changed

httpx/_config.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class UnsetType:
4646

4747

4848
class SSLContext(ssl.SSLContext):
49+
_default_contexts: dict[tuple[bool, bool], "SSLContext"] = {}
4950
DEFAULT_CA_BUNDLE_PATH = Path(certifi.where())
5051

5152
def __init__(
@@ -128,6 +129,24 @@ def _load_client_certs(self, cert: typing.Optional[CertTypes] = None) -> None:
128129
password=cert[2],
129130
)
130131

132+
@classmethod
133+
def from_defaults(cls, http1: bool = True, http2: bool = False) -> "SSLContext":
134+
context = cls._default_contexts.get((http1, http2))
135+
if context is not None:
136+
return context
137+
138+
context = SSLContext()
139+
if ssl.HAS_ALPN:
140+
alpn_idents = []
141+
if http1:
142+
alpn_idents.append("http/1.1")
143+
if http2:
144+
alpn_idents.append("h2")
145+
context.set_alpn_protocols(alpn_idents)
146+
147+
cls._default_contexts[(http1, http2)] = context
148+
return context
149+
131150
def __repr__(self) -> str:
132151
class_name = self.__class__.__name__
133152

httpx/_transports/default.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ def __init__(
137137
socket_options: typing.Iterable[SOCKET_OPTION] | None = None,
138138
) -> None:
139139
proxy = Proxy(url=proxy) if isinstance(proxy, (str, URL)) else proxy
140-
ssl_context = ssl_context or SSLContext()
140+
ssl_context = ssl_context or SSLContext.from_defaults(http1=http1, http2=http2)
141141

142142
if proxy is None:
143143
self._pool = httpcore.ConnectionPool(
@@ -276,7 +276,7 @@ def __init__(
276276
socket_options: typing.Iterable[SOCKET_OPTION] | None = None,
277277
) -> None:
278278
proxy = Proxy(url=proxy) if isinstance(proxy, (str, URL)) else proxy
279-
ssl_context = ssl_context or SSLContext()
279+
ssl_context = ssl_context or SSLContext.from_defaults(http1=http1, http2=http2)
280280

281281
if proxy is None:
282282
self._pool = httpcore.AsyncConnectionPool(

tests/test_utils.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,7 @@ def test_logging_redirect_chain(server, caplog):
121121

122122
def test_logging_ssl(caplog):
123123
caplog.set_level(logging.DEBUG)
124-
with httpx.Client():
125-
pass
124+
_context = httpx.SSLContext()
126125

127126
cafile = certifi.where()
128127
assert caplog.record_tuples == [

0 commit comments

Comments
 (0)