diff --git a/homeassistant/components/media_player/browse_media.py b/homeassistant/components/media_player/browse_media.py index 6fe4683c1fc..26494e4c8a7 100644 --- a/homeassistant/components/media_player/browse_media.py +++ b/homeassistant/components/media_player/browse_media.py @@ -15,7 +15,9 @@ from .const import CONTENT_AUTH_EXPIRY_TIME, MEDIA_CLASS_DIRECTORY @callback -def async_process_play_media_url(hass: HomeAssistant, media_content_id: str) -> str: +def async_process_play_media_url( + hass: HomeAssistant, media_content_id: str, *, allow_relative_url: bool = False +) -> str: """Update a media URL with authentication if it points at Home Assistant.""" if media_content_id[0] != "/" and not is_hass_url(hass, media_content_id): return media_content_id @@ -34,8 +36,8 @@ def async_process_play_media_url(hass: HomeAssistant, media_content_id: str) -> ) media_content_id = str(parsed.join(yarl.URL(signed_path))) - # prepend external URL - if media_content_id[0] == "/": + # convert relative URL to absolute URL + if media_content_id[0] == "/" and not allow_relative_url: media_content_id = f"{get_url(hass)}{media_content_id}" return media_content_id diff --git a/homeassistant/components/media_source/__init__.py b/homeassistant/components/media_source/__init__.py index 77b254dcf9d..2bcd80a39ab 100644 --- a/homeassistant/components/media_source/__init__.py +++ b/homeassistant/components/media_source/__init__.py @@ -2,21 +2,20 @@ from __future__ import annotations from collections.abc import Callable -import dataclasses -from datetime import timedelta from typing import Any -from urllib.parse import quote import voluptuous as vol from homeassistant.components import frontend, websocket_api -from homeassistant.components.http.auth import async_sign_path from homeassistant.components.media_player import ( ATTR_MEDIA_CONTENT_ID, CONTENT_AUTH_EXPIRY_TIME, BrowseError, BrowseMedia, ) +from homeassistant.components.media_player.browse_media import ( + async_process_play_media_url, +) from homeassistant.components.websocket_api import ActiveConnection from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.integration_platform import ( @@ -177,13 +176,12 @@ async def websocket_resolve_media( connection.send_error(msg["id"], "resolve_media_failed", str(err)) return - data = dataclasses.asdict(media) - - if data["url"][0] == "/": - data["url"] = async_sign_path( - hass, - quote(data["url"]), - timedelta(seconds=msg["expires"]), - ) - - connection.send_result(msg["id"], data) + connection.send_result( + msg["id"], + { + "url": async_process_play_media_url( + hass, media.url, allow_relative_url=True + ), + "mime_type": media.mime_type, + }, + ) diff --git a/tests/components/media_source/test_init.py b/tests/components/media_source/test_init.py index 319ef295be3..2655000efc9 100644 --- a/tests/components/media_source/test_init.py +++ b/tests/components/media_source/test_init.py @@ -187,7 +187,8 @@ async def test_websocket_resolve_media(hass, hass_ws_client, filename): assert msg["id"] == 1 assert msg["result"]["mime_type"] == media.mime_type - # Validate url is signed. + # Validate url is relative and signed. + assert msg["result"]["url"][0] == "/" parsed = yarl.URL(msg["result"]["url"]) assert parsed.path == getattr(media, "url") assert "authSig" in parsed.query