mirror of
https://github.com/home-assistant/core.git
synced 2025-07-27 23:27:37 +00:00
Fix WebOS TV image fetch SSL verify failure (#85841)
This commit is contained in:
parent
be899b6ab6
commit
9b5ac5b173
@ -1,14 +1,18 @@
|
|||||||
"""Support for interface with an LG webOS Smart TV."""
|
"""Support for interface with an LG webOS Smart TV."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import asyncio
|
||||||
from collections.abc import Awaitable, Callable, Coroutine
|
from collections.abc import Awaitable, Callable, Coroutine
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
from http import HTTPStatus
|
||||||
import logging
|
import logging
|
||||||
|
from ssl import SSLContext
|
||||||
from typing import Any, TypeVar, cast
|
from typing import Any, TypeVar, cast
|
||||||
|
|
||||||
from aiowebostv import WebOsClient, WebOsTvPairError
|
from aiowebostv import WebOsClient, WebOsTvPairError
|
||||||
|
import async_timeout
|
||||||
from typing_extensions import Concatenate, ParamSpec
|
from typing_extensions import Concatenate, ParamSpec
|
||||||
|
|
||||||
from homeassistant import util
|
from homeassistant import util
|
||||||
@ -28,6 +32,7 @@ from homeassistant.const import (
|
|||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
from homeassistant.helpers.entity import DeviceInfo
|
from homeassistant.helpers.entity import DeviceInfo
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
@ -466,3 +471,25 @@ class LgWebOSMediaPlayerEntity(RestoreEntity, MediaPlayerEntity):
|
|||||||
async def async_command(self, command: str, **kwargs: Any) -> None:
|
async def async_command(self, command: str, **kwargs: Any) -> None:
|
||||||
"""Send a command."""
|
"""Send a command."""
|
||||||
await self._client.request(command, payload=kwargs.get(ATTR_PAYLOAD))
|
await self._client.request(command, payload=kwargs.get(ATTR_PAYLOAD))
|
||||||
|
|
||||||
|
async def _async_fetch_image(self, url: str) -> tuple[bytes | None, str | None]:
|
||||||
|
"""Retrieve an image.
|
||||||
|
|
||||||
|
webOS uses self-signed certificates, thus we need to use an empty
|
||||||
|
SSLContext to bypass validation errors if url starts with https.
|
||||||
|
"""
|
||||||
|
content = None
|
||||||
|
ssl_context = None
|
||||||
|
if url.startswith("https"):
|
||||||
|
ssl_context = SSLContext()
|
||||||
|
|
||||||
|
websession = async_get_clientsession(self.hass)
|
||||||
|
with suppress(asyncio.TimeoutError), async_timeout.timeout(10):
|
||||||
|
response = await websession.get(url, ssl=ssl_context)
|
||||||
|
if response.status == HTTPStatus.OK:
|
||||||
|
content = await response.read()
|
||||||
|
|
||||||
|
if content is None:
|
||||||
|
_LOGGER.warning("Error retrieving proxied image from %s", url)
|
||||||
|
|
||||||
|
return content, None
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"""The tests for the LG webOS media player platform."""
|
"""The tests for the LG webOS media player platform."""
|
||||||
import asyncio
|
import asyncio
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
from http import HTTPStatus
|
||||||
from unittest.mock import Mock
|
from unittest.mock import Mock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
@ -697,3 +698,68 @@ async def test_supported_features_ignore_cache(hass, client):
|
|||||||
attrs = hass.states.get(ENTITY_ID).attributes
|
attrs = hass.states.get(ENTITY_ID).attributes
|
||||||
|
|
||||||
assert attrs[ATTR_SUPPORTED_FEATURES] == supported
|
assert attrs[ATTR_SUPPORTED_FEATURES] == supported
|
||||||
|
|
||||||
|
|
||||||
|
async def test_get_image_http(
|
||||||
|
hass, client, hass_client_no_auth, aioclient_mock, monkeypatch
|
||||||
|
):
|
||||||
|
"""Test get image via http."""
|
||||||
|
url = "http://something/valid_icon"
|
||||||
|
monkeypatch.setitem(client.apps[LIVE_TV_APP_ID], "icon", url)
|
||||||
|
await setup_webostv(hass)
|
||||||
|
await client.mock_state_update()
|
||||||
|
|
||||||
|
attrs = hass.states.get(ENTITY_ID).attributes
|
||||||
|
assert "entity_picture_local" not in attrs
|
||||||
|
|
||||||
|
aioclient_mock.get(url, text="image")
|
||||||
|
client = await hass_client_no_auth()
|
||||||
|
|
||||||
|
resp = await client.get(attrs["entity_picture"])
|
||||||
|
content = await resp.read()
|
||||||
|
|
||||||
|
assert content == b"image"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_get_image_http_error(
|
||||||
|
hass, client, hass_client_no_auth, aioclient_mock, caplog, monkeypatch
|
||||||
|
):
|
||||||
|
"""Test get image via http error."""
|
||||||
|
url = "http://something/icon_error"
|
||||||
|
monkeypatch.setitem(client.apps[LIVE_TV_APP_ID], "icon", url)
|
||||||
|
await setup_webostv(hass)
|
||||||
|
await client.mock_state_update()
|
||||||
|
|
||||||
|
attrs = hass.states.get(ENTITY_ID).attributes
|
||||||
|
assert "entity_picture_local" not in attrs
|
||||||
|
|
||||||
|
aioclient_mock.get(url, exc=asyncio.TimeoutError())
|
||||||
|
client = await hass_client_no_auth()
|
||||||
|
|
||||||
|
resp = await client.get(attrs["entity_picture"])
|
||||||
|
content = await resp.read()
|
||||||
|
|
||||||
|
assert resp.status == HTTPStatus.INTERNAL_SERVER_ERROR
|
||||||
|
assert f"Error retrieving proxied image from {url}" in caplog.text
|
||||||
|
assert content == b""
|
||||||
|
|
||||||
|
|
||||||
|
async def test_get_image_https(
|
||||||
|
hass, client, hass_client_no_auth, aioclient_mock, monkeypatch
|
||||||
|
):
|
||||||
|
"""Test get image via http."""
|
||||||
|
url = "https://something/valid_icon_https"
|
||||||
|
monkeypatch.setitem(client.apps[LIVE_TV_APP_ID], "icon", url)
|
||||||
|
await setup_webostv(hass)
|
||||||
|
await client.mock_state_update()
|
||||||
|
|
||||||
|
attrs = hass.states.get(ENTITY_ID).attributes
|
||||||
|
assert "entity_picture_local" not in attrs
|
||||||
|
|
||||||
|
aioclient_mock.get(url, text="https_image")
|
||||||
|
client = await hass_client_no_auth()
|
||||||
|
|
||||||
|
resp = await client.get(attrs["entity_picture"])
|
||||||
|
content = await resp.read()
|
||||||
|
|
||||||
|
assert content == b"https_image"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user