Fix root path requests (#5815)

* Fix root path requests

Since #5759 we've tried to access the path explicitly. However, this
raises KeyError exception when trying to access the proxied root path
(e.g. http://supervisor/core/api/). Before #5759 get was used, which
lead to no exception, but instead inserted a `None` into the path.

It seems aiohttp doesn't provide a path when the root is accessed. So
simply convert this to no path as well by setting path to an empty
string.

* Add rudimentary pytest for regular proxy requets
This commit is contained in:
Stefan Agner 2025-04-07 11:09:45 +02:00 committed by GitHub
parent dedf5df5ad
commit 59a7e9519d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 37 additions and 3 deletions

View File

@ -154,7 +154,7 @@ class APIIngress(CoreSysAttributes):
# Process requests
addon = self._extract_addon(request)
path = request.match_info["path"]
path = request.match_info.get("path", "")
session_data = self.sys_ingress.get_session_data(session)
try:
# Websocket

View File

@ -117,7 +117,7 @@ class APIProxy(CoreSysAttributes):
raise HTTPBadGateway()
# Normal request
path = request.match_info["path"]
path = request.match_info.get("path", "")
async with self._api_client(request, path) as client:
data = await client.read()
return web.Response(

View File

@ -7,7 +7,7 @@ from collections.abc import Awaitable, Callable, Coroutine, Generator
from json import dumps
import logging
from typing import Any, cast
from unittest.mock import patch
from unittest.mock import AsyncMock, patch
from aiohttp import ClientWebSocketResponse, WSCloseCode
from aiohttp.http_websocket import WSMessage, WSMsgType
@ -17,6 +17,7 @@ import pytest
from supervisor.addons.addon import Addon
from supervisor.api.proxy import APIProxy
from supervisor.const import ATTR_ACCESS_TOKEN
from supervisor.homeassistant.api import HomeAssistantAPI
def id_generator() -> Generator[int]:
@ -220,3 +221,36 @@ async def test_proxy_auth_abort_log(
assert (
"Unexpected message during authentication for WebSocket API" in caplog.text
)
@pytest.mark.parametrize("path", ["", "mock_path"])
async def test_api_proxy_get_request(
api_client: TestClient,
install_addon_example: Addon,
request: pytest.FixtureRequest,
path: str,
):
"""Test the API proxy request using patch for make_request."""
install_addon_example.persist[ATTR_ACCESS_TOKEN] = "abc123"
install_addon_example.data["homeassistant_api"] = True
request.param = "local_example"
with patch.object(HomeAssistantAPI, "make_request") as make_request:
# Mock the response from make_request
mock_response = AsyncMock()
mock_response.status = 200
mock_response.content_type = "application/json"
mock_response.read.return_value = b"mocked response"
make_request.return_value.__aenter__.return_value = mock_response
response = await api_client.get(
f"/core/api/{path}", headers={"Authorization": "Bearer abc123"}
)
assert make_request.call_args[0][0] == "get"
assert make_request.call_args[0][1] == f"api/{path}"
assert response.status == 200
assert await response.text() == "mocked response"
assert response.content_type == "application/json"