From 5f68e0801bd7b09075debcb463cb63e7fc85c8af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cyril=20Nicod=C3=A8me?= Date: Fri, 15 Oct 2021 10:14:56 +0200 Subject: [PATCH 1/4] Replacing assignation by typing for `websocket_handshake` Related to #2272 --- sanic/server/protocols/websocket_protocol.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sanic/server/protocols/websocket_protocol.py b/sanic/server/protocols/websocket_protocol.py index 457f1cd065..95fa833a9a 100644 --- a/sanic/server/protocols/websocket_protocol.py +++ b/sanic/server/protocols/websocket_protocol.py @@ -109,7 +109,7 @@ def close_if_idle(self): return super().close_if_idle() async def websocket_handshake( - self, request, subprotocols=Optional[Sequence[str]] + self, request, subprotocols: Optional[Sequence[str]] = None ): # let the websockets package do the handshake with the client try: From 11cfdcae6f7576a211183a11f8378197333f5d69 Mon Sep 17 00:00:00 2001 From: Adam Hopkins Date: Sun, 17 Oct 2021 11:43:45 +0300 Subject: [PATCH 2/4] Fix some type hinting issues --- sanic/server/protocols/websocket_protocol.py | 24 +++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/sanic/server/protocols/websocket_protocol.py b/sanic/server/protocols/websocket_protocol.py index 95fa833a9a..674ec5a378 100644 --- a/sanic/server/protocols/websocket_protocol.py +++ b/sanic/server/protocols/websocket_protocol.py @@ -1,7 +1,8 @@ -from typing import TYPE_CHECKING, Optional, Sequence +from typing import TYPE_CHECKING, Optional, Sequence, cast from websockets.connection import CLOSED, CLOSING, OPEN from websockets.server import ServerConnection +from websockets.typing import Subprotocol from sanic.exceptions import ServerError from sanic.log import error_logger @@ -15,13 +16,6 @@ class WebSocketProtocol(HttpProtocol): - - websocket: Optional[WebsocketImplProtocol] - websocket_timeout: float - websocket_max_size = Optional[int] - websocket_ping_interval = Optional[float] - websocket_ping_timeout = Optional[float] - def __init__( self, *args, @@ -35,7 +29,7 @@ def __init__( **kwargs, ): super().__init__(*args, **kwargs) - self.websocket = None + self.websocket: Optional[WebsocketImplProtocol] = None self.websocket_timeout = websocket_timeout self.websocket_max_size = websocket_max_size if websocket_max_queue is not None and websocket_max_queue > 0: @@ -116,7 +110,15 @@ async def websocket_handshake( if subprotocols is not None: # subprotocols can be a set or frozenset, # but ServerConnection needs a list - subprotocols = list(subprotocols) + subprotocols = cast( + Optional[Sequence[Subprotocol]], + list( + [ + Subprotocol(subprotocol) + for subprotocol in subprotocols + ] + ), + ) ws_conn = ServerConnection( max_size=self.websocket_max_size, subprotocols=subprotocols, @@ -142,7 +144,7 @@ async def websocket_handshake( ) rbody += "".join(f"{k}: {v}\r\n" for k, v in resp.headers.items()) if resp.body is not None: - rbody += f"\r\n{resp.body}\r\n\r\n" + rbody += f"\r\n{resp.body.decode('utf-8')}\r\n\r\n" else: rbody += "\r\n" await super().send(rbody.encode()) From d35854b25a67b3c072a64be3345efa258e9c45d0 Mon Sep 17 00:00:00 2001 From: Adam Hopkins Date: Tue, 26 Oct 2021 22:57:04 +0300 Subject: [PATCH 3/4] Cleanup websocket handchake response concat --- sanic/server/protocols/websocket_protocol.py | 23 +++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/sanic/server/protocols/websocket_protocol.py b/sanic/server/protocols/websocket_protocol.py index 674ec5a378..4f0708341d 100644 --- a/sanic/server/protocols/websocket_protocol.py +++ b/sanic/server/protocols/websocket_protocol.py @@ -133,21 +133,18 @@ async def websocket_handshake( ) raise ServerError(msg, status_code=500) if 100 <= resp.status_code <= 299: - rbody = "".join( - [ - "HTTP/1.1 ", - str(resp.status_code), - " ", - resp.reason_phrase, - "\r\n", - ] + first_line = ( + f"HTTP/1.1 {resp.status_code} {resp.reason_phrase}\r\n" + ).encode() + rbody = bytearray(first_line) + rbody += b"".join( + [f"{k}: {v}\r\n".encode() for k, v in resp.headers.items()] ) - rbody += "".join(f"{k}: {v}\r\n" for k, v in resp.headers.items()) + rbody += b"\r\n" if resp.body is not None: - rbody += f"\r\n{resp.body.decode('utf-8')}\r\n\r\n" - else: - rbody += "\r\n" - await super().send(rbody.encode()) + rbody += resp.body + rbody += b"\r\n\r\n" + await super().send(rbody) else: raise ServerError(resp.body, resp.status_code) self.websocket = WebsocketImplProtocol( From c716de957c1b109b3dde8bd9687b5b165fb2671d Mon Sep 17 00:00:00 2001 From: Adam Hopkins Date: Wed, 27 Oct 2021 00:08:04 +0300 Subject: [PATCH 4/4] Optimize concat encoding --- sanic/server/protocols/websocket_protocol.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sanic/server/protocols/websocket_protocol.py b/sanic/server/protocols/websocket_protocol.py index 4f0708341d..2321e9492b 100644 --- a/sanic/server/protocols/websocket_protocol.py +++ b/sanic/server/protocols/websocket_protocol.py @@ -137,9 +137,9 @@ async def websocket_handshake( f"HTTP/1.1 {resp.status_code} {resp.reason_phrase}\r\n" ).encode() rbody = bytearray(first_line) - rbody += b"".join( - [f"{k}: {v}\r\n".encode() for k, v in resp.headers.items()] - ) + rbody += ( + "".join(f"{k}: {v}\r\n" for k, v in resp.headers.items()) + ).encode() rbody += b"\r\n" if resp.body is not None: rbody += resp.body