mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-23 17:16:33 +00:00
Fix proxy handling with failing connection (#760)
* Fix proxy handling with failing connection * fix lint * Fix exception handling * clenaup error handling * Fix type error * Fix event stream * Fix stream handling * Fix * Fix lint * Handle * Update proxy.py * fix lint
This commit is contained in:
parent
000a3c1f7e
commit
5ab5036504
@ -5,14 +5,15 @@ import logging
|
|||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from aiohttp import web
|
from aiohttp import web
|
||||||
from aiohttp.web_exceptions import (
|
from aiohttp.web_exceptions import HTTPBadGateway, HTTPUnauthorized
|
||||||
HTTPBadGateway, HTTPInternalServerError, HTTPUnauthorized)
|
from aiohttp.client_exceptions import ClientConnectorError
|
||||||
from aiohttp.hdrs import CONTENT_TYPE, AUTHORIZATION
|
from aiohttp.hdrs import CONTENT_TYPE, AUTHORIZATION
|
||||||
import async_timeout
|
import async_timeout
|
||||||
|
|
||||||
from ..const import HEADER_HA_ACCESS
|
from ..const import HEADER_HA_ACCESS
|
||||||
from ..coresys import CoreSysAttributes
|
from ..coresys import CoreSysAttributes
|
||||||
from ..exceptions import HomeAssistantAuthError, HomeAssistantAPIError
|
from ..exceptions import (
|
||||||
|
HomeAssistantAuthError, HomeAssistantAPIError, APIError)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -82,19 +83,13 @@ class APIProxy(CoreSysAttributes):
|
|||||||
response.content_type = request.headers.get(CONTENT_TYPE)
|
response.content_type = request.headers.get(CONTENT_TYPE)
|
||||||
try:
|
try:
|
||||||
await response.prepare(request)
|
await response.prepare(request)
|
||||||
while True:
|
async for data in client.content:
|
||||||
data = await client.content.read(10)
|
|
||||||
if not data:
|
|
||||||
break
|
|
||||||
await response.write(data)
|
await response.write(data)
|
||||||
|
|
||||||
except aiohttp.ClientError:
|
except (aiohttp.ClientError, aiohttp.ClientPayloadError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
finally:
|
|
||||||
client.close()
|
|
||||||
_LOGGER.info("Home Assistant EventStream close")
|
_LOGGER.info("Home Assistant EventStream close")
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
async def api(self, request):
|
async def api(self, request):
|
||||||
@ -117,7 +112,7 @@ class APIProxy(CoreSysAttributes):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
client = await self.sys_websession_ssl.ws_connect(
|
client = await self.sys_websession_ssl.ws_connect(
|
||||||
url, heartbeat=60, verify_ssl=False)
|
url, heartbeat=30, verify_ssl=False)
|
||||||
|
|
||||||
# Handle authentication
|
# Handle authentication
|
||||||
data = await client.receive_json()
|
data = await client.receive_json()
|
||||||
@ -129,7 +124,7 @@ class APIProxy(CoreSysAttributes):
|
|||||||
# Invalid protocol
|
# Invalid protocol
|
||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
"Got unexpected response from HA WebSocket: %s", data)
|
"Got unexpected response from HA WebSocket: %s", data)
|
||||||
raise HTTPBadGateway()
|
raise APIError()
|
||||||
|
|
||||||
if self.sys_homeassistant.refresh_token:
|
if self.sys_homeassistant.refresh_token:
|
||||||
await self.sys_homeassistant.ensure_access_token()
|
await self.sys_homeassistant.ensure_access_token()
|
||||||
@ -156,19 +151,19 @@ class APIProxy(CoreSysAttributes):
|
|||||||
|
|
||||||
raise HomeAssistantAuthError()
|
raise HomeAssistantAuthError()
|
||||||
|
|
||||||
except (RuntimeError, ValueError) as err:
|
except (RuntimeError, ValueError, ClientConnectorError) as err:
|
||||||
_LOGGER.error("Client error on WebSocket API %s.", err)
|
_LOGGER.error("Client error on WebSocket API %s.", err)
|
||||||
except HomeAssistantAuthError as err:
|
except HomeAssistantAuthError as err:
|
||||||
_LOGGER.error("Failed authentication to Home Assistant WebSocket")
|
_LOGGER.error("Failed authentication to Home Assistant WebSocket")
|
||||||
|
|
||||||
raise HTTPBadGateway()
|
raise APIError()
|
||||||
|
|
||||||
async def websocket(self, request):
|
async def websocket(self, request):
|
||||||
"""Initialize a WebSocket API connection."""
|
"""Initialize a WebSocket API connection."""
|
||||||
_LOGGER.info("Home Assistant WebSocket API request initialize")
|
_LOGGER.info("Home Assistant WebSocket API request initialize")
|
||||||
|
|
||||||
# init server
|
# init server
|
||||||
server = web.WebSocketResponse(heartbeat=60)
|
server = web.WebSocketResponse(heartbeat=30)
|
||||||
await server.prepare(request)
|
await server.prepare(request)
|
||||||
|
|
||||||
# handle authentication
|
# handle authentication
|
||||||
@ -200,10 +195,13 @@ class APIProxy(CoreSysAttributes):
|
|||||||
})
|
})
|
||||||
except (RuntimeError, ValueError) as err:
|
except (RuntimeError, ValueError) as err:
|
||||||
_LOGGER.error("Can't initialize handshake: %s", err)
|
_LOGGER.error("Can't initialize handshake: %s", err)
|
||||||
raise HTTPInternalServerError() from None
|
return server
|
||||||
|
|
||||||
# init connection to hass
|
# init connection to hass
|
||||||
|
try:
|
||||||
client = await self._websocket_client()
|
client = await self._websocket_client()
|
||||||
|
except APIError:
|
||||||
|
return server
|
||||||
|
|
||||||
_LOGGER.info("Home Assistant WebSocket API request running")
|
_LOGGER.info("Home Assistant WebSocket API request running")
|
||||||
try:
|
try:
|
||||||
@ -238,7 +236,7 @@ class APIProxy(CoreSysAttributes):
|
|||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
except RuntimeError as err:
|
except (RuntimeError, ConnectionError, TypeError) as err:
|
||||||
_LOGGER.info("Home Assistant WebSocket API error: %s", err)
|
_LOGGER.info("Home Assistant WebSocket API error: %s", err)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
@ -248,7 +246,9 @@ class APIProxy(CoreSysAttributes):
|
|||||||
server_read.cancel()
|
server_read.cancel()
|
||||||
|
|
||||||
# close connections
|
# close connections
|
||||||
|
if not client.closed:
|
||||||
await client.close()
|
await client.close()
|
||||||
|
if not server.closed:
|
||||||
await server.close()
|
await server.close()
|
||||||
|
|
||||||
_LOGGER.info("Home Assistant WebSocket API connection is closed")
|
_LOGGER.info("Home Assistant WebSocket API connection is closed")
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
attr==0.3.1
|
attr==0.3.1
|
||||||
async_timeout==3.0.0
|
async_timeout==3.0.1
|
||||||
aiohttp==3.4.0
|
aiohttp==3.4.4
|
||||||
docker==3.5.0
|
docker==3.5.0
|
||||||
colorlog==3.1.2
|
colorlog==3.1.4
|
||||||
voluptuous==0.11.5
|
voluptuous==0.11.5
|
||||||
gitpython==2.1.10
|
gitpython==2.1.10
|
||||||
pytz==2018.4
|
pytz==2018.5
|
||||||
pyudev==0.21.0
|
pyudev==0.21.0
|
||||||
pycryptodome==3.6.6
|
pycryptodome==3.6.6
|
||||||
cpe==1.2.1
|
cpe==1.2.1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user