Example #1
0
    def __read(self):
        """
        Read the next frame(s) from the socket.
        """
        fastbuf = BytesIO()
        while self.running:
            try:
                try:
                    c = self.receive()
                except exception.InterruptedException:
                    log.debug("socket read interrupted, restarting")
                    continue
            except Exception:
                c = b''
            if len(c) == 0:
                raise exception.ConnectionClosedException()
            fastbuf.write(c)
            if b'\x00' in c:
                break
            elif c == b'\x0a':
                # heartbeat (special case)
                return [
                    c,
                ]
        self.__recvbuf += fastbuf.getvalue()
        fastbuf.close()
        result = []

        if self.__recvbuf and self.running:
            while True:
                pos = self.__recvbuf.find(b'\x00')

                if pos >= 0:
                    frame = self.__recvbuf[0:pos]
                    preamble_end = frame.find(b'\n\n')
                    if preamble_end >= 0:
                        content_length_match = BaseTransport.__content_length_re.search(
                            frame[0:preamble_end])
                        if content_length_match:
                            content_length = int(
                                content_length_match.group('value'))
                            content_offset = preamble_end + 2
                            frame_size = content_offset + content_length
                            if frame_size > len(frame):
                                #
                                # Frame contains NUL bytes, need to read more
                                #
                                if frame_size < len(self.__recvbuf):
                                    pos = frame_size
                                    frame = self.__recvbuf[0:pos]
                                else:
                                    #
                                    # Haven't read enough data yet, exit loop and wait for more to arrive
                                    #
                                    break
                    result.append(frame)
                    self.__recvbuf = self.__recvbuf[pos + 1:]
                else:
                    break
        return result
Example #2
0
    def __read(self):
        """
        Read the next frame(s) from the socket.

        :return: list of frames read
        :rtype: list(bytes)
        """
        fastbuf = BytesIO()
        while self.running:
            try:
                try:
                    c = self.receive()
                except exception.InterruptedException:
                    log.debug("socket read interrupted, restarting")
                    continue
            except Exception:
                log.debug("socket read error", exc_info=True)
                c = b''
            if c is None or len(c) == 0:
                raise exception.ConnectionClosedException()
            if c == b'\x0a' and not self.__recvbuf and not fastbuf.tell():
                #
                # EOL to an empty receive buffer: treat as heartbeat.
                # Note that this may misdetect an optional EOL at end of frame as heartbeat in case the
                # previous receive() got a complete frame whose NUL at end of frame happened to be the
                # last byte of that read. But that should be harmless in practice.
                #
                fastbuf.close()
                return [c]
            fastbuf.write(c)
            if b'\x00' in c:
                #
                # Possible end of frame
                #
                break
        self.__recvbuf += fastbuf.getvalue()
        fastbuf.close()
        result = []

        if self.__recvbuf and self.running:
            while True:
                pos = self.__recvbuf.find(b'\x00')

                if pos >= 0:
                    frame = self.__recvbuf[0:pos]
                    preamble_end_match = utils.PREAMBLE_END_RE.search(frame)
                    if preamble_end_match:
                        preamble_end = preamble_end_match.start()
                        content_length_match = BaseTransport.__content_length_re.search(
                            frame[0:preamble_end])
                        if content_length_match:
                            content_length = int(
                                content_length_match.group('value'))
                            content_offset = preamble_end_match.end()
                            frame_size = content_offset + content_length
                            if frame_size > len(frame):
                                #
                                # Frame contains NUL bytes, need to read more
                                #
                                if frame_size < len(self.__recvbuf):
                                    pos = frame_size
                                    frame = self.__recvbuf[0:pos]
                                else:
                                    #
                                    # Haven't read enough data yet, exit loop and wait for more to arrive
                                    #
                                    break
                    result.append(frame)
                    pos += 1
                    #
                    # Ignore optional EOLs at end of frame
                    #
                    while self.__recvbuf[pos:pos + 1] == b'\x0a':
                        pos += 1
                    self.__recvbuf = self.__recvbuf[pos:]
                else:
                    break
        return result