mirror of
https://github.com/home-assistant/core.git
synced 2025-07-10 06:47:09 +00:00
Improve content type handling in ImageEntity (#95365)
This commit is contained in:
parent
116dd67472
commit
190d67b56c
@ -62,9 +62,9 @@ class ImageContentTypeError(HomeAssistantError):
|
|||||||
"""Error with the content type while loading an image."""
|
"""Error with the content type while loading an image."""
|
||||||
|
|
||||||
|
|
||||||
def valid_image_content_type(content_type: str) -> str:
|
def valid_image_content_type(content_type: str | None) -> str:
|
||||||
"""Validate the assigned content type is one of an image."""
|
"""Validate the assigned content type is one of an image."""
|
||||||
if content_type.split("/", 1)[0] != "image":
|
if content_type is None or content_type.split("/", 1)[0] != "image":
|
||||||
raise ImageContentTypeError
|
raise ImageContentTypeError
|
||||||
return content_type
|
return content_type
|
||||||
|
|
||||||
@ -174,9 +174,10 @@ class ImageEntity(Entity):
|
|||||||
url, timeout=GET_IMAGE_TIMEOUT, follow_redirects=True
|
url, timeout=GET_IMAGE_TIMEOUT, follow_redirects=True
|
||||||
)
|
)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
|
content_type = response.headers.get("content-type")
|
||||||
return Image(
|
return Image(
|
||||||
content=response.content,
|
content=response.content,
|
||||||
content_type=response.headers["content-type"],
|
content_type=valid_image_content_type(content_type),
|
||||||
)
|
)
|
||||||
except httpx.TimeoutException:
|
except httpx.TimeoutException:
|
||||||
_LOGGER.error("%s: Timeout getting image from %s", self.entity_id, url)
|
_LOGGER.error("%s: Timeout getting image from %s", self.entity_id, url)
|
||||||
@ -189,6 +190,14 @@ class ImageEntity(Entity):
|
|||||||
err,
|
err,
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
|
except ImageContentTypeError:
|
||||||
|
_LOGGER.error(
|
||||||
|
"%s: Image from %s has invalid content type: %s",
|
||||||
|
self.entity_id,
|
||||||
|
url,
|
||||||
|
content_type,
|
||||||
|
)
|
||||||
|
return None
|
||||||
|
|
||||||
async def async_image(self) -> bytes | None:
|
async def async_image(self) -> bytes | None:
|
||||||
"""Return bytes of image."""
|
"""Return bytes of image."""
|
||||||
|
@ -256,3 +256,34 @@ async def test_fetch_image_url_exception(
|
|||||||
|
|
||||||
resp = await client.get("/api/image_proxy/image.test")
|
resp = await client.get("/api/image_proxy/image.test")
|
||||||
assert resp.status == HTTPStatus.INTERNAL_SERVER_ERROR
|
assert resp.status == HTTPStatus.INTERNAL_SERVER_ERROR
|
||||||
|
|
||||||
|
|
||||||
|
@respx.mock
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"content_type",
|
||||||
|
[
|
||||||
|
None,
|
||||||
|
"text/plain",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_fetch_image_url_wrong_content_type(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
hass_client: ClientSessionGenerator,
|
||||||
|
content_type: str | None,
|
||||||
|
) -> None:
|
||||||
|
"""Test fetching an image with an authenticated client."""
|
||||||
|
respx.get("https://example.com/myimage.jpg").respond(
|
||||||
|
status_code=HTTPStatus.OK, content_type=content_type, content=b"Test"
|
||||||
|
)
|
||||||
|
|
||||||
|
mock_integration(hass, MockModule(domain="test"))
|
||||||
|
mock_platform(hass, "test.image", MockImagePlatform([MockURLImageEntity(hass)]))
|
||||||
|
assert await async_setup_component(
|
||||||
|
hass, image.DOMAIN, {"image": {"platform": "test"}}
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
client = await hass_client()
|
||||||
|
|
||||||
|
resp = await client.get("/api/image_proxy/image.test")
|
||||||
|
assert resp.status == HTTPStatus.INTERNAL_SERVER_ERROR
|
||||||
|
Loading…
x
Reference in New Issue
Block a user