Fix getting the current host for IPv6 urls (#126889)

pull/126850/head
J. Nick Koston 2024-09-27 04:26:35 -05:00 committed by GitHub
parent 3c0be47d3c
commit 9ec26a9be5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 69 additions and 2 deletions

View File

@ -220,7 +220,15 @@ def _get_request_host() -> str | None:
# partition the host to remove the port # partition the host to remove the port
# because the raw host header can contain the port # because the raw host header can contain the port
host = request.headers.get(hdrs.HOST) host = request.headers.get(hdrs.HOST)
return None if host is None else host.partition(":")[0] if host is None:
return None
# IPv6 addresses are enclosed in brackets
# use same logic as yarl and urllib to extract the host
if "[" in host:
return (host.partition("[")[2]).partition("]")[0]
if ":" in host:
host = host.partition(":")[0]
return host
@bind_hass @bind_hass

View File

@ -587,7 +587,7 @@ async def test_get_url(hass: HomeAssistant) -> None:
assert get_url(hass, allow_internal=False) assert get_url(hass, allow_internal=False)
async def test_get_request_host(hass: HomeAssistant) -> None: async def test_get_request_host_with_port(hass: HomeAssistant) -> None:
"""Test getting the host of the current web request from the request context.""" """Test getting the host of the current web request from the request context."""
with pytest.raises(NoURLAvailableError): with pytest.raises(NoURLAvailableError):
_get_request_host() _get_request_host()
@ -604,6 +604,65 @@ async def test_get_request_host(hass: HomeAssistant) -> None:
assert _get_request_host() == "example.com" assert _get_request_host() == "example.com"
async def test_get_request_host_without_port(hass: HomeAssistant) -> None:
"""Test getting the host of the current web request from the request context."""
with pytest.raises(NoURLAvailableError):
_get_request_host()
with patch("homeassistant.components.http.current_request") as mock_request_context:
mock_request = Mock()
mock_request.headers = CIMultiDictProxy(CIMultiDict({hdrs.HOST: "example.com"}))
mock_request.url = URL("http://example.com/test/request")
mock_request.host = "example.com"
mock_request_context.get = Mock(return_value=mock_request)
assert _get_request_host() == "example.com"
async def test_get_request_ipv6_address(hass: HomeAssistant) -> None:
"""Test getting the ipv6 host of the current web request from the request context."""
with pytest.raises(NoURLAvailableError):
_get_request_host()
with patch("homeassistant.components.http.current_request") as mock_request_context:
mock_request = Mock()
mock_request.headers = CIMultiDictProxy(CIMultiDict({hdrs.HOST: "[::1]:8123"}))
mock_request.url = URL("http://[::1]:8123/test/request")
mock_request.host = "[::1]:8123"
mock_request_context.get = Mock(return_value=mock_request)
assert _get_request_host() == "::1"
async def test_get_request_ipv6_address_without_port(hass: HomeAssistant) -> None:
"""Test getting the ipv6 host of the current web request from the request context."""
with pytest.raises(NoURLAvailableError):
_get_request_host()
with patch("homeassistant.components.http.current_request") as mock_request_context:
mock_request = Mock()
mock_request.headers = CIMultiDictProxy(CIMultiDict({hdrs.HOST: "[::1]"}))
mock_request.url = URL("http://[::1]/test/request")
mock_request.host = "[::1]"
mock_request_context.get = Mock(return_value=mock_request)
assert _get_request_host() == "::1"
async def test_get_request_host_no_host_header(hass: HomeAssistant) -> None:
"""Test getting the host of the current web request from the request context."""
with pytest.raises(NoURLAvailableError):
_get_request_host()
with patch("homeassistant.components.http.current_request") as mock_request_context:
mock_request = Mock()
mock_request.headers = CIMultiDictProxy(CIMultiDict())
mock_request.url = URL("/test/request")
mock_request_context.get = Mock(return_value=mock_request)
assert _get_request_host() is None
@patch("homeassistant.components.hassio.is_hassio", Mock(return_value=True)) @patch("homeassistant.components.hassio.is_hassio", Mock(return_value=True))
@patch( @patch(
"homeassistant.components.hassio.get_host_info", "homeassistant.components.hassio.get_host_info",