Improve content type handling in ImageEntity (#95365)

This commit is contained in:
Erik Montnemery 2023-06-27 15:28:49 +02:00 committed by GitHub
parent 116dd67472
commit 190d67b56c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 3 deletions

View File

@ -62,9 +62,9 @@ class ImageContentTypeError(HomeAssistantError):
"""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."""
if content_type.split("/", 1)[0] != "image":
if content_type is None or content_type.split("/", 1)[0] != "image":
raise ImageContentTypeError
return content_type
@ -174,9 +174,10 @@ class ImageEntity(Entity):
url, timeout=GET_IMAGE_TIMEOUT, follow_redirects=True
)
response.raise_for_status()
content_type = response.headers.get("content-type")
return Image(
content=response.content,
content_type=response.headers["content-type"],
content_type=valid_image_content_type(content_type),
)
except httpx.TimeoutException:
_LOGGER.error("%s: Timeout getting image from %s", self.entity_id, url)
@ -189,6 +190,14 @@ class ImageEntity(Entity):
err,
)
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:
"""Return bytes of image."""

View File

@ -256,3 +256,34 @@ async def test_fetch_image_url_exception(
resp = await client.get("/api/image_proxy/image.test")
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