예제 #1
0
    async def _send_tcp_message(self, message, stream_writer: asyncio.streams.StreamWriter):
        """
        Write a message to a stream asynchronously
        """
        LOG.trace("Sending %s", message)

        # encode message
        buf = bytes()
        buf += self._encode_message(message)

        # send message
        stream_writer.write(buf)
예제 #2
0
    async def _serve(self, reader: asyncio.streams.StreamReader,
                     writer: asyncio.streams.StreamWriter):
        try:
            proxy = self.pool.pick()
            if not proxy:
                writer.write(b"HTTP/1.1 412 Empty proxy list")
                writer.write(b"\r\n\r\n")
                await writer.drain()
                writer.close()
                return

            logging.info("Selected proxy %s" % proxy)
            remote_reader, remote_writer = await asyncio.open_connection(
                proxy.hostname, proxy.port)
            proxy_auth = None
            if proxy.username:
                proxy_auth = "Proxy-Authorization: %s" % basic_auth(
                    proxy.username, proxy.password)
            await asyncio.gather(*[
                pipe(reader, remote_writer, proxy_auth),
                pipe(remote_reader, writer),
            ])
            proxy.usages += 1
        finally:
            writer.close()
예제 #3
0
    async def _getMessage(reader: asyncio.streams.StreamReader,
                          writer: asyncio.streams.StreamWriter,
                          application: str,
                          timeout: int = 180) -> Optional[dict]:

        END_READING_DATA_MESSAGE = bytes.fromhex(
            "070E10011A003A04080D120050036000")

        while timeout > 0:

            print(timeout, "Начал ждать новое сообщение")

            startEntry = time()

            prefix = await Application._readStream(reader,
                                                   timeout=timeout,
                                                   length=1)
            if not prefix:
                return None
            endEntry = time()
            interval = endEntry - startEntry
            timeout -= interval

            length = await Application._readMessageLength(reader)
            message = await Application._readStream(reader,
                                                    timeout=1,
                                                    length=length)
            if not message:
                return None

            print("Получил новое сообщение", message)

            if prefix == b'\x07':
                iqs = IqStanza()
                iqs.ParseFromString(message)

            elif prefix == b'\x08':
                dms = DataMessageStanza()
                dms.ParseFromString(message)
                dictMessage = MessageToDict(dms)
                writer.write(END_READING_DATA_MESSAGE)
                if "category" in dictMessage and dictMessage[
                        "category"] == application:
                    return dictMessage
            elif prefix == b'\x04':
                return None
            else:
                if not prefix:
                    return None
예제 #4
0
    def __init__(self, reader: asyncio.streams.StreamReader, writer: asyncio.streams.StreamWriter):
        self.reader = reader
        self.writer = writer

        self.address = writer.get_extra_info('peername')

        self.reader_queue = asyncio.Queue(50) # WARNING: this queue full might be problematic, blocks
        self.writer_queue = asyncio.Queue(50) # same here

        self.is_alive = True
        self.timed_out = False

        self.reader_coroutine_closed = False
        self.writer_coroutine_closed = False
예제 #5
0
 async def send(self, writer: asyncio.streams.StreamWriter, message: gp_message) -> None:
     message_bin = message.SerializeToString()
     message_len = len(message_bin)
     message_name = message.DESCRIPTOR.name
     try:
         self._logger.debug('Send protobuf message "%s" (%d bytes)', message_name, message_len)
         writer.write(pack('>I', message_len + self._type_size))
         writer.write(HASerrializeProtocol._hash(message_name))
         writer.write(message_bin)
         await writer.drain()
     except ConnectionResetError:
         msg = 'Send protobuf message "%s" (%d bytes) finished with error: Connection lost'
         self._logger.error(msg, message_name, message_len)
         raise
     except Exception as ex:
         msg = 'Send protobuf message "%s" (%d bytes) finished with error: <%s> %s'
         self._logger.error(msg, message_name, message_len, type(ex), ex)
         raise
예제 #6
0
    async def send(self, writer: asyncio.streams.StreamWriter, message: gp_message) -> None:
        message_bin = message.SerializeToString()
        message_len = len(message_bin)
        message_name = message.DESCRIPTOR.name

        try:
            self._logger.debug('Send protobuf message "%s" (%d bytes)', message_name, message_len)
            writer.write(hex(message_len)[2:].encode('utf-8'))
            writer.write(b'\r\n')
            writer.write(message_bin)
            await writer.drain()
        except ConnectionResetError:
            msg = 'Send protobuf message "%s" (%d bytes) finished with error: Connection lost'
            self._logger.error(msg, message_name, message_len)
            raise
        except Exception as ex:
            msg = 'Send protobuf message "%s" (%d bytes) finished with error: <%s> %s'
            self._logger.error(msg, message_name, message_len, type(ex), ex)
            raise
예제 #7
0
 async def handle_command(reader: asyncio.streams.StreamReader,
                          writer: asyncio.streams.StreamWriter) -> None:
     encrypted_cmd = await reader.read(2048)
     try:
         # decrypt and load message to raise exception if it is invalid
         cmd = loads(smartplug.decrypt(encrypted_cmd).decode("utf-8"))
         if cmd != SmartPlugMock.ok_command:
             raise smartplug.DecryptionException
         # send response
         response = dumps(SmartPlugMock.ok_response)
         encrypted_response = smartplug.encrypt(response.encode("utf-8"))
         writer.write(encrypted_response)
     except (JSONDecodeError, UnicodeDecodeError,
             smartplug.DecryptionException):
         # incorrect command, close connection
         pass
     writer.write_eof()
     await writer.drain()
     writer.close()
     await writer.wait_closed()
예제 #8
0
def write_message(writer: asyncio.streams.StreamWriter, message):
    data = json.dumps(message)
    writer.write(netstring_encode(data))
예제 #9
0
async def process_connection(reader: asyncio.streams.StreamReader, writer: asyncio.streams.StreamWriter):
    peer = writer.get_extra_info('peername')

    def callback(char, d):
        if writer.is_closing():
            return
        char = char.encode('ascii')
        writer.write(ResponseOp.ON_DATA + to_bytes(len(char), 2) + char + to_bytes(len(d), 1) + d)
        asyncio.ensure_future(writer.drain())

    print('Incoming connection from %s:%d' % peer)
    adapter: Optional[bleak.BleakClient] = None

    try:
        while True:
            cmd = await reader.readexactly(1)
            if cmd == RequestOp.SCAN:
                timeout = struct.unpack('!f', await reader.readexactly(4))[0]
                try:
                    toys = await bleak.discover(timeout)
                except BaseException as e:
                    err = str(e)[:0xffff].encode('utf_8')
                    writer.write(ResponseOp.ERROR + to_bytes(len(err), 2) + err)
                    await writer.drain()
                    continue
                writer.write(ResponseOp.OK + to_bytes(len(toys), 2))
                await writer.drain()
                for toy in toys:
                    name = toy.name.encode('utf_8')
                    addr = toy.address.encode('ascii')
                    writer.write(to_bytes(len(name), 2) + name + to_bytes(len(addr), 2) + addr)
                    await writer.drain()
            elif cmd == RequestOp.END:
                break
            else:
                seq_size = await reader.readexactly(3)
                seq, size = seq_size[0], to_int(seq_size[1:])
                data = (await reader.readexactly(size)).decode('ascii')
                try:
                    if cmd == RequestOp.INIT:
                        adapter = bleak.BleakClient(data, timeout=5.0)
                        await adapter.connect()
                    elif cmd == RequestOp.SET_CALLBACK:
                        await adapter.start_notify(data, callback)
                    elif cmd == RequestOp.WRITE:
                        size = to_int(await reader.readexactly(2))
                        payload = bytearray(await reader.readexactly(size))
                        await adapter.write_gatt_char(data, payload, True)
                except EOFError:
                    raise
                except BaseException as e:
                    err = str(e)[:0xffff].encode('utf_8')
                    writer.write(ResponseOp.ERROR + to_bytes(len(err), 2) + err + bytes([seq]))
                    await writer.drain()
                    continue
                writer.write(ResponseOp.OK + bytes([seq]))
                await writer.drain()
    finally:
        writer.close()
        if adapter and await adapter.is_connected():
            await adapter.disconnect()
        await writer.wait_closed()
        print('Disconnected from %s:%d' % peer)