prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  ASGI websocket must pass thru bytes as is
  
  
  _Originally posted by @Tronic in https://github.com/sanic-org/sanic/pull/2640#discussion_r1058027028_
        
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `sanic/server/websockets/connection.py`
  Content:
  ```
  1 from typing import (
  2     Any,
  3     Awaitable,
  4     Callable,
  5     Dict,
  6     List,
  7     MutableMapping,
  8     Optional,
  9     Union,
  10 )
  11 
  12 from sanic.exceptions import InvalidUsage
  13 
  14 
  15 ASGIMessage = MutableMapping[str, Any]
  16 
  17 
  18 class WebSocketConnection:
  19     """
  20     This is for ASGI Connections.
  21     It provides an interface similar to WebsocketProtocol, but
  22     sends/receives over an ASGI connection.
  23     """
  24 
  25     # TODO
  26     # - Implement ping/pong
  27 
  28     def __init__(
  29         self,
  30         send: Callable[[ASGIMessage], Awaitable[None]],
  31         receive: Callable[[], Awaitable[ASGIMessage]],
  32         subprotocols: Optional[List[str]] = None,
  33     ) -> None:
  34         self._send = send
  35         self._receive = receive
  36         self._subprotocols = subprotocols or []
  37 
  38     async def send(self, data: Union[str, bytes], *args, **kwargs) -> None:
  39         message: Dict[str, Union[str, bytes]] = {"type": "websocket.send"}
  40 
  41         if isinstance(data, bytes):
  42             message.update({"bytes": data})
  43         else:
  44             message.update({"text": str(data)})
  45 
  46         await self._send(message)
  47 
  48     async def recv(self, *args, **kwargs) -> Optional[str]:
  49         message = await self._receive()
  50 
  51         if message["type"] == "websocket.receive":
  52             try:
  53                 return message["text"]
  54             except KeyError:
  55                 try:
  56                     return message["bytes"].decode()
  57                 except KeyError:
  58                     raise InvalidUsage("Bad ASGI message received")
  59         elif message["type"] == "websocket.disconnect":
  60             pass
  61 
  62         return None
  63 
  64     receive = recv
  65 
  66     async def accept(self, subprotocols: Optional[List[str]] = None) -> None:
  67         subprotocol = None
  68         if subprotocols:
  69             for subp in subprotocols:
  70                 if subp in self.subprotocols:
  71                     subprotocol = subp
  72                     break
  73 
  74         await self._send(
  75             {
  76                 "type": "websocket.accept",
  77                 "subprotocol": subprotocol,
  78             }
  79         )
  80 
  81     async def close(self, code: int = 1000, reason: str = "") -> None:
  82         pass
  83 
  84     @property
  85     def subprotocols(self):
  86         return self._subprotocols
  87 
  88     @subprotocols.setter
  89     def subprotocols(self, subprotocols: Optional[List[str]] = None):
  90         self._subprotocols = subprotocols or []
  91
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/sanic/server/websockets/connection.py b/sanic/server/websockets/connection.py
  --- a/sanic/server/websockets/connection.py
  +++ b/sanic/server/websockets/connection.py
  @@ -45,7 +45,7 @@
   
           await self._send(message)
   
  -    async def recv(self, *args, **kwargs) -> Optional[str]:
  +    async def recv(self, *args, **kwargs) -> Optional[Union[str, bytes]]:
           message = await self._receive()
   
           if message["type"] == "websocket.receive":
  @@ -53,7 +53,7 @@
                   return message["text"]
               except KeyError:
                   try:
  -                    return message["bytes"].decode()
  +                    return message["bytes"]
                   except KeyError:
                       raise InvalidUsage("Bad ASGI message received")
           elif message["type"] == "websocket.disconnect":
  
verification_info: {"golden_diff": "diff --git a/sanic/server/websockets/connection.py b/sanic/server/websockets/connection.py\n--- a/sanic/server/websockets/connection.py\n+++ b/sanic/server/websockets/connection.py\n@@ -45,7 +45,7 @@\n \n         await self._send(message)\n \n-    async def recv(self, *args, **kwargs) -> Optional[str]:\n+    async def recv(self, *args, **kwargs) -> Optional[Union[str, bytes]]:\n         message = await self._receive()\n \n         if message[\"type\"] == \"websocket.receive\":\n@@ -53,7 +53,7 @@\n                 return message[\"text\"]\n             except KeyError:\n                 try:\n-                    return message[\"bytes\"].decode()\n+                    return message[\"bytes\"]\n                 except KeyError:\n                     raise InvalidUsage(\"Bad ASGI message received\")\n         elif message[\"type\"] == \"websocket.disconnect\":\n", "issue": "ASGI websocket must pass thru bytes as is\n\r\n\r\n_Originally posted by @Tronic in https://github.com/sanic-org/sanic/pull/2640#discussion_r1058027028_\r\n      \n", "before_files": [{"content": "from typing import (\n    Any,\n    Awaitable,\n    Callable,\n    Dict,\n    List,\n    MutableMapping,\n    Optional,\n    Union,\n)\n\nfrom sanic.exceptions import InvalidUsage\n\n\nASGIMessage = MutableMapping[str, Any]\n\n\nclass WebSocketConnection:\n    \"\"\"\n    This is for ASGI Connections.\n    It provides an interface similar to WebsocketProtocol, but\n    sends/receives over an ASGI connection.\n    \"\"\"\n\n    # TODO\n    # - Implement ping/pong\n\n    def __init__(\n        self,\n        send: Callable[[ASGIMessage], Awaitable[None]],\n        receive: Callable[[], Awaitable[ASGIMessage]],\n        subprotocols: Optional[List[str]] = None,\n    ) -> None:\n        self._send = send\n        self._receive = receive\n        self._subprotocols = subprotocols or []\n\n    async def send(self, data: Union[str, bytes], *args, **kwargs) -> None:\n        message: Dict[str, Union[str, bytes]] = {\"type\": \"websocket.send\"}\n\n        if isinstance(data, bytes):\n            message.update({\"bytes\": data})\n        else:\n            message.update({\"text\": str(data)})\n\n        await self._send(message)\n\n    async def recv(self, *args, **kwargs) -> Optional[str]:\n        message = await self._receive()\n\n        if message[\"type\"] == \"websocket.receive\":\n            try:\n                return message[\"text\"]\n            except KeyError:\n                try:\n                    return message[\"bytes\"].decode()\n                except KeyError:\n                    raise InvalidUsage(\"Bad ASGI message received\")\n        elif message[\"type\"] == \"websocket.disconnect\":\n            pass\n\n        return None\n\n    receive = recv\n\n    async def accept(self, subprotocols: Optional[List[str]] = None) -> None:\n        subprotocol = None\n        if subprotocols:\n            for subp in subprotocols:\n                if subp in self.subprotocols:\n                    subprotocol = subp\n                    break\n\n        await self._send(\n            {\n                \"type\": \"websocket.accept\",\n                \"subprotocol\": subprotocol,\n            }\n        )\n\n    async def close(self, code: int = 1000, reason: str = \"\") -> None:\n        pass\n\n    @property\n    def subprotocols(self):\n        return self._subprotocols\n\n    @subprotocols.setter\n    def subprotocols(self, subprotocols: Optional[List[str]] = None):\n        self._subprotocols = subprotocols or []\n", "path": "sanic/server/websockets/connection.py"}], "after_files": [{"content": "from typing import (\n    Any,\n    Awaitable,\n    Callable,\n    Dict,\n    List,\n    MutableMapping,\n    Optional,\n    Union,\n)\n\nfrom sanic.exceptions import InvalidUsage\n\n\nASGIMessage = MutableMapping[str, Any]\n\n\nclass WebSocketConnection:\n    \"\"\"\n    This is for ASGI Connections.\n    It provides an interface similar to WebsocketProtocol, but\n    sends/receives over an ASGI connection.\n    \"\"\"\n\n    # TODO\n    # - Implement ping/pong\n\n    def __init__(\n        self,\n        send: Callable[[ASGIMessage], Awaitable[None]],\n        receive: Callable[[], Awaitable[ASGIMessage]],\n        subprotocols: Optional[List[str]] = None,\n    ) -> None:\n        self._send = send\n        self._receive = receive\n        self._subprotocols = subprotocols or []\n\n    async def send(self, data: Union[str, bytes], *args, **kwargs) -> None:\n        message: Dict[str, Union[str, bytes]] = {\"type\": \"websocket.send\"}\n\n        if isinstance(data, bytes):\n            message.update({\"bytes\": data})\n        else:\n            message.update({\"text\": str(data)})\n\n        await self._send(message)\n\n    async def recv(self, *args, **kwargs) -> Optional[Union[str, bytes]]:\n        message = await self._receive()\n\n        if message[\"type\"] == \"websocket.receive\":\n            try:\n                return message[\"text\"]\n            except KeyError:\n                try:\n                    return message[\"bytes\"]\n                except KeyError:\n                    raise InvalidUsage(\"Bad ASGI message received\")\n        elif message[\"type\"] == \"websocket.disconnect\":\n            pass\n\n        return None\n\n    receive = recv\n\n    async def accept(self, subprotocols: Optional[List[str]] = None) -> None:\n        subprotocol = None\n        if subprotocols:\n            for subp in subprotocols:\n                if subp in self.subprotocols:\n                    subprotocol = subp\n                    break\n\n        await self._send(\n            {\n                \"type\": \"websocket.accept\",\n                \"subprotocol\": subprotocol,\n            }\n        )\n\n    async def close(self, code: int = 1000, reason: str = \"\") -> None:\n        pass\n\n    @property\n    def subprotocols(self):\n        return self._subprotocols\n\n    @subprotocols.setter\n    def subprotocols(self, subprotocols: Optional[List[str]] = None):\n        self._subprotocols = subprotocols or []\n", "path": "sanic/server/websockets/connection.py"}]}