From 37f3eccb1e7cef8316490c00df87d94c1edc3346 Mon Sep 17 00:00:00 2001
From: Pascal Vizeli <pascal.vizeli@syshack.ch>
Date: Wed, 10 Apr 2019 05:13:39 +0200
Subject: [PATCH] Bugfix: pass protocol out of header to application layer
 (#22955)

---
 homeassistant/components/hassio/ingress.py | 41 +++++++++++++++-------
 1 file changed, 28 insertions(+), 13 deletions(-)

diff --git a/homeassistant/components/hassio/ingress.py b/homeassistant/components/hassio/ingress.py
index 4f7c99618c1..f4cc97c3853 100644
--- a/homeassistant/components/hassio/ingress.py
+++ b/homeassistant/components/hassio/ingress.py
@@ -70,7 +70,18 @@ class HassIOIngress(HomeAssistantView):
             self, request: web.Request, token: str, path: str
     ) -> web.WebSocketResponse:
         """Ingress route for websocket."""
-        ws_server = web.WebSocketResponse()
+        if hdrs.SEC_WEBSOCKET_PROTOCOL in request.headers:
+            req_protocols = [
+                str(proto.strip())
+                for proto in
+                request.headers[hdrs.SEC_WEBSOCKET_PROTOCOL].split(",")
+            ]
+        else:
+            req_protocols = ()
+
+        ws_server = web.WebSocketResponse(
+            protocols=req_protocols, autoclose=False, autoping=False
+        )
         await ws_server.prepare(request)
 
         # Preparing
@@ -83,7 +94,8 @@ class HassIOIngress(HomeAssistantView):
 
         # Start proxy
         async with self._websession.ws_connect(
-                url, headers=source_header
+                url, headers=source_header, protocols=req_protocols,
+                autoclose=False, autoping=False,
         ) as ws_client:
             # Proxy requests
             await asyncio.wait(
@@ -205,14 +217,17 @@ def _is_websocket(request: web.Request) -> bool:
 
 async def _websocket_forward(ws_from, ws_to):
     """Handle websocket message directly."""
-    async for msg in ws_from:
-        if msg.type == aiohttp.WSMsgType.TEXT:
-            await ws_to.send_str(msg.data)
-        elif msg.type == aiohttp.WSMsgType.BINARY:
-            await ws_to.send_bytes(msg.data)
-        elif msg.type == aiohttp.WSMsgType.PING:
-            await ws_to.ping()
-        elif msg.type == aiohttp.WSMsgType.PONG:
-            await ws_to.pong()
-        elif ws_to.closed:
-            await ws_to.close(code=ws_to.close_code, message=msg.extra)
+    try:
+        async for msg in ws_from:
+            if msg.type == aiohttp.WSMsgType.TEXT:
+                await ws_to.send_str(msg.data)
+            elif msg.type == aiohttp.WSMsgType.BINARY:
+                await ws_to.send_bytes(msg.data)
+            elif msg.type == aiohttp.WSMsgType.PING:
+                await ws_to.ping()
+            elif msg.type == aiohttp.WSMsgType.PONG:
+                await ws_to.pong()
+            elif ws_to.closed:
+                await ws_to.close(code=ws_to.close_code, message=msg.extra)
+    except RuntimeError:
+        _LOGGER.debug("Ingress Websocket runtime error")
-- 
GitLab