diff --git a/homeassistant/components/hassio/ingress.py b/homeassistant/components/hassio/ingress.py index b0c6e9d1dbe..e58c2d790f2 100644 --- a/homeassistant/components/hassio/ingress.py +++ b/homeassistant/components/hassio/ingress.py @@ -8,7 +8,7 @@ import os import aiohttp from aiohttp import ClientTimeout, hdrs, web -from aiohttp.web_exceptions import HTTPBadGateway +from aiohttp.web_exceptions import HTTPBadGateway, HTTPBadRequest from multidict import CIMultiDict from homeassistant.components.http import HomeAssistantView @@ -185,7 +185,11 @@ def _init_header(request: web.Request, token: str) -> CIMultiDict | dict[str, st # Set X-Forwarded-For forward_for = request.headers.get(hdrs.X_FORWARDED_FOR) - connected_ip = ip_address(request.transport.get_extra_info("peername")[0]) + if (peername := request.transport.get_extra_info("peername")) is None: + _LOGGER.error("Can't set forward_for header, missing peername") + raise HTTPBadRequest() + + connected_ip = ip_address(peername[0]) if forward_for: forward_for = f"{forward_for}, {connected_ip!s}" else: diff --git a/tests/components/hassio/test_ingress.py b/tests/components/hassio/test_ingress.py index e75de8741bf..8f7d97213e0 100644 --- a/tests/components/hassio/test_ingress.py +++ b/tests/components/hassio/test_ingress.py @@ -1,5 +1,7 @@ """The tests for the hassio component.""" +from unittest.mock import MagicMock, patch + from aiohttp.hdrs import X_FORWARDED_FOR, X_FORWARDED_HOST, X_FORWARDED_PROTO import pytest @@ -275,3 +277,29 @@ async def test_ingress_websocket(hassio_client, build_type, aioclient_mock): assert aioclient_mock.mock_calls[-1][3][X_FORWARDED_FOR] assert aioclient_mock.mock_calls[-1][3][X_FORWARDED_HOST] assert aioclient_mock.mock_calls[-1][3][X_FORWARDED_PROTO] + + +async def test_ingress_missing_peername(hassio_client, aioclient_mock, caplog): + """Test hadnling of missing peername.""" + aioclient_mock.get( + "http://127.0.0.1/ingress/lorem/ipsum", + text="test", + ) + + def get_extra_info(_): + return None + + with patch( + "aiohttp.web_request.BaseRequest.transport", + return_value=MagicMock(), + ) as transport_mock: + transport_mock.get_extra_info = get_extra_info + resp = await hassio_client.get( + "/api/hassio_ingress/lorem/ipsum", + headers={"X-Test-Header": "beer"}, + ) + + assert "Can't set forward_for header, missing peername" in caplog.text + + # Check we got right response + assert resp.status == 400