Beispiel #1
0
    async def recv_data(self):
        data_len = 0
        buff = tmp_file()
        try:
            with buff.open('wb') as fh:
                while chunk_size := as_uint(await self.conn.read(4)):
                    if chunk_size > MAX_IN_MEMORY:
                        data_len += await self._recv_large_chunk(
                            fh, chunk_size)
                    else:
                        data_len += await self._recv_small_chunk(
                            fh, chunk_size)

            if data_len > self.conn.conf.max_plain_payload:
                if self.data_type != T_FILE:
                    raise ProtocolError(
                        f'Attempted to send message larger than '
                        f'{format_amount(self.conn.conf.max_plain_payload)}',
                        conn=self.conn)
                decode = buff
            elif self.data_type != T_FILE:
                with buff.open('rb') as _fh:
                    decode = _fh.read()
            self.data = await Codec.decode(decode, self.data_type,
                                           self.headers)
            self.data_len = data_len
Beispiel #2
0
    async def init(self):
        await self.write(to_uint(self.PROTOCOL_VERSION, 4))
        result = await self.read(4)
        if result != bytes(4):
            raise ProtocolError(
                f'Unsupported protocol version. '
                f'Please upgrade your client to: {as_uint(result)}',
                conn=self
            )

        client_stmt = ClientStatement(
            api=self.api_version,
            client_time=time_ns() // 1000_000,
            scheme_format='JSON',
            compressors=['gzip', 'zlib'],
            default_compression='zlib',
        )
        self.set_compressors(['gzip', 'zlib'], 'zlib')
        await self.write(client_stmt.pack())
        stmt: ServerStatement = ServerStatement.unpack(
            await self.read(as_uint(await self.read(4)))
        )
        self.time_delta = (stmt.server_time / 1000) - time()

        if self.conf.handshake is not None:
            await self.conf.handshake.send(self)

        self.debug(f'{self} initialized')
Beispiel #3
0
 async def decompress_file(cls, src: Path, dst: Path,
                           headers: T_Headers) -> None:
     compressor = zlib.decompressobj()
     value = 1
     with src.open('rb') as rc:
         with dst.open('wb') as wc:
             ln = as_uint(rc.read(4))
             while line := rc.read(1 << 24):
                 wc.write(buff := compressor.decompress(line))
                 value = zlib.adler32(buff, value)
             wc.write(compressor.flush())
Beispiel #4
0
    async def init(cls, conn):
        head = await cls._recv_head(conn)
        headers_size = as_uint(await conn.read(4))
        headers = Headers.decode(await conn.read(headers_size))
        conn.debug(
            f'[RECV {conn.address}] [{int2hex(head.message_id):<4}] <- HEADERS {headers}'
        )

        action = cls(**vars(head), headers=headers)
        action.conn = conn
        return action
Beispiel #5
0
 async def decompress(cls, data: bytes, headers: T_Headers) -> bytes:
     ln, data = as_uint(data[:4]), data[4:]
     buff = zlib.decompress(data)
     checksum = headers.get('Adler32', None)
     if ln != len(buff):
         raise CompressorError('Broken data received: Length mismatch',
                               data=data,
                               headers=headers)
     if checksum is not None and zlib.adler32(buff) != checksum:
         raise CompressorError('Broken data received: Checksum mismatch',
                               data=data,
                               headers=headers)
     return buff
Beispiel #6
0
 async def handle_stream(self, stream: IOStream, address: tuple[str, int]) -> None:
     try:
         protocol_version = as_uint(await stream.read_bytes(4))
         if not self.protocols[0] <= protocol_version <= self.protocols[1]:
             await stream.write(to_uint(self.protocols[1], 4))
             stream.close(CatsError('Unsupported protocol version'))
             return
         await stream.write(bytes(4))
         async with self.create_connection(stream, address, protocol_version) as conn:
             conn: ServerConnection
             conn.debug(f'[INIT {address}]')
             await conn.init()
             await conn.start()
         conn.debug(f'[STOP {address}]')
     except self.app.config.stream_errors:
         pass
    async def init(self):
        self.client: ClientStatement = ClientStatement.unpack(
            await self.read(as_uint(await self.read(4)))
        )
        self.api_version = self.client.api
        self.set_compressors(self.client.compressors, self.client.default_compression)
        self.debug(f'[RECV {self.address}] {self.client}')

        server_stmt = ServerStatement(
            server_time=time_ns() // 1000_000,
        )
        await self.write(server_stmt.pack())
        self.debug(f'[SEND {self.address}] {server_stmt}')

        if self.conf.handshake is not None:
            await self.conf.handshake.validate(self)

        self.debug(f'{self} initialized')