Skip to content

Commit 27a10dd

Browse files
Add sni hostname extension (#696)
* Add `sni_hostname` extension * Fix linting * Add 'sni_hostname' to `CHANGELOG.md` and `extensions.md` * Typo * Update CHANGELOG.md * Update docs/extensions.md * Fix changelog --------- Co-authored-by: Tom Christie <tom@tomchristie.com>
1 parent 834000d commit 27a10dd

File tree

4 files changed

+24
-2
lines changed

4 files changed

+24
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
99
- Improve logging with per-module logger names. (#690)
1010
- Resolve race condition during import of `anyio` package. (#692)
1111
- Enable TCP_NODELAY for all synchronous sockets. (#651)
12+
- Add `sni_hostname` request extension. (#696)
1213

1314
## 0.17.1 (May 17th, 2023)
1415

docs/extensions.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,23 @@ The following event types are currently exposed...
147147
* `"http2.receive_response_body"`
148148
* `"http2.response_closed"`
149149

150+
### `"sni_hostname"`
151+
152+
The server's hostname, which is used to confirm the hostname supplied by the SSL certificate.
153+
154+
For example:
155+
156+
``` python
157+
headers = {"Host": "www.encode.io"}
158+
extensions = {"sni_hostname": "www.encode.io"}
159+
response = httpcore.request(
160+
"GET",
161+
"https://185.199.108.153",
162+
headers=headers,
163+
extensions=extensions
164+
)
165+
```
166+
150167
## Response Extensions
151168

152169
### `"http_version"`

httpcore/_async/connection.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ async def handle_async_request(self, request: Request) -> Response:
9595

9696
async def _connect(self, request: Request) -> AsyncNetworkStream:
9797
timeouts = request.extensions.get("timeout", {})
98+
sni_hostname = request.extensions.get("sni_hostname", None)
9899
timeout = timeouts.get("connect", None)
99100

100101
retries_left = self._retries
@@ -136,7 +137,8 @@ async def _connect(self, request: Request) -> AsyncNetworkStream:
136137

137138
kwargs = {
138139
"ssl_context": ssl_context,
139-
"server_hostname": self._origin.host.decode("ascii"),
140+
"server_hostname": sni_hostname
141+
or self._origin.host.decode("ascii"),
140142
"timeout": timeout,
141143
}
142144
async with Trace("start_tls", logger, request, kwargs) as trace:

httpcore/_sync/connection.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ def handle_request(self, request: Request) -> Response:
9595

9696
def _connect(self, request: Request) -> NetworkStream:
9797
timeouts = request.extensions.get("timeout", {})
98+
sni_hostname = request.extensions.get("sni_hostname", None)
9899
timeout = timeouts.get("connect", None)
99100

100101
retries_left = self._retries
@@ -136,7 +137,8 @@ def _connect(self, request: Request) -> NetworkStream:
136137

137138
kwargs = {
138139
"ssl_context": ssl_context,
139-
"server_hostname": self._origin.host.decode("ascii"),
140+
"server_hostname": sni_hostname
141+
or self._origin.host.decode("ascii"),
140142
"timeout": timeout,
141143
}
142144
with Trace("start_tls", logger, request, kwargs) as trace:

0 commit comments

Comments
 (0)