Skip to content

Commit

Permalink
Allow camera stream to fail safely (#50728)
Browse files Browse the repository at this point in the history
  • Loading branch information
dermotduffy authored May 18, 2021
1 parent 1f80def commit 2e10370
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
9 changes: 6 additions & 3 deletions homeassistant/components/camera/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ async def async_get_stream_source(hass: HomeAssistant, entity_id: str) -> str |
@bind_hass
async def async_get_mjpeg_stream(
hass: HomeAssistant, request: web.Request, entity_id: str
) -> web.StreamResponse:
) -> web.StreamResponse | None:
"""Fetch an mjpeg stream from a camera entity."""
camera = _get_camera_from_entity_id(hass, entity_id)

Expand Down Expand Up @@ -399,7 +399,7 @@ async def handle_async_still_stream(

async def handle_async_mjpeg_stream(
self, request: web.Request
) -> web.StreamResponse:
) -> web.StreamResponse | None:
"""Serve an HTTP MJPEG stream from the camera.
This method can be overridden by camera platforms to proxy
Expand Down Expand Up @@ -543,7 +543,10 @@ async def handle(self, request: web.Request, camera: Camera) -> web.StreamRespon
"""Serve camera stream, possibly with interval."""
interval_str = request.query.get("interval")
if interval_str is None:
return await camera.handle_async_mjpeg_stream(request)
stream = await camera.handle_async_mjpeg_stream(request)
if stream is None:
raise web.HTTPBadGateway()
return stream

try:
# Compose camera stream from stills
Expand Down
23 changes: 22 additions & 1 deletion tests/components/camera/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@
from homeassistant.components.camera.prefs import CameraEntityPreferences
from homeassistant.components.websocket_api.const import TYPE_RESULT
from homeassistant.config import async_process_ha_core_config
from homeassistant.const import ATTR_ENTITY_ID, EVENT_HOMEASSISTANT_START
from homeassistant.const import (
ATTR_ENTITY_ID,
EVENT_HOMEASSISTANT_START,
HTTP_BAD_GATEWAY,
HTTP_OK,
)
from homeassistant.exceptions import HomeAssistantError
from homeassistant.setup import async_setup_component

Expand Down Expand Up @@ -354,3 +359,19 @@ async def test_record_service(hass, mock_camera, mock_stream):
# So long as we call stream.record, the rest should be covered
# by those tests.
assert mock_record.called


async def test_camera_proxy_stream(hass, mock_camera, hass_client):
"""Test record service."""

client = await hass_client()

response = await client.get("/api/camera_proxy_stream/camera.demo_camera")
assert response.status == HTTP_OK

with patch(
"homeassistant.components.demo.camera.DemoCamera.handle_async_mjpeg_stream",
return_value=None,
):
response = await client.get("/api/camera_proxy_stream/camera.demo_camera")
assert response.status == HTTP_BAD_GATEWAY

0 comments on commit 2e10370

Please sign in to comment.