Ejemplo n.º 1
0
    async def ws_connect(self):
        """Connect to the websocket server."""
        if self.connected:
            raise TransportError('Connection already open.')

        try:
            self._client = await self.session.ws_connect(
                self._url, **self._connect_kwargs)
        except (ClientError, HttpProcessingError, asyncio.TimeoutError) as exc:
            raise TransportError('Error connecting to server', None, exc)
        return self.session.loop.create_task(self._ws_loop())
Ejemplo n.º 2
0
    async def _ws_loop(self):
        """Listen for messages from the websocket server."""
        msg = None
        try:
            while True:
                msg = await self._client.receive()

                if msg.type == aiohttp.WSMsgType.CLOSED:
                    break
                if msg.type == aiohttp.WSMsgType.ERROR:
                    break

                if msg.type == aiohttp.WSMsgType.BINARY:
                    try:
                        # If we get a binary message, try and decode it as a
                        # UTF-8 JSON string, in case the server is sending
                        # binary websocket messages. If it doens't decode we'll
                        # ignore it since we weren't expecting binary messages
                        # anyway
                        data = json.loads(msg.data.decode())
                    except ValueError:
                        continue
                elif msg.type == aiohttp.WSMsgType.TEXT:
                    try:
                        data = msg.json()
                    except ValueError as exc:
                        raise TransportError('Error Parsing JSON', None, exc)
                else:
                    # This is tested with test_message_ping_ignored, but
                    # cpython's optimizations prevent coveragepy from detecting
                    # that it's run
                    # https://bitbucket.org/ned/coveragepy/issues/198/continue-marked-as-not-covered
                    continue  # pragma: no cover

                if 'method' in data:
                    request = jsonrpc_base.Request.parse(data)
                    response = self.receive_request(request)
                    if response:
                        await self.send_message(response)
                else:
                    self._pending_messages[data['id']].response = data

        except (ClientError, HttpProcessingError, asyncio.TimeoutError) as exc:
            raise TransportError('Transport Error', None, exc)
        finally:
            await self.close()
            if msg and msg.type == aiohttp.WSMsgType.ERROR:
                raise TransportError(
                    'Websocket error detected. Connection closed.')
Ejemplo n.º 3
0
    async def send_message(self, message):
        """Send the HTTP message to the server and return the message response.

        No result is returned if message is a notification.
        """
        if self._client is None:
            raise TransportError('Client is not connected.', message)

        try:
            await self._client.send_str(message.serialize())
            if message.response_id:
                pending_message = PendingMessage(loop=self.session.loop)
                self._pending_messages[message.response_id] = pending_message
                response = await pending_message.wait(self._timeout)
                del self._pending_messages[message.response_id]
            else:
                response = None
            return message.parse_response(response)
        except (ClientError, HttpProcessingError, asyncio.TimeoutError) as exc:
            raise TransportError('Transport Error', message, exc)
Ejemplo n.º 4
0
    def send_message(self, message):
        """Issue the request to the server and return the method result (if not a notification)"""
        try:
            if isinstance(message, jsonrpc_base.Request):
                data = jsonrpc_base.Request.parse(
                    json.loads(message.serialize()))
            else:
                data = message.serialize()
            response = json.loads(json.dumps(self._handler(data)))
        except Exception as requests_exception:
            raise TransportError('Transport Error', message,
                                 requests_exception)

        return message.parse_response(response)
Ejemplo n.º 5
0
    def send_message(self, message):
        """Send the HTTP message to the server and return the message response.

        No result is returned if message is a notification.
        """
        try:
            response = yield from self._request(data=message.serialize())
        except (aiohttp.ClientError, asyncio.TimeoutError) as exc:
            raise TransportError('Transport Error', message, exc)

        if response.status != 200:
            raise TransportError('HTTP %d %s' % (response.status, response.reason), message)

        if message.response_id is None:
            # Message is notification, so no response is expcted.
            return None

        try:
            response_data = yield from response.json()
        except ValueError as value_error:
            raise TransportError('Cannot deserialize response body', message, value_error)

        return message.parse_response(response_data)
Ejemplo n.º 6
0
 def test_transport_error_constructor(self):
     with self.assertRaisesRegex(TransportError, 'Test Message'):
         raise TransportError('Test Message')
Ejemplo n.º 7
0
def test_transport_error_constructor(server):
    with pytest.raises(TransportError, match='Test Message'):
        raise TransportError('Test Message')