Reolink fix playback headers (#141015)

This commit is contained in:
starkillerOG 2025-03-20 20:45:07 +01:00 committed by Franck Nijhof
parent 5681f4f2ea
commit 121ee27105
No known key found for this signature in database
GPG Key ID: D62583BA8AB11CA3
2 changed files with 34 additions and 10 deletions

View File

@ -83,7 +83,16 @@ class PlaybackProxyView(HomeAssistantView):
_LOGGER.warning("Reolink playback proxy error: %s", str(err))
return web.Response(body=str(err), status=HTTPStatus.BAD_REQUEST)
headers = dict(request.headers)
headers.pop("Host", None)
headers.pop("Referer", None)
if _LOGGER.isEnabledFor(logging.DEBUG):
_LOGGER.debug(
"Requested Playback Proxy Method %s, Headers: %s",
request.method,
headers,
)
_LOGGER.debug(
"Opening VOD stream from %s: %s",
host.api.camera_name(ch),
@ -93,6 +102,7 @@ class PlaybackProxyView(HomeAssistantView):
try:
reolink_response = await self.session.get(
reolink_url,
headers=headers,
timeout=ClientTimeout(
connect=15, sock_connect=15, sock_read=5, total=None
),
@ -118,18 +128,25 @@ class PlaybackProxyView(HomeAssistantView):
]:
err_str = f"Reolink playback expected video/mp4 but got {reolink_response.content_type}"
_LOGGER.error(err_str)
if reolink_response.content_type == "text/html":
text = await reolink_response.text()
_LOGGER.debug(text)
return web.Response(body=err_str, status=HTTPStatus.BAD_REQUEST)
response = web.StreamResponse(
status=200,
reason="OK",
headers={
"Content-Type": "video/mp4",
},
response_headers = dict(reolink_response.headers)
_LOGGER.debug(
"Response Playback Proxy Status %s:%s, Headers: %s",
reolink_response.status,
reolink_response.reason,
response_headers,
)
response_headers["Content-Type"] = "video/mp4"
if reolink_response.content_length is not None:
response.content_length = reolink_response.content_length
response = web.StreamResponse(
status=reolink_response.status,
reason=reolink_response.reason,
headers=response_headers,
)
await response.prepare(request)
@ -141,7 +158,8 @@ class PlaybackProxyView(HomeAssistantView):
"Timeout while reading Reolink playback from %s, writing EOF",
host.api.nvr_name,
)
finally:
reolink_response.release()
reolink_response.release()
await response.write_eof()
return response

View File

@ -46,8 +46,12 @@ def get_mock_session(
mock_response = Mock()
mock_response.content_length = content_length
mock_response.headers = {}
mock_response.status = 200
mock_response.reason = "OK"
mock_response.content_type = content_type
mock_response.content.iter_chunked = Mock(return_value=content)
mock_response.text = AsyncMock(return_value="test")
mock_session = Mock()
mock_session.get = AsyncMock(return_value=mock_response)
@ -178,16 +182,18 @@ async def test_playback_proxy_timeout(
assert response.status == 200
@pytest.mark.parametrize(("content_type"), [("video/x-flv"), ("text/html")])
async def test_playback_wrong_content(
hass: HomeAssistant,
reolink_connect: MagicMock,
config_entry: MockConfigEntry,
hass_client: ClientSessionGenerator,
content_type: str,
) -> None:
"""Test playback proxy URL with a wrong content type in the response."""
reolink_connect.get_vod_source.return_value = (TEST_MIME_TYPE_MP4, TEST_URL)
mock_session = get_mock_session(content_type="video/x-flv")
mock_session = get_mock_session(content_type=content_type)
with patch(
"homeassistant.components.reolink.views.async_get_clientsession",