Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions custom_components/multiscrape/http_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
CONF_TIMEOUT, CONF_USERNAME, CONF_VERIFY_SSL,
HTTP_DIGEST_AUTHENTICATION)
from homeassistant.core import HomeAssistant
from homeassistant.util.ssl import client_context, create_no_verify_ssl_context

from .const import (CONF_FORM_INPUT, CONF_FORM_INPUT_FILTER,
CONF_FORM_RESUBMIT_ERROR, CONF_FORM_SELECT,
Expand Down Expand Up @@ -68,9 +69,13 @@ def __init__(
self._file_manager = file_manager
self._form_authenticator = form_authenticator

# Create dedicated httpx client with its own cookie jar
# Create dedicated httpx client with its own cookie jar.
# Use HA's pre-warmed cached SSL context so CA certs are never loaded
# on the event loop (homeassistant.util.ssl pre-warms the cache at
# import time precisely to avoid blocking I/O here).
ssl_ctx = client_context() if http_config.verify_ssl else create_no_verify_ssl_context()
self._client = httpx.AsyncClient(
verify=http_config.verify_ssl,
verify=ssl_ctx,
timeout=http_config.timeout,
follow_redirects=True,
)
Expand Down
29 changes: 29 additions & 0 deletions tests/test_http_session.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
"""Tests for the unified HttpSession class."""


import ssl
from unittest.mock import patch

import httpx
import pytest
import respx
Expand Down Expand Up @@ -120,6 +123,32 @@ def session_with_file_manager(hass: HomeAssistant, http_config, mock_file_manage
"""


# ============================================================================
# Regression: issue #578 — blocking SSL cert load on event loop
# ============================================================================


@pytest.mark.parametrize("verify_ssl", [True, False])
def test_init_does_not_load_verify_locations(hass: HomeAssistant, verify_ssl):
"""HttpSession must not call ssl.SSLContext.load_verify_locations during init.

Regression guard for issue #578: constructing httpx.AsyncClient(verify=bool)
triggers a synchronous CA-bundle load on the event loop. We avoid this by
passing a pre-built (and pre-warmed) ssl.SSLContext from HA's util.ssl.
"""
with patch.object(
ssl.SSLContext, "load_verify_locations"
) as mock_load:
HttpSession(
config_name="test_ssl",
hass=hass,
http_config=make_http_config(verify_ssl=verify_ssl),
file_manager=None,
)

mock_load.assert_not_called()


# ============================================================================
# Basic Request Tests
# ============================================================================
Expand Down