def handleMessage(self, msg_code, msg_data): if msg_code == 20: # If he send extended message, we can extend connection time self.resetTimeout() # Extended handshake if ord(msg_data[0]) == 0: hs_data = bdecode(msg_data[1:]) if "metadata_size" in hs_data and "m" in hs_data and "ut_metadata" in hs_data[ "m"]: metadata_size = hs_data["metadata_size"] ut_metadata_id = hs_data["m"]["ut_metadata"] hs_response = { "e": 0, "metadata_size": hs_data["metadata_size"], "v": "\xce\xbcTorrent 3.4.9", "m": { "ut_metadata": 1 }, "reqq": 255 } # Response extended handshake self.sendExtendedMessage(0, hs_response) sleep(0.5) # Request metadata for i in range(0, 1 + metadata_size / (16 * 1024)): self.sendExtendedMessage(ut_metadata_id, { "msg_type": 0, "piece": i }) sleep(0.05) else: self.transport.loseConnection() elif ord(msg_data[0]) == 1: r, l = decode_dict(msg_data[1:], 0) if r["msg_type"] == 1: self._metadata[r["piece"]] = msg_data[l + 1:] metadata = reduce(lambda r, e: r + self._metadata[e], sorted(self._metadata.keys()), "") if len(metadata) == r["total_size"]: if sha1(metadata).digest() == self._info_hash: self._deferred.callback(bdecode(metadata)) # Abort connection anyway self.transport.abortConnection()
def handle_message(self, msg_data): if msg_data[0] == 0: hs_body = bdecode(msg_data[1:]) metadata_size = hs_body.get("metadata_size", 0) ut_metadata_id = hs_body.get("m", {}).get("ut_metadata", 0) if metadata_size and ut_metadata_id: hs_response = { "e": 0, "metadata_size": metadata_size, "v": "μTorrent 3.2.3", "m": { "ut_metadata": 1 }, "reqq": 255 } self.send_extended_message(0, hs_response) for i in range(0, int(1 + metadata_size / (16 * 1024))): self.send_extended_message(ut_metadata_id, { "msg_type": 0, "piece": i }) elif msg_data[0] == 1: r, l = decode_dict(msg_data[1:], 0) if r["msg_type"] == 1: self.metadata[r["piece"]] = msg_data[l + 1:] metadata = bytes() for key in sorted(self.metadata.keys()): metadata += self.metadata[key] if len(metadata) == r["total_size"]: if sha1(metadata).digest() == self.info_hash: result = bdecode(metadata) else: result = None if not self.result_future.done(): self.result_future.set_result(result) self.transport.close()
def extract(fname, out=""): tname = sub(fname, ".exe$", ".torrent") file = open(fname, "rb") data = file.read() file.close() i = 0 datafrom = "" while i < len(data) - 11: d = data[i:i + 11] if d == "d8:announce": datafrom = data[i:] break i += 1 decoded, length = decode_dict(datafrom, 0) datafrom = datafrom[:length] out = out or fname + ".torrent" out = open(out, "wb") out.write(datafrom) out.close()
def extract(fname, out=""): tname = sub(fname, ".exe$", ".torrent") file = open(fname, "rb") data = file.read() file.close() i = 0 datafrom = "" while i < len(data) - 11: d = data[i:i+11] if d == "d8:announce": datafrom = data[i:] break i += 1 decoded, length = decode_dict(datafrom, 0) datafrom = datafrom[:length] out = out or fname + ".torrent" out = open(out, "wb") out.write(datafrom) out.close()
def test_nested_dict(self): """ Test that a nested dict is decoded correctly. """ self.n = bencode.decode_dict("d3:keyd3:key5:valueee") self.assertEquals(self.n, {"key": {"key": "value"}})
def test_mixed_dict(self): """ Test that a dict with a list value is decoded correctly. """ self.n = bencode.decode_dict("d3:keyl1:a1:bee") self.assertEquals(self.n, {'key': ['a', 'b']})
def test_longer_dict(self): """ Test that a longer dict is decoded correctly. """ self.n = bencode.decode_dict("d5:key_17:value_15:key_27:value_2e") self.assertEquals(self.n, {"key_1": "value_1", "key_2": "value_2"})
def test_simple_dict(self): """ Test that a one key dict is decoded correctly. """ self.n = bencode.decode_dict("d3:key5:valuee") self.assertEquals(self.n, {"key": "value"})
def test_nested_dict(self): """ Test that a nested dict is decoded correctly. """ self.n = bencode.decode_dict("d3:keyd3:key5:valueee") self.assertEquals(self.n, {"key":{"key":"value"}})
def test_simple_dict(self): """ Test that a one key dict is decoded correctly. """ self.n = bencode.decode_dict("d3:key5:valuee") self.assertEquals(self.n, {"key":"value"})
def test_decode_dict(self): bstr = b'd2:id4:spam6:target4:eggse' # r, de_index = decode_list(bstr, 0) # self.assertListEqual([b'spam',b'eggs'], r) # self.assertEquals(14, de_index) self.assertEqual(({b"id":b"spam", b"target":b"eggs"}, 26), decode_dict(bstr, 0))
def def_nested_dict(self): exp = 'd4:spaml1:a1:bee' d = {'spam': ['a', 'b']} self.assertEqual(d, b.decode_dict(exp))
def test_reg_dict(self): exp = 'd3:cow3:moo4:spam4:eggse' d = {'cow': 'moo', 'spam': 'eggs'} self.assertEqual(d, b.decode_dict(exp))
def decodeBencode(self, myFileDump): myBencode = bencode.decode_dict(myFileDump, 0) return myBencode
def test_longer_dict(self): """ Test that a longer dict is decoded correctly. """ self.n = bencode.decode_dict("d5:key_17:value_15:key_27:value_2e") self.assertEquals(self.n, {"key_1":"value_1", "key_2":"value_2"})
def __load(self): self.__connect() try: # Send handshake message self.__send_handshake() # Wait for response data self.__read_handshake() time.sleep(0.1) self.__send_extended_handshake() # Read next message while True: msg = self.__read_message() if msg is not None: msg_id, msg_data = msg # Ignore all other messages except "extended" if msg_id != 20: continue def piece_iterator(metadata_size): return range(0, 1 + metadata_size / (16 * 1024)) e_msg_id = unpack("B", msg_data[0])[0] if e_msg_id == 0: extensions = bdecode(msg_data[1:]) if "m" in extensions and "ut_metadata" in extensions[ "m"] and "metadata_size" in extensions: time.sleep(0.1) self.__metadata_size = extensions["metadata_size"] ut_metadata_id = extensions["m"]["ut_metadata"] for i in piece_iterator(self.__metadata_size): self.__send_metadata_request(ut_metadata_id, i) elif e_msg_id == 1: response = msg_data[1:] r_dict, r_len = decode_dict(response, 0) self.__metadata[r_dict["piece"]] = response[r_len:] metadata = reduce(lambda a, e: a + self.__metadata[e], piece_iterator(self.__metadata_size), "") if len( metadata ) == self.__metadata_size and self.__on_metadata_loaded is not None: self.__on_metadata_loaded(metadata) return finally: self.__disconnect() if self.__on_finish is not None: self.__on_finish()