Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sni hostname extension #696

Merged
merged 10 commits into from
May 23, 2023
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Improve logging with per-module logger names. (#690)
- Resolve race condition during import of `anyio` package. (#692)
- Enable TCP_NODELAY for all synchronous sockets. (#651)
- Add `sni_hostname` request extension. (#696)

## 0.17.1 (May 17th, 2023)

Expand Down
17 changes: 17 additions & 0 deletions docs/extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,23 @@ The following event types are currently exposed...
* `"http2.receive_response_body"`
* `"http2.response_closed"`

### `"sni_hostname"`

The server's hostname, which is used to confirm the hostname supplied by the SSL certificate.

For example:

``` python
headers = {"Host": "www.encode.io"}
extensions = {"sni_hostname": "www.encode.io"}
response = httpcore.request(
"GET",
"https://185.199.108.153",
headers=headers,
extensions=extensions
)
```

## Response Extensions

### `"http_version"`
Expand Down
4 changes: 3 additions & 1 deletion httpcore/_async/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ async def handle_async_request(self, request: Request) -> Response:

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

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

kwargs = {
"ssl_context": ssl_context,
"server_hostname": self._origin.host.decode("ascii"),
"server_hostname": sni_hostname
or self._origin.host.decode("ascii"),
"timeout": timeout,
}
async with Trace("start_tls", logger, request, kwargs) as trace:
Expand Down
4 changes: 3 additions & 1 deletion httpcore/_sync/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ def handle_request(self, request: Request) -> Response:

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

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

kwargs = {
"ssl_context": ssl_context,
"server_hostname": self._origin.host.decode("ascii"),
"server_hostname": sni_hostname
or self._origin.host.decode("ascii"),
"timeout": timeout,
}
with Trace("start_tls", logger, request, kwargs) as trace:
Expand Down