From fc2ca1646abacf3624a04efb320e8e725e200abb Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 9 Mar 2024 18:02:42 -1000 Subject: [PATCH] Fix MJPEG fallback when still image URL is missing with basic auth (#112861) * Fix MJPEG fallback when still image URL is missing with basic auth I picked up an old DCS-930L (circa 2010) camera to test with to fix #94877 * Fix MJPEG fallback when still image URL is missing with basic auth I picked up an old DCS-930L (circa 2010) camera to test with to fix #94877 * Fix MJPEG fallback when still image URL is missing with basic auth I picked up an old DCS-930L (circa 2010) camera to test with to fix #94877 * Fix MJPEG fallback when still image URL is missing with basic auth I picked up an old DCS-930L (circa 2010) camera to test with to fix #94877 --- homeassistant/components/mjpeg/camera.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/homeassistant/components/mjpeg/camera.py b/homeassistant/components/mjpeg/camera.py index d424df620cf..6a5c4e3203b 100644 --- a/homeassistant/components/mjpeg/camera.py +++ b/homeassistant/components/mjpeg/camera.py @@ -134,12 +134,11 @@ class MjpegCamera(Camera): self, width: int | None = None, height: int | None = None ) -> bytes | None: """Return a still image response from the camera.""" - # DigestAuth is not supported if ( self._authentication == HTTP_DIGEST_AUTHENTICATION or self._still_image_url is None ): - return await self._async_digest_camera_image() + return await self._async_digest_or_fallback_camera_image() websession = async_get_clientsession(self.hass, verify_ssl=self._verify_ssl) try: @@ -157,15 +156,17 @@ class MjpegCamera(Camera): return None - def _get_digest_auth(self) -> httpx.DigestAuth: - """Return a DigestAuth object.""" + def _get_httpx_auth(self) -> httpx.Auth: + """Return a httpx auth object.""" username = "" if self._username is None else self._username - return httpx.DigestAuth(username, self._password) + digest_auth = self._authentication == HTTP_DIGEST_AUTHENTICATION + cls = httpx.DigestAuth if digest_auth else httpx.BasicAuth + return cls(username, self._password) - async def _async_digest_camera_image(self) -> bytes | None: + async def _async_digest_or_fallback_camera_image(self) -> bytes | None: """Return a still image response from the camera using digest authentication.""" client = get_async_client(self.hass, verify_ssl=self._verify_ssl) - auth = self._get_digest_auth() + auth = self._get_httpx_auth() try: if self._still_image_url: # Fallback to MJPEG stream if still image URL is not available @@ -196,7 +197,7 @@ class MjpegCamera(Camera): ) -> web.StreamResponse | None: """Generate an HTTP MJPEG stream from the camera using digest authentication.""" async with get_async_client(self.hass, verify_ssl=self._verify_ssl).stream( - "get", self._mjpeg_url, auth=self._get_digest_auth(), timeout=TIMEOUT + "get", self._mjpeg_url, auth=self._get_httpx_auth(), timeout=TIMEOUT ) as stream: response = web.StreamResponse(headers=stream.headers) await response.prepare(request)