Beispiel #1
0
 def parse(data):
     response = HttpResponse()
     for i in range(0, len(data)):
         response.parse(data[i])
         if response.is_read_completely():
             break
     return response
    def _read_response(self, timeout=10):
        # following the information from page 71 about HTTP Message splitting:
        # The blocks start with 2 byte little endian defining the length of the encrypted data (max 1024 bytes)
        # followed by 16 byte authTag
        blocks = []
        tmp = bytearray()
        exp_len = 1024
        response = HttpResponse()
        while not response.is_read_completely():
            # make sure we read all blocks but without blocking to long. Was introduced to support chunked transfer mode
            # from https://github.com/maximkulkin/esp-homekit
            self.sock.setblocking(0)

            no_data_remaining = (len(tmp) == 0)

            # if there is no data use the long timeout so we don't miss anything, else since there is still data go on
            # much quicker.
            if no_data_remaining:
                used_timeout = timeout
            else:
                used_timeout = 0.01
            data_ready = select.select([self.sock], [], [], used_timeout)[0]

            # check if there is anything more to do
            if not data_ready and no_data_remaining:
                break

            self.sock.settimeout(0.1)
            data = self.sock.recv(exp_len)

            # ready but no data => continue
            if not data and no_data_remaining:
                continue

            tmp += data
            length = int.from_bytes(tmp[0:2], 'little')
            if length + 18 > len(tmp):
                # if the the amount of data in tmp is not length + 2 bytes for length + 16 bytes for the tag, the block
                # is not complete yet
                continue
            tmp = tmp[2:]

            block = tmp[0:length]
            tmp = tmp[length:]

            tag = tmp[0:16]
            tmp = tmp[16:]

            decrypted = self.decrypt_block(length, block, tag)
            # TODO how to react to False?
            if tmp is not False:
                response.parse(decrypted)

            # check how long next block will be
            if int.from_bytes(tmp[0:2], 'little') < 1024:
                exp_len = int.from_bytes(tmp[0:2], 'little') - len(tmp) + 18

        return response
Beispiel #3
0
    def _read_response(self):
        # following the information from page 71 about HTTP Message splitting:
        # The blocks start with 2 byte little endian defining the length of the encrypted data (max 1024 bytes)
        # followed by 16 byte authTag
        blocks = []
        tmp = bytearray()
        exp_len = 128
        response = HttpResponse()
        while not response.is_read_completly():
            # make sure we read all blocks but without blocking to long. Was introduced to support chunked transfer mode
            # from https://github.com/maximkulkin/esp-homekit
            self.sock.setblocking(0)
            ready = select.select([self.sock], [], [], 10)
            if not ready[0]:
                break

            self.sock.settimeout(0.1)
            data = self.sock.recv(exp_len)

            # ready but no data => quit
            if not data:
                break

            tmp += data
            length = int.from_bytes(tmp[0:2], 'little')
            if length + 18 > len(tmp):
                # if the the amount of data in tmp is not length + 2 bytes for length + 16 bytes for the tag, the block
                # is not complete yet
                continue
            tmp = tmp[2:]

            block = tmp[0:length]
            tmp = tmp[length:]

            tag = tmp[0:16]
            tmp = tmp[16:]

            response.parse(self.decrypt_block(length, block, tag))

            # check how long next block will be
            if int.from_bytes(tmp[0:2], 'little') < 1024:
                exp_len = int.from_bytes(tmp[0:2], 'little') - len(tmp) + 18

        return response
Beispiel #4
0
 def function_for_put_testing(url, body):
     response = HttpResponse()
     response.body = json.dumps({'characteristics': []}).encode()
     return response
Beispiel #5
0
 def function_for_put_testing(url, body):
     assert ' ' not in body, 'Regression of https://github.com/jlusiardi/homekit_python/issues/181'
     response = HttpResponse()
     response.body = json.dumps({'characteristics': []}).encode()
     return response