def async_aiohttp_proxy_web(hass, request, web_coro, buffer_size=102400, timeout=10): """Stream websession request to aiohttp web response.""" try: with async_timeout.timeout(timeout, loop=hass.loop): req = yield from web_coro except asyncio.CancelledError: # The user cancelled the request return except asyncio.TimeoutError as err: # Timeout trying to start the web request raise HTTPGatewayTimeout() from err except aiohttp.ClientError as err: # Something went wrong with the connection raise HTTPBadGateway() from err try: yield from async_aiohttp_proxy_stream(hass, request, req.content, req.headers.get(CONTENT_TYPE)) finally: req.close()
async def async_aiohttp_proxy_web( hass: HomeAssistantType, request: web.BaseRequest, web_coro: Awaitable[aiohttp.ClientResponse], buffer_size: int = 102400, timeout: int = 10) -> Optional[web.StreamResponse]: """Stream websession request to aiohttp web response.""" try: with async_timeout.timeout(timeout, loop=hass.loop): req = await web_coro except asyncio.CancelledError: # The user cancelled the request return None except asyncio.TimeoutError as err: # Timeout trying to start the web request raise HTTPGatewayTimeout() from err except aiohttp.ClientError as err: # Something went wrong with the connection raise HTTPBadGateway() from err try: return await async_aiohttp_proxy_stream(hass, request, req.content, req.headers.get(CONTENT_TYPE)) finally: req.close()
def handle_async_mjpeg_stream(self, request): """Generate an HTTP MJPEG stream from the camera.""" # aiohttp don't support DigestAuth -> Fallback if self._authentication == HTTP_DIGEST_AUTHENTICATION: yield from super().handle_async_mjpeg_stream(request) return # connect to stream try: with async_timeout.timeout(10, loop=self.hass.loop): stream = yield from self.hass.websession.get(self._mjpeg_url, auth=self._auth) except asyncio.TimeoutError: raise HTTPGatewayTimeout() response = web.StreamResponse() response.content_type = stream.headers.get(CONTENT_TYPE_HEADER) response.enable_chunked_encoding() yield from response.prepare(request) try: while True: data = yield from stream.content.read(102400) if not data: break response.write(data) finally: self.hass.loop.create_task(stream.release()) yield from response.write_eof()
def handle_async_mjpeg_stream(self, request): """Return a MJPEG stream image response directly from the camera.""" streaming_url = SYNO_API_URL.format(self._synology_url, WEBAPI_PATH, self._streaming_path) streaming_payload = { 'api': STREAMING_API, 'method': 'Stream', 'version': '1', 'cameraId': self._camera_id, 'format': 'mjpeg' } try: with async_timeout.timeout(TIMEOUT, loop=self.hass.loop): stream = yield from self.hass.websession.get( streaming_url, payload=streaming_payload, cookies={'id': self._session_id}) except asyncio.TimeoutError: raise HTTPGatewayTimeout() response = web.StreamResponse() response.content_type = stream.headers.get(CONTENT_TYPE_HEADER) yield from response.prepare(request) try: while True: data = yield from stream.content.read(102400) if not data: break response.write(data) finally: self.hass.loop.create_task(stream.release()) yield from response.write_eof()
def handle_async_mjpeg_stream(self, request): """Generate an HTTP MJPEG stream from the camera.""" # aiohttp don't support DigestAuth -> Fallback if self._authentication == HTTP_DIGEST_AUTHENTICATION: yield from super().handle_async_mjpeg_stream(request) return # connect to stream websession = async_get_clientsession(self.hass) stream = None response = None try: with async_timeout.timeout(10, loop=self.hass.loop): stream = yield from websession.get(self._mjpeg_url, auth=self._auth) response = web.StreamResponse() response.content_type = stream.headers.get(CONTENT_TYPE_HEADER) yield from response.prepare(request) while True: data = yield from stream.content.read(102400) if not data: break response.write(data) except asyncio.TimeoutError: raise HTTPGatewayTimeout() finally: if stream is not None: yield from stream.close() if response is not None: yield from response.write_eof()
def async_aiohttp_proxy_stream(hass, request, stream_coro, buffer_size=102400, timeout=10): """Stream websession request to aiohttp web response.""" response = None stream = None try: with async_timeout.timeout(timeout, loop=hass.loop): stream = yield from stream_coro response = web.StreamResponse() response.content_type = stream.headers.get(CONTENT_TYPE) yield from response.prepare(request) while True: data = yield from stream.content.read(buffer_size) if not data: break response.write(data) except asyncio.TimeoutError: raise HTTPGatewayTimeout() except (aiohttp.errors.ClientError, aiohttp.errors.ClientDisconnectedError): pass except (asyncio.CancelledError, ConnectionResetError): response = None finally: if stream is not None: stream.close() if response is not None: yield from response.write_eof()
def handle_async_mjpeg_stream(self, request): """Return a MJPEG stream image response directly from the camera.""" streaming_url = SYNO_API_URL.format(self._synology_url, WEBAPI_PATH, self._streaming_path) streaming_payload = { 'api': STREAMING_API, 'method': 'Stream', 'version': '1', 'cameraId': self._camera_id, 'format': 'mjpeg' } stream = None response = None try: with async_timeout.timeout(TIMEOUT, loop=self.hass.loop): stream = yield from self._websession.get( streaming_url, params=streaming_payload) response = web.StreamResponse() response.content_type = stream.headers.get(CONTENT_TYPE_HEADER) yield from response.prepare(request) while True: data = yield from stream.content.read(102400) if not data: break response.write(data) except (asyncio.TimeoutError, aiohttp.errors.ClientError): _LOGGER.exception("Error on %s", streaming_url) raise HTTPGatewayTimeout() finally: if stream is not None: self.hass.async_add_job(stream.release()) if response is not None: yield from response.write_eof()