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()
Exemple #2
0
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()
Exemple #3
0
    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()
Exemple #4
0
    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()
Exemple #5
0
    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()
Exemple #7
0
    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()