コード例 #1
0
class ControlledConnection:
    def __init__(self, data, limit, leave_open=False):
        self._reader = StreamReader(limit)
        self._reader.feed_data(data)
        if not leave_open:
            self._reader.feed_eof()
        self._mock_write_data = b""

    def get_mock_write_data(self):
        return self._mock_write_data

    async def read(self, size):
        try:
            return await self._reader.read(min(size, 100))
        except Exception:
            raise MalformedDataError

    async def readuntil(self, delim):
        try:
            return await self._reader.readuntil(delim)
        except Exception:
            raise MalformedDataError

    async def readexactly(self, amount):
        try:
            return await self._reader.readexactly(amount)
        except Exception:
            raise MalformedDataError

    async def write(self, data):
        self._mock_write_data += data

    def close(self):
        pass
コード例 #2
0
ファイル: padlock.py プロジェクト: Chaotikum/padlock
def hmland(manager, host, port):
    while True:
        print("Connecting to hmland")

        try:
          loop = events.get_event_loop()
          reader = StreamReader(limit=_DEFAULT_LIMIT, loop=loop)
          protocol = StreamReaderProtocol(reader, loop=loop)
          transport, _ = yield from loop.create_connection(lambda: protocol, host, port)
          writer = StreamWriter(transport, protocol, reader, loop)
          reader, writer = yield from asyncio.open_connection(host, port)

          transport._sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)

          manager.setWriter(writer)

          asyncio.async(manager.update_locks())

          while True:
              line = yield from reader.readline()
              if not line:
                  break

              yield from manager.handle(line.decode("UTF-8").strip())

        except:
          pass

        yield from asyncio.sleep(2)
コード例 #3
0
ファイル: h2tp.py プロジェクト: qweasdzxcpkh/rain
    def connection_made(self, transport):
        self.reader = StreamReader(loop=self.loop)
        self.transport = transport

        self.request.remote_addr = self.remoteaddr
        self.reader.set_transport(transport)

        self.loop.create_task(self.parse())
コード例 #4
0
ファイル: _gzip.py プロジェクト: nICEnnnnnnnLee/dns
def gzip_decompress(reader, writer):
    new_reader = StreamReader(limit=reader._limit, loop=reader._loop)
    task = asyncio.create_task(decompressReader(reader, new_reader))
    _feed_eof = new_reader.feed_eof

    def new_feed_eof():
        if not task.done():
            task.cancel()
        _feed_eof()

    new_reader.feed_eof = new_feed_eof
    return new_reader, writer
コード例 #5
0
 def make(data, *, limit=None, exc=None):
     if limit is not None:
         r = StreamReader(loop=event_loop, limit=limit)
     else:
         r = StreamReader(loop=event_loop)
     w = mock_stream_writers()
     r.feed_data(data)
     if exc is not None:
         r.set_exception(exc)
     else:
         r.feed_eof()
     return r, w
コード例 #6
0
    def __init__(self, *args, quality_check=False, **kwargs):
        """

        Args:
            *args:
            quality_check (bool): there are times when we only establish a connection to check the quality of the node/address
            **kwargs:
        """
        self._stream_reader = StreamReader()
        self._stream_writer = None
        nodemanager = kwargs.pop('nodemanager')
        self.client = NeoNode(self, nodemanager, quality_check)
        self._loop = events.get_event_loop()
        super().__init__(self._stream_reader)
コード例 #7
0
ファイル: WorldServer.py プロジェクト: xfrankbx/idewave-core
    async def handle_connection(self, reader: StreamReader, writer: StreamWriter):
        temp_ref = TempRef()
        world_packet_manager = WorldPacketManager(temp_ref=temp_ref, reader=reader, writer=writer)

        peername = writer.get_extra_info('peername')
        Logger.debug('[World Server]: Accept connection from {}'.format(peername))

        Logger.info('[World Server]: trying to process auth session')
        auth = AuthManager(reader, writer, temp_ref=temp_ref, world_packet_manager=world_packet_manager)
        await auth.process(step=AuthStep.SECOND)

        self._register_tasks()

        while True:
            try:
                request = await asyncio.wait_for(reader.read(4096), timeout=1.0)
                if request:
                    response = await asyncio.wait_for(world_packet_manager.process(request), timeout=1.0)

                    if response:
                        for packet in response:
                            writer.write(packet)
                            await writer.drain()

            except TimeoutError:
                continue

            except Exception as e:
                Logger.error('[World Server]: exception, {}'.format(e))
                traceback.print_exc()
                break

        writer.close()
コード例 #8
0
 def make(data, *, limit=None):
     if limit is not None:
         r = StreamReader(loop=event_loop, limit=limit)
     else:
         r = StreamReader(loop=event_loop)
     w = mock_stream_writers()
     r.feed_data(data)
     r.feed_eof()
     return r, w
コード例 #9
0
ファイル: asyncio_connection.py プロジェクト: sxpert/myhomepy
    async def run(self):
        self._run = True
        started = False
        # start with the login procedure

        # TODO: this is broken, it fails to restart properly

        ctr = 0
        while self._run:
            if self.protocol and not self.protocol.is_connected:
                # reset everything
                self.log('we have been disconnected - reset everything')
                self.reader = None
                self.writer = None
                self.protocol = None
                self.transport = None

            if not self.reader:
                self.log('create a StreamReader')
                self.reader = StreamReader(loop=self.loop)
            if not self.protocol:
                self.log('create OWNProtocol')
                self.protocol = OWNProtocol(self.reader, log=self.log)
            if not self.protocol.is_connected:
                if not self._auto_restart:
                    if started:
                        self.log("no autorestart... bailing out")
                        break
                started = True
                self.log('attempt connection')
                self.is_ready.clear()
                self.log('resetting the msg handler')
                self.msg_handler = self.state_start
                try:
                    self.log('create a new transport connection')
                    self.transport, _ = await self.loop.create_connection(
                        lambda: self.protocol, self.host, self.port)
                except gaierror:
                    self.log('sleep about 5 seconds')
                    await asyncio.sleep(5)
                else:
                    self.log('create a new StreamWriter')
                    self.writer = StreamWriter(
                        self.transport, self.protocol, self.reader, self.loop)
                    self.log('connection is up and running')
            try:
                pkt = await asyncio.wait_for(self.reader.readuntil(b'##'), timeout=1)
            except asyncio.TimeoutError:
                pass
            else:
                # from now on, packets are strings
                msg = pkt.decode('ascii')
                # self.log('packet (%d)=> %s' % (ctr, msg))
                self.log('<= %s' % (msg))
                await self.msg_handler(msg)
                ctr += 1
        self.transport.close()
        self.log('AsyncIOOWNConnection.run : %s the end' % (str(self)))
コード例 #10
0
def column_options():
    reader = BufferedReader(StreamReader(), constants.BUFFER_SIZE)
    writer = BufferedWriter()
    context = Context()
    context.client_settings = {
        "strings_as_bytes": False,
        "strings_encoding": constants.STRINGS_ENCODING,
    }
    column_options = {"reader": reader, "writer": writer, "context": context}
    return column_options
コード例 #11
0
async def test_connection_init(event_loop, mock_stream_writers):
    r = StreamReader(loop=event_loop)
    w = mock_stream_writers()
    connection = Connection(r, w)
    assert connection.reader is r
    assert connection.writer is w
    # Did we screw up __str__?
    str(connection)
    connection.add_header("foo")
    str(connection)
コード例 #12
0
def get_connection_mock(ip, port) -> Tuple[MagicMock, MagicMock]:
    reader = StreamReader()
    reader_mock, writer_mock = (
        MagicMock(spec_set=StreamReader, wraps=reader),
        MagicMock(spec_set=StreamWriter),
    )
    writer_mock.get_extra_info.return_value = (ip, port)
    reader_mock.__anext__ = AsyncMock(spec_set=reader.__anext__,
                                      wraps=reader.__anext__)
    return reader_mock, writer_mock
コード例 #13
0
async def read_json_line(reader: StreamReader) -> Any:
    while True:
        line = await reader.readline()
        if line:
            logging.debug(f"read line from socket: {line!r}")
            try:
                return json.loads(line.decode("utf-8").strip())
            except (ValueError, UnicodeDecodeError):
                logging.warning("invalid JSON received")
        if reader.at_eof():
            raise DisconnectedError()
コード例 #14
0
ファイル: WorldServer.py プロジェクト: etem/idewave-core
    async def handle_connection(self, reader: StreamReader,
                                writer: StreamWriter):
        self._register_tasks()

        temp_ref = TempRef()
        world_packet_manager = WorldPacketManager(temp_ref=temp_ref,
                                                  reader=reader,
                                                  writer=writer)

        Logger.info('[World Server]: trying to process auth session')
        auth = AuthManager(reader,
                           writer,
                           temp_ref=temp_ref,
                           world_packet_manager=world_packet_manager,
                           session_keys=self.session_keys)

        is_authenticated = await auth.process(step=AuthStep.SECOND)

        if is_authenticated:

            peer_name = writer.get_extra_info('peername')
            Logger.success(
                '[World Server]: Accept connection from {}'.format(peer_name))

            while True:
                try:
                    request = await asyncio.wait_for(reader.read(4096),
                                                     timeout=0.01)
                    if request:
                        response = await asyncio.wait_for(
                            world_packet_manager.process(request),
                            timeout=0.01)

                        if response:
                            for packet in response:
                                writer.write(packet)
                                await writer.drain()

                except TimeoutError:
                    pass

                except BrokenPipeError:
                    pass

                except Exception as e:
                    Logger.error('[World Server]: exception, {}'.format(e))
                    traceback.print_exc()
                    break
                finally:
                    await asyncio.sleep(0.01)

        writer.close()
コード例 #15
0
ファイル: protocol.py プロジェクト: cloud8little/neo3-python
    def __init__(self, *args, **kwargs):
        """

        Args:
            *args:
            **kwargs:
        """
        sr = StreamReader()
        self._stream_reader_orig = sr
        self._stream_reader_wr = weakref.ref(sr)
        self._stream_writer = None
        self.client = node.NeoNode(self)
        self._loop = events.get_event_loop()
        super().__init__(sr)
コード例 #16
0
ファイル: http.py プロジェクト: filipovskii/koa.py
  def data_received(self, data):
    print('Data received {}'.format(data.decode('latin-1')))

    if not self._parser:
      self._parser = HttpParser()

    parser = self._parser

    parser.execute(data, len(data))

    if parser.is_headers_complete():
      print("Headers\n{}".format(parser.get_headers()))
      self._transport.pause_reading()

      reader = StreamReader()
      reader.set_transport(self._transport)

      request = HttpRequest(
          reader,
          method=parser.get_method(),
          url=parser.get_url(),
          query_string=parser.get_query_string(),
          version=parser.get_version(),
          headers=parser.get_headers())

      self._request = request

      ctx = HttpContext(request, HttpResponse(self._transport))
      f = asyncio.async(self._app.on_request(ctx))


    if parser.is_message_complete():
      print("Message complete")
      self._parser = None
      self._request = None
      self._transport.resume_reading()
コード例 #17
0
ファイル: LoginServer.py プロジェクト: lyrl/wowcore
    async def handle_connection(self, reader: StreamReader,
                                writer: StreamWriter):
        peername = writer.get_extra_info('peername')
        Logger.info(
            '[Login Server]: Accepted connection from {}'.format(peername))

        auth = AuthManager(reader, writer)

        while not reader.at_eof():
            response = await auth.process()
            if not response:
                break

        Logger.warning('[Login Server]: closing...')
        writer.close()
コード例 #18
0
 async def get_time(self):
     NTP_QUERY = bytearray(48)
     NTP_QUERY[0] = 0x1B
     addr = socket.getaddrinfo(self.host, 123)[0][-1]
     s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
     s.setblocking(False)
     stream = StreamReader(s)
     try:
         s.sendto(NTP_QUERY, addr)
         msg = await stream.read(48)
     finally:
         await stream.wait_closed()
     val = struct.unpack("!I", msg[40:44])[0] - self.ntp_delta
     if self.timezone_callback:
         val = self.timezone_callback(val)
     return val
コード例 #19
0
    async def _reader_task(self, reader: StreamReader) -> None:
        buffer = b""
        while not reader.at_eof():
            chunk = await reader.read(1)
            if not chunk:
                break
            buffer += chunk
            try:
                byte_count, channel_id, frame = unmarshal(buffer)
            except UnmarshalingException:
                continue
            else:
                buffer = b""

            _logger.debug(f"<- {frame.name} {channel_id}")
            await self.dispatch_frame(frame, channel_id)
コード例 #20
0
    async def process_request(reader: StreamReader, writer: StreamWriter,
                              world_packet_mgr: WorldPacketManager):
        request = await asyncio.wait_for(
            reader.read(4096), timeout=Config.Realm.Settings.min_timeout)
        if request:
            opcode, data = request[:1], request[1:]

            if data:
                response = await asyncio.wait_for(
                    world_packet_mgr.process(opcode=opcode, data=data),
                    timeout=Config.Realm.Settings.min_timeout)

                if response:
                    for packet in response:
                        writer.write(packet)
                        await writer.drain()
コード例 #21
0
    async def process_request(reader: StreamReader, writer: StreamWriter, world_packet_mgr: WorldPacketManager):
        request: bytes = await wait_for(reader.read(4096), timeout=Config.Realm.Settings.min_timeout)
        if request:
            size, opcode, data = request[:2], request[2:6], request[6:]

            response: List[bytes] = await wait_for(
                world_packet_mgr.process(
                    size=size,
                    opcode=opcode,
                    data=data
                ),
                timeout=Config.Realm.Settings.min_timeout
            )

            if response:
                for packet in response:
                    writer.write(packet)
                    await writer.drain()
コード例 #22
0
    async def handle_connection(self, reader: StreamReader,
                                writer: StreamWriter):
        peername = writer.get_extra_info('peername')
        Logger.debug(
            '[World Server]: Accept connection from {}'.format(peername))

        await self.accept_connection(peername)

        auth = AuthSessionManager(reader, writer)
        auth.prepare()
        await auth.process()

        # If I understand it correctly, after SMSG_AUTH_RESPONSE server should waiting for CMSG_CHAR_ENUM
        # But next request never sends by client. Client stucks on 'Connected'
        try:
            next_request = await asyncio.wait_for(reader.read(1024),
                                                  timeout=1.0)
            Logger.debug(
                '[World Server]: next request = {}'.format(next_request))
        except TimeoutError:
            Logger.error('[World Server]: next request was not received')
        finally:
            Logger.warning('[World Server]: closing...')
コード例 #23
0
async def ee4_srv(r: StreamReader, w: StreamWriter):
    logger.info(f"connection established")
    # create new context for client
    ctx = SubscriptionContext(r, w)
    try:
        while not r.exception():
            msg_raw = await r.readline()
            msg = msg_raw.decode().strip()
            logger.info(f"< {msg}")
            out = cmd_handler(msg, ctx)
            logger.info(f"> {out}")
            w.write(f"{out}\r\n".encode())
            await w.drain()
    except UnicodeDecodeError:
        logger.warning("invalid char encountered")
    except AttributeError:
        logger.warning("attribute error encountered")
    except ConnectionError:
        logger.warning("connection error encountered")
    finally:
        logger.info("cleaning up resources")
        ctx.end()
    logger.info(f"resources purged. connection terminated.")
コード例 #24
0
ファイル: core.py プロジェクト: blockchain-Bobby/p2p-python
    async def initial_connection_check(self, reader: StreamReader,
                                       writer: StreamWriter):
        host_port = writer.get_extra_info('peername')
        new_user: Optional[User] = None
        try:
            # 1. send plain message
            writer.write(b'hello')
            await writer.drain()

            # 2. receive other's header
            try:
                received = await asyncio.wait_for(reader.read(BUFFER_SIZE),
                                                  5.0)
                if len(received) == 0:
                    raise PeerToPeerError('empty msg receive')
                header = json.loads(received.decode())
            except asyncio.TimeoutError:
                raise PeerToPeerError('timeout on other\'s header receive')
            except json.JSONDecodeError:
                raise PeerToPeerError(
                    'json decode error on other\'s header receive')

            # 3. generate new user
            user_header = UserHeader(**header)
            new_user = User(user_header, self.number, reader, writer,
                            host_port, AESCipher.create_key(), SERVER_SIDE)
            self.number += 1
            if new_user.header.name == V.SERVER_NAME:
                raise ConnectionAbortedError('Same origin connection')

            # 4. send my public key
            my_sec, my_pub = generate_keypair()
            send = json.dumps({'public-key': my_pub}).encode()
            await new_user.send(send)
            self.traffic.put_traffic_up(send)

            # 5. receive public key
            try:
                receive = await new_user.recv()
                self.traffic.put_traffic_down(receive)
                if len(receive) == 0:
                    raise ConnectionAbortedError('received msg is zero.')
                data = json.loads(receive.decode())
            except asyncio.TimeoutError:
                raise PeerToPeerError('timeout on public key receive')
            except json.JSONDecodeError:
                raise PeerToPeerError(
                    'json decode error on public key receive')

            # 6. encrypt and send AES key and header
            send = json.dumps({
                'aes-key': new_user.aeskey,
                'header': self.get_server_header(),
            })
            key = generate_shared_key(my_sec, data['public-key'])
            encrypted = AESCipher.encrypt(key, send.encode())
            await new_user.send(encrypted)
            self.traffic.put_traffic_up(encrypted)

            # 7. receive accept signal
            try:
                encrypted = await new_user.recv()
                self.traffic.put_traffic_down(encrypted)
            except asyncio.TimeoutError:
                raise PeerToPeerError('timeout on accept signal receive')
            receive = AESCipher.decrypt(new_user.aeskey, encrypted)
            if receive != b'accept':
                raise PeerToPeerError(f"Not accept signal! {receive}")

            # 8. accept connection
            log.info(
                f"established connection as server from {new_user.header.name} {new_user.get_host_port()}"
            )
            asyncio.ensure_future(self.receive_loop(new_user))
            # server port's reachable check
            await asyncio.sleep(1.0)
            await self.check_reachable(new_user)
            return
        except (ConnectionAbortedError, ConnectionResetError) as e:
            msg = f"disconnect error {host_port} {e}"
        except PeerToPeerError as e:
            msg = f"peer2peer error {host_port} {e}"
        except Exception as e:
            msg = "InitialConnCheck: {}".format(e)
            log.error(msg, exc_info=True)

        # EXCEPTION!
        if new_user:
            # remove user
            self.remove_connection(new_user, msg)
        else:
            # close socket
            log.debug(msg)
            try:
                writer.write(msg.encode())
                await writer.drain()
            except Exception:
                pass
            try:
                writer.close()
            except Exception:
                pass
コード例 #25
0
 def __init__(self, data, limit, leave_open=False):
     self._reader = StreamReader(limit)
     self._reader.feed_data(data)
     if not leave_open:
         self._reader.feed_eof()
     self._mock_write_data = b""
コード例 #26
0
 def setUp(self):
     self.proxy = Proxy('127.0.0.1', '80', timeout=0.1)
     self.proxy._reader['conn'] = StreamReader()
コード例 #27
0
async def test_connection_init(event_loop, mock_stream_writers):
    r = StreamReader(loop=event_loop)
    w = mock_stream_writers()
    connection = Connection(r, w)
    assert connection.reader is r
    assert connection.writer is w
コード例 #28
0
ファイル: h2tp.py プロジェクト: qweasdzxcpkh/rain
class HTTPProtocol(asyncio.Protocol):
    request_cls = Request

    def __init__(self, app=None):
        self.app = app
        self.router = app.router
        self.transport = None
        self.reader = None
        self.writer = None
        self._request: Request = None
        self.keep_alive = False
        self.loop = asyncio.get_event_loop()

    @property
    def request(self):
        if self._request is None:
            self._request = self.request_cls()
            self._request.remote_addr = self.remoteaddr

        return self._request

    @cachedproperty
    def remoteaddr(self):
        return '{}:{}'.format(*self.transport.get_extra_info('peername'))

    def _del_req(self):
        self._request = None

    def connection_made(self, transport):
        self.reader = StreamReader(loop=self.loop)
        self.transport = transport

        self.request.remote_addr = self.remoteaddr
        self.reader.set_transport(transport)

        self.loop.create_task(self.parse())

    def data_received(self, data):
        self.reader.feed_data(data)

    # noinspection PyProtectedMember
    async def parse(self):
        while True:
            req = self.request
            line = await self.reader.readline()

            if not req._f:
                req._f = True
                _ = _parse_first_line(line)
                if not _ or len(_) != 4:
                    req.parse_error = BadRequestError()
                    return await self.finish()

                req.method, req.path, req.query_string, req.hv = _
            else:
                if req._body_length:
                    req._body_lines.append(line)
                    req._body_length += len(line)
                    if req._body_length > req.content_length + 1:
                        raise BadRequestError
                    elif req._body_length == req.content_length + 1:
                        return await self.finish()
                else:
                    if line == b'\r\n':
                        if req.method in {'GET', 'HEAD'
                                          } or not req.content_length:
                            return await self.finish()

                        req._body_length = 1
                        req._body_lines = []
                    else:
                        error = _parse_header_line(line, req)
                        if error is not None:
                            req.parse_error = error
                            return await self.finish()

    async def finish(self):
        req = self.request
        delattr(req, '_f')
        delattr(req, '_body_length')
        self._del_req()

        await self.app.handle(req, self)

        if req.keepalive:
            await self.parse()
        else:
            self.transport.close()

    def send(self, bs):
        self.transport.write(bs)

    def error(self, err, **kwargs):
        handler = self.app.error_handlers.get(err.status)
        if handler:
            return handler(err, **kwargs)
        else:
            return err.make_response(**kwargs)
コード例 #29
0
class ControlledConnection:
    def __init__(self, limit=100000000):
        self._reader = StreamReader(limit)
        self._mock_write_data = b""
        self._closed = False
        self._closed_by_us = False

    def _feed_data(self, data):
        self._reader.feed_data(data)

    def _feed_eof(self):
        self._reader.feed_eof()

    def _get_mock_write_data(self):
        return self._mock_write_data

    def _check_eof(self):
        if self._reader.at_eof():
            self._closed = True

    async def read(self, size):
        self._check_eof()
        try:
            return await self._reader.read(min(size, 100))
        except Exception:
            self._closed = True
            raise MalformedDataError

    async def readuntil(self, delim):
        self._check_eof()
        try:
            return await self._reader.readuntil(delim)
        except Exception:
            self._closed = True
            raise MalformedDataError

    async def readexactly(self, amount):
        self._check_eof()
        try:
            return await self._reader.readexactly(amount)
        except Exception:
            self._closed = True
            raise MalformedDataError

    async def write(self, data):
        self._mock_write_data += data
        return not self._closed

    async def add_header(self, header):
        pass

    def close(self):
        self._closed = True
        self._closed_by_us = True

    async def wait_closed(self):
        while not self._closed:
            await asyncio.sleep(1)

    def closed_by_us(self):
        return self._closed_by_us
コード例 #30
0
class NeoProtocol(StreamReaderProtocol):
    def __init__(self, *args, quality_check=False, **kwargs):
        """

        Args:
            *args:
            quality_check (bool): there are times when we only establish a connection to check the quality of the node/address
            **kwargs:
        """
        self._stream_reader = StreamReader()
        self._stream_writer = None
        nodemanager = kwargs.pop('nodemanager')
        self.client = NeoNode(self, nodemanager, quality_check)
        self._loop = events.get_event_loop()
        super().__init__(self._stream_reader)

    def connection_made(self,
                        transport: asyncio.transports.BaseTransport) -> None:
        super().connection_made(transport)
        self._stream_writer = StreamWriter(transport, self,
                                           self._stream_reader, self._loop)

        if self.client:
            asyncio.create_task(self.client.connection_made(transport))

    def connection_lost(self, exc: Optional[Exception] = None) -> None:
        if self.client:
            task = asyncio.create_task(self.client.connection_lost(exc))
            task.add_done_callback(
                lambda args: super(NeoProtocol, self).connection_lost(exc))
        else:
            super().connection_lost(exc)

    def eof_received(self) -> bool:
        self._stream_reader.feed_eof()

        self.connection_lost()
        return True
        # False == Do not keep connection open, this makes sure that `connection_lost` gets called.
        # return False

    async def send_message(self, message: Message) -> None:
        try:
            self._stream_writer.write(message.to_array())
            await self._stream_writer.drain()
        except ConnectionResetError:
            # print("connection reset")
            self.connection_lost(ConnectionResetError)
        except ConnectionError:
            # print("connection error")
            self.connection_lost(ConnectionError)
        except asyncio.CancelledError:
            # print("task cancelled, closing connection")
            self.connection_lost(asyncio.CancelledError)
        except Exception as e:
            # print(f"***** woah what happened here?! {traceback.format_exc()}")
            self.connection_lost()

    async def read_message(self, timeout: int = 30) -> Message:
        if timeout == 0:
            # avoid memleak. See: https://bugs.python.org/issue37042
            timeout = None

        async def _read():
            try:
                message_header = await self._stream_reader.readexactly(24)
                magic, command, payload_length, checksum = struct.unpack(
                    'I 12s I I',
                    message_header)  # uint32, 12byte-string, uint32, uint32

                payload_data = await self._stream_reader.readexactly(
                    payload_length)
                payload, = struct.unpack('{}s'.format(payload_length),
                                         payload_data)

            except Exception:
                # ensures we break out of the main run() loop of Node, which triggers a disconnect callback to clean up
                self.client.disconnecting = True
                return None

            m = Message(magic,
                        command.rstrip(b'\x00').decode('utf-8'), payload)

            if checksum != m.get_checksum(payload):
                logger.debug("Message checksum incorrect")
                return None
            else:
                return m

        try:
            return await asyncio.wait_for(_read(), timeout)
        except Exception:
            return None

    def disconnect(self) -> None:
        if self._stream_writer:
            self._stream_writer.close()
コード例 #31
0
def stream_reader_writer_slots_before_units(hass):
    """Create a StreamReader and fill it with connection messages."""
    reader = StreamReader()
    reader.feed_data(
        b"\x1b[H\x1b[2JWelcome to the Folding@home Client command server.\n")
    reader.feed_data(b"OK\n")
    reader.feed_data(b"> \n")
    reader.feed_data(b"> \n")
    reader.feed_data(b"> \n")
    reader.feed_data(b"> \n")
    reader.feed_data(b"PyON 1 slots\n")
    reader.feed_data(
        b'[{"id": "00", "status": "READY", "description": "cpu: 3", "options": {"idle": "false"}, "reason": "", "idle": False}]\n'
    )
    reader.feed_data(b"---\n")
    reader.feed_data(b"> \n")
    reader.feed_data(b"> \n")
    reader.feed_data(b"> \n")
    reader.feed_data(b"> \n")
    reader.feed_data(b"PyON 1 units\n")
    reader.feed_data(b"""[{
        "id": "00",
        "state": "RUNNING",
        "error": "NO_ERROR",
        "project": 11777,
        "run": 0,
        "clone": 17250,
        "gen": 0,
        "core": "0x22",
        "unit": "0x00000003287234c95e774a8488c5d4ea",
        "percentdone": "72.51%",
        "eta": "1 hours 04 mins",
        "ppd": "359072",
        "creditestimate": "58183",
        "waitingon": "",
        "nextattempt": "0.00 secs",
        "timeremaining": "8.08 days",
        "totalframes": 100,
        "framesdone": 72,
        "assigned": "2020-03-28T08: 33: 55Z",
        "timeout": "2020-03-29T08: 33: 55Z",
        "deadline": "2020-04-05T13: 21: 54Z",
        "ws": "40.114.52.201",
        "cs": "13.82.98.119",
        "attempts": 0,
        "slot": "00",
        "tpf": "2 mins 20 secs",
        "basecredit": "9405"
    }
    ]\n""")
    reader.feed_data(b"---\n")
    reader.feed_data(b"> \n")
    reader.feed_data(b"> \n")
    reader.feed_data(b"> \n")
    reader.feed_data(b"> \n")
    reader.feed_eof()
    stream_writer = AsyncMock()
    stream_writer.close = MagicMock()
    return (reader, stream_writer)
コード例 #32
0
 def __init__(self, limit=100000000):
     self._reader = StreamReader(limit)
     self._mock_write_data = b""
     self._closed = False
     self._closed_by_us = False
コード例 #33
0
ファイル: test_proxy.py プロジェクト: jtr860830/proxybroker2
def proxy():
    proxy = Proxy('127.0.0.1', '80', timeout=0.1)
    proxy._reader['conn'] = StreamReader()
    return proxy
コード例 #34
0
ファイル: asyncio_connection.py プロジェクト: sxpert/myhomepy
class AsyncIOOWNConnection(object):
    SOCKET_MODES = ('*99*0##', '*99*1##', '*99*9##')
    MODE_COLORS = (COLOR_LT_BLUE, COLOR_LT_GREEN, COLOR_LT_CYAN)
    MODE_NAMES = ('CMD', 'MON', 'SCMD')

    ACK = '*#*1##'

    def __init__(self, host, port, passwd, queue, mode,
                 log=None, loop=None):
        self.host = host
        self.port = port
        self.passwd = passwd
        self.queue = queue
        self.mode = mode
        self.loop = loop
        self._auto_restart = True
        self._run = False
        if self.loop is None:
            self.loop = asyncio.get_event_loop()
        self.is_ready = asyncio.Event(loop=self.loop)
        if log is None:
            hdr = '[%s:%d %s]' % \
                (self.host, self.port, self.MODE_NAMES[self.mode])
            self.log = \
                get_logger(header=hdr,
                           color=self.MODE_COLORS[self.mode])
        else:
            self.log = log
        self.reader = None
        self.writer = None
        self.protocol = None
        self.transport = None

    @property
    def auto_restart(self):
        return self._auto_restart

    @auto_restart.setter
    def auto_restart(self, value):
        self._auto_restart = value

    async def run(self):
        self._run = True
        started = False
        # start with the login procedure

        # TODO: this is broken, it fails to restart properly

        ctr = 0
        while self._run:
            if self.protocol and not self.protocol.is_connected:
                # reset everything
                self.log('we have been disconnected - reset everything')
                self.reader = None
                self.writer = None
                self.protocol = None
                self.transport = None

            if not self.reader:
                self.log('create a StreamReader')
                self.reader = StreamReader(loop=self.loop)
            if not self.protocol:
                self.log('create OWNProtocol')
                self.protocol = OWNProtocol(self.reader, log=self.log)
            if not self.protocol.is_connected:
                if not self._auto_restart:
                    if started:
                        self.log("no autorestart... bailing out")
                        break
                started = True
                self.log('attempt connection')
                self.is_ready.clear()
                self.log('resetting the msg handler')
                self.msg_handler = self.state_start
                try:
                    self.log('create a new transport connection')
                    self.transport, _ = await self.loop.create_connection(
                        lambda: self.protocol, self.host, self.port)
                except gaierror:
                    self.log('sleep about 5 seconds')
                    await asyncio.sleep(5)
                else:
                    self.log('create a new StreamWriter')
                    self.writer = StreamWriter(
                        self.transport, self.protocol, self.reader, self.loop)
                    self.log('connection is up and running')
            try:
                pkt = await asyncio.wait_for(self.reader.readuntil(b'##'), timeout=1)
            except asyncio.TimeoutError:
                pass
            else:
                # from now on, packets are strings
                msg = pkt.decode('ascii')
                # self.log('packet (%d)=> %s' % (ctr, msg))
                self.log('<= %s' % (msg))
                await self.msg_handler(msg)
                ctr += 1
        self.transport.close()
        self.log('AsyncIOOWNConnection.run : %s the end' % (str(self)))

    def stop(self):
        self.log('stop requested', LOG_DEBUG)
        self._run = False

    async def send_packet(self, msg):
        self.log('=> %s' % (msg))
        if isinstance(msg, str):
            pkt = msg.encode('ascii')
            self.writer.write(pkt)
        await self.writer.drain()

    async def state_start(self, msg):
        if msg == self.ACK:
            self.msg_handler = self.state_login
            cmd_msg = self.SOCKET_MODES[self.mode]
            await self.send_packet(cmd_msg)
        else:
            self.log('we didn\'t get ACK')

    async def state_login(self, msg):
        if msg == '*98*2##':
            # this is a call for sha2 hmac authentication
            self.msg_handler = self.state_hmac_sha2
            await self.send_packet(self.ACK)
        else:
            # attempt matching the old password system
            ops_m = re.match(r'^\*#(\d+)##$', msg)
            if ops_m is not None:
                nonce = ops_m.groups()[0]
                # calculate the password
                passwd = ownCalcPass(self.passwd, nonce)
                passwd_msg = ('*#%s##' % (passwd))
                self.msg_handler = self.state_auth
                await self.send_packet(passwd_msg)
            else:
                self.log("unable to parse the openpassword nonce request")
                await asyncio.sleep(0)

    async def state_hmac_sha2(self, msg):
        ra_m = re.match(r'^\*#(\d{128})##$', msg)
        if ra_m is not None:
            ra = ra_m.group(1)
            hmac = ownCalcHmacSha2(self.passwd, ra)
            rb, hmac_client, self.hmac_server = hmac
            self.msg_handler = self.state_hmac_sha2_check_response
            hmac_packet = ('*#%s*%s##' % (rb, hmac_client))
            await self.send_packet(hmac_packet)
        else:
            self.log("unable to parse the hmac_sha2 request")
            await asyncio.sleep(0)

    async def state_hmac_sha2_check_response(self, msg):
        c_resp_m = re.match(r'^\*#(\d{128})##$', msg)
        if c_resp_m is not None:
                c_resp = c_resp_m.group(1)
                if c_resp == self.hmac_server:
                    self.is_ready.set()
                    self.msg_handler = self.state_dispatch
                    await self.send_packet(self.ACK)
                    
                else:
                    self.log("wrong response from server, expected %s", self.hmac_server)
                    await asyncio.sleep(0)
        else:
            self.log("unable to parse the hmac_sha2 request")
            await asyncio.sleep(0)

    async def state_auth(self, msg):
        if msg == self.ACK:
            self.is_ready.set()
            self.msg_handler = self.state_dispatch

    async def state_dispatch(self, msg):
        await self.queue.put((msg, self.mode, ))