def test_list(self): self.assertEqual(bencode.encode([]), 'le') self.assertEqual(bencode.encode([ ['test', 2], [ ['foo'], [3] ] ]), 'll4:testi2eell3:fooeli3eeee')
def test_weird_msg(self): self.ping_d[m.ARGS] = [] assert_raises(m.MsgError, m.IncomingMsg, bencode.encode(self.ping_d)) self.ping_d[m.ARGS] = 1 assert_raises(m.MsgError, m.IncomingMsg, bencode.encode(self.ping_d)) self.ping_d[m.ARGS] = 'ZZZZ' assert_raises(m.MsgError, m.IncomingMsg, bencode.encode(self.ping_d))
def encode_ext(obj, encode_ext): if isinstance(obj, str): return bencode.encode(obj.encode("utf-8")) elif isinstance(obj, datetime.date): return bencode.encode(obj.toordinal()) else: return bencode.encode(obj, encode_ext)
def test_encode_unsupported_data_type(): """Try to encode unsupported object (a Python set)""" with pytest.raises(ValueError) as excinfo: bencode.encode(set()) assert str(excinfo.value) == ( "Cannot encode data: objects of type <class 'set'> are not supported.")
def render_GET(self, request): """ :type request: twisted.web.http.Request Take a request, do some some database work, return a peer list response. """ try: if not all(map(lambda x: x in request.args, ['info_hash', 'compact', 'port', 'peer_id'])): raise TorrentRegistryException('Not all arguments set') info_hash = request.args['info_hash'][0] compact = request.args['compact'][0].lower() not in ('0', 'false') ip = request.client.host port = int(request.args['port'][0]) peer_id = request.args['peer_id'][0] event = request.args.get('event', [''])[0] # TODO: process 'started', 'completed' and 'stopped' events if event == 'stopped': self.registry.remove_peer(info_hash, peer_id, ip, port) else: self.registry.add_peer(info_hash, peer_id, ip, port) return encode({ "interval": self.interval, "complete": 0, "incomplete": 0, "peers": self.registry.peer_list(info_hash, compact) }) except TorrentRegistryException, e: log.error(e.message) return encode({ 'failure reason': e.message })
def get(self): """ :type request: tornado.httputil.HTTPServerRequest Take a request, do some some database work, return a peer list response. """ try: if not all(map(lambda x: x in self.request.query_arguments, ['info_hash', 'compact', 'port', 'peer_id'])): raise TorrentRegistryException('Not all arguments set') info_hash = self.get_query_argument('info_hash') compact = self.get_query_argument('compact').lower() not in ('0', 'false') ip = self.request.remote_ip port = int(self.get_query_argument('port')) peer_id = self.get_query_argument('peer_id') event = self.request.args.get('event', [''])[0] # TODO: process 'started', 'completed' and 'stopped' events if event == 'stopped': self.registry.remove_peer(info_hash, peer_id, ip, port) else: self.registry.add_peer(info_hash, peer_id, ip, port) return encode({ "interval": self.interval, "complete": 0, "incomplete": 0, "peers": self.registry.peer_list(info_hash, compact) }) except TorrentRegistryException, e: log.error(e.message) return encode({ 'failure reason': e.message })
def test_error_dictionary_keys_arent_strings(): error = False try: encode({1:"a"}) except AssertionError as e: error = True assert error
def test_dict(self): self.assertEqual(bencode.encode({}), 'de') self.assertEqual(bencode.encode({ 'test': 12, 'foo': [ 'bar', {'test': ['again', 12]} ] }), 'd3:fool3:bard4:testl5:againi12eeee4:testi12ee')
def test_error_dictionary_keys_arent_strings(): error = False try: encode({1: "a"}) except AssertionError as e: error = True assert error
def test_weird_msg(self): self.ping_d[m.ARGS] = [] assert_raises(m.MsgError, m.IncomingMsg, Datagram(bencode.encode(self.ping_d), tc.CLIENT_ADDR)) self.ping_d[m.ARGS] = 1 assert_raises(m.MsgError, m.IncomingMsg, Datagram(bencode.encode(self.ping_d), tc.CLIENT_ADDR)) self.ping_d[m.ARGS] = 'ZZZZ' assert_raises(m.MsgError, m.IncomingMsg, Datagram(bencode.encode(self.ping_d), tc.CLIENT_ADDR))
def test_weird_msg(self): self.ping_d[m.ARGS] = [] assert_raises(m.MsgError, servers_msg_f.incoming_msg, Datagram(bencode.encode(self.ping_d), tc.CLIENT_ADDR)) self.ping_d[m.ARGS] = 1 assert_raises(m.MsgError, servers_msg_f.incoming_msg, Datagram(bencode.encode(self.ping_d), tc.CLIENT_ADDR)) self.ping_d[m.ARGS] = 'ZZZZ' assert_raises(m.MsgError, servers_msg_f.incoming_msg, Datagram(bencode.encode(self.ping_d), tc.CLIENT_ADDR))
def test_tid_error(self): # no TID del self.msg_d[m.TID] assert_raises(m.MsgError, m.IncomingMsg, bencode.encode(self.msg_d)) # invalid m.TID self.msg_d[m.TID] = 1 assert_raises(m.MsgError, m.IncomingMsg, bencode.encode(self.msg_d)) self.msg_d[m.TID] = [] assert_raises(m.MsgError, m.IncomingMsg, bencode.encode(self.msg_d)) self.msg_d[m.TID] = {} assert_raises(m.MsgError, m.IncomingMsg, bencode.encode(self.msg_d))
def test_sender_id(self): # no sender_id del self.ping_d[m.ARGS][m.ID] assert_raises(m.MsgError, m.IncomingMsg, bencode.encode(self.ping_d)) # bad ID self.ping_d[m.ARGS][m.ID] = 'a' assert_raises(m.MsgError, m.IncomingMsg, bencode.encode(self.ping_d)) self.ping_d[m.ARGS][m.ID] = 1 assert_raises(m.MsgError, m.IncomingMsg, bencode.encode(self.ping_d)) self.ping_d[m.ARGS][m.ID] = [] assert_raises(m.MsgError, m.IncomingMsg, bencode.encode(self.ping_d)) self.ping_d[m.ARGS][m.ID] = {} assert_raises(m.MsgError, m.IncomingMsg, bencode.encode(self.ping_d))
def test_type_error(self): # no TYPE del self.msg_d[m.TYPE] assert_raises(m.MsgError, m.IncomingMsg, bencode.encode(self.msg_d)) # invalid m.TYPE self.msg_d[m.TYPE] = 1 assert_raises(m.MsgError, m.IncomingMsg, bencode.encode(self.msg_d)) self.msg_d[m.TYPE] = [] assert_raises(m.MsgError, m.IncomingMsg, bencode.encode(self.msg_d)) self.msg_d[m.TYPE] = {} assert_raises(m.MsgError, m.IncomingMsg, bencode.encode(self.msg_d)) # unknown m.TYPE self.msg_d[m.TYPE] = 'z' assert_raises(m.MsgError, m.IncomingMsg, bencode.encode(self.msg_d))
def test_query(self): # no m.QUERY del self.ping_d[m.QUERY] assert_raises(m.MsgError, m.IncomingMsg, bencode.encode(self.ping_d)) # bad m.QUERY self.ping_d[m.QUERY] = 1 assert_raises(m.MsgError, m.IncomingMsg, bencode.encode(self.ping_d)) self.ping_d[m.QUERY] = [] assert_raises(m.MsgError, m.IncomingMsg, bencode.encode(self.ping_d)) self.ping_d[m.QUERY] = {} assert_raises(m.MsgError, m.IncomingMsg, bencode.encode(self.ping_d)) # unknown m.QUERY is not an error at this point # responder will process it and send an errror msg if necesary self.ping_d[m.QUERY] = 'a' m.IncomingMsg(bencode.encode(self.ping_d))
def test_tid_error(self): # no TID del self.msg_d[m.TID] assert_raises(m.MsgError, servers_msg_f.incoming_msg, Datagram(bencode.encode(self.msg_d), tc.CLIENT_ADDR)) # invalid m.TID self.msg_d[m.TID] = 1 assert_raises(m.MsgError, servers_msg_f.incoming_msg, Datagram(bencode.encode(self.msg_d), tc.CLIENT_ADDR)) self.msg_d[m.TID] = [] assert_raises(m.MsgError, servers_msg_f.incoming_msg, Datagram(bencode.encode(self.msg_d), tc.CLIENT_ADDR)) self.msg_d[m.TID] = {} assert_raises(m.MsgError, servers_msg_f.incoming_msg, Datagram(bencode.encode(self.msg_d), tc.CLIENT_ADDR))
def test_tid_error(self): # no TID del self.msg_d[m.TID] assert_raises(m.MsgError, m.IncomingMsg, Datagram(bencode.encode(self.msg_d), tc.CLIENT_ADDR)) # invalid m.TID self.msg_d[m.TID] = 1 assert_raises(m.MsgError, m.IncomingMsg, Datagram(bencode.encode(self.msg_d), tc.CLIENT_ADDR)) self.msg_d[m.TID] = [] assert_raises(m.MsgError, m.IncomingMsg, Datagram(bencode.encode(self.msg_d), tc.CLIENT_ADDR)) self.msg_d[m.TID] = {} assert_raises(m.MsgError, m.IncomingMsg, Datagram(bencode.encode(self.msg_d), tc.CLIENT_ADDR))
def encode(self, tid): self._lock.acquire() self._dict[TID] = tid result = bencode.encode(self._dict) del self._dict[TID] self._lock.release() return result
def _calc_info_hash(self): self.info_hash = None info_dict = self._torrent_decoded["info"] self.info_hash = hashlib.sha1(bencode.encode( info_dict)).hexdigest().upper() return(self.info_hash)
def _calc_info_hash(self): self.info_hash = None info_dict = self._torrent_decoded["info"] self.info_hash = hashlib.sha1( bencode.encode(info_dict)).hexdigest().upper() return (self.info_hash)
async def send_request_to_node( request: Dict[str, Any], ip: str, port: int, ) -> Any: """ Creates a connection a node and sends a given request to the node and returns the response :param port: port where node is serving :param ip: ip of node :param request: Dictionary of a request as specified in the Spec Document :return: node response """ reader, writer = await asyncio.open_connection(ip, port) writer.write(bencode.encode(request)) writer.write_eof() await writer.drain() data = b'' while 1: sockdata = await reader.read() if not sockdata: break data += sockdata reader.feed_eof() response = bencode.decode(data) if (response['status'] == 'ok'): logger.debug("sending OK") return response['response'] else: logger.debug("sending error") raise_network_error(response['error'])
def parse_bytes(content: bytes) -> dict: """Parse only needed values by this app from content of torrent file (.torrent) See: https://wiki.theory.org/index.php/BitTorrentSpecification#Metainfo_File_Structure Args: content (bytes): binary content of torrent file Returns: dict: with following keys * 'name': str * 'info_hash': str (hexadecimal values), * 'tracker_urls': list * 'creation_date': datetime.datetime * 'length': integer, number of bytes with 1024 convention (for kilo,...) """ decoded_content = bencode.decode(content) return_dict = {} return_dict['name'] = decoded_content['info']['name'] return_dict['info_hash'] = hashlib.sha1( bencode.encode(decoded_content['info'])).hexdigest() announce_list = [] announce_list.append(decoded_content.get('announce')) if "announce-list" in decoded_content: announce_list.extend([ url for urls in decoded_content.get('announce-list') for url in urls ]) tracker_urls = [ extract_tracker_url_from_announce(url) for url in announce_list if url ] tracker_urls = [ url_split for url_split in tracker_urls if url_split.scheme and url_split.netloc ] return_dict['tracker_urls'] = tracker_urls if "creation date" in decoded_content: return_dict['creation_date'] = datetime.datetime.fromtimestamp( int(decoded_content['creation date'])) if "length" in decoded_content['info']: return_dict['size'] = int(decoded_content['info']['length']) if "files" in decoded_content['info']: for file_info in decoded_content['info']['files']: if "length" in file_info: if 'size' in return_dict: return_dict['size'] += int(file_info['length']) else: return_dict['size'] = int(file_info['length']) return return_dict
def __init__(self, hash, torrent_dir): self.hash = hash self.torrent_dir = torrent_dir if not self.get_from_url() and not self.get_from_file(): raise Exception( "Could not find a torrent with this hash on the tracker or in the torrent directory:" + str(self.torrent_dir)) with open(torrent_dir + hash + '.torrent', 'rb') as file: contents = file.read() self.torrentFile = bencode.decode(contents) self.totalLength = 0 self.pieceLength = self.torrentFile['info']['piece length'] self.pieces = self.torrentFile['info']['pieces'] self.info_hash = utils.sha1_hash( bencode.encode(self.torrentFile['info'])) self.peer_id = self.generate_peer_id() self.announceList = self.getTrakers() self.fileNames = [] self.get_files() if self.totalLength % self.pieceLength == 0: self.numberOfPieces = self.totalLength / self.pieceLength else: self.numberOfPieces = int(self.totalLength / self.pieceLength) + 1 logging.debug(self.announceList) logging.debug(self.fileNames) assert (self.totalLength > 0) assert (len(self.fileNames) > 0)
def create_torrent(tracker, file): be_dict = {'announce': tracker} name = file.split("\\")[-1] size = os.path.getsize(file) # Default piece length is 512kB. piece_length = (2**9) * 1000 pieces = sha1_file(file, piece_length) # info dictionary. info_dict = { 'length': size, 'name': name, 'piece length': piece_length, 'pieces': pieces } be_dict['info'] = info_dict be = bencode.encode(be_dict) torrent_path = file + ".torrent" # bencode.bwrite(be, torrent_path) with open(torrent_path, 'wb') as torrent_file: torrent_file.write(be)
def handshake(self, conn): host_exts = set(peer.extensions[k] for k in ["commands"]) peer_exts = conn.handshake(info_hash=self.info_hash, host_id=self.host_id, extensions=host_exts) assert host_exts.issubset(peer_exts) obj = OrderedDict(m=peer.extended_commands) conn.send_cmd("extended", cmd=0, msg=bencode.encode(obj))
def setUp(self): """ Write a little bencoded data to a file. """ self.filename = "test.txt" self.data = bencode.encode([1, 2, 3]) with open(self.filename, "w") as self.file: self.file.write(self.data)
async def send_request_to_tracker( request: Dict[str, Any], ip: str, port: int, ) -> Dict[str, Any]: """ Creates a connection with the tracker and sends a given request to the tracker and returns the response :param port: port where tracker is serving :param ip: ip of tracker :param request: ['POST'/'GET', node_id|drop_id, data] :return: tracker response """ reader, writer = await asyncio.open_connection(ip, port) writer.write(bencode.encode(request)) writer.write_eof() await writer.drain() response = b'' while 1: data = await reader.read() if not data: break else: response += data reader.feed_eof() return bencode.decode(response)
def __init__(self, filename): metafile = open(filename, 'rb') try: self._metainfo = debencode.decode(metafile.read()) except Exception: raise ValueError("Invalid BitTorrent metainfo file format") if 'announce' not in self._metainfo or 'info' not in self._metainfo: raise ValueError("Invalid BitTorrent metainfo file format") info = self._metainfo['info'] if ('piece length' not in info or 'pieces' not in info or 'name' not in info): raise ValueError("Invalid BitTorrent metainfo file format") try: if 'length' in info: # Single file mode self._directory = '../result/' self._files = [([info['name']], info['length'])] self._length = info['length'] else: # Multi file mode self._directory = info['name'] self._files = [(d['path'], d['length']) for d in self._metainfo['info']['files']] self._length = sum([length for (_, length) in self._files]) except: raise ValueError("Invalid BitTorrent metainfo file format") self._hash = hashlib.sha1(bencode.encode(info)).digest() self._num_pieces = len(self._metainfo['info']['pieces'])/20
def test_encodeInt(self): """ bencode a random number of integers (fewer than 100), with random values (less than one million) and ensure that the encoding gives us the proper result """ for i in range(0, 100): num = random.randint(0,1000000) self.assertEqual(bencode.encode(num), "".join(['i', str(num), 'e']))
def __init__(self, torrent_file, target_file, port = PEER_PORT, error_handler = None, tracker_retry_time = consts['TRACKER_RETRY_TIME']): self.running = False self.is_downloading = False self.completed = False self.paused = False self.peer_port = port self.error_handler = error_handler self.tracker_retry_time = tracker_retry_time self.data = read_torrent_file(torrent_file) self.info_hash = sha1(encode(self.data["info"])).digest() self.peer_id = generate_peer_id() self.handshake = generate_handshake(self.info_hash, self.peer_id) self.tracker_thread = None # check is seed self.target_file = target_file self.storage = Storage(self.data['info']) self.piece_num = self.storage.piece_num print 'piece_num:', self.piece_num import os if os.path.exists(target_file): self.storage.set_file(target_file) self.picker = PiecePicker(self) self.selector = PeerSelector(self) self.downloading = [] self.count_received = {}
def get_torrent_file(self) -> str: """ 因为qbt的API中没有返回种子所在位置,只能通过 'export_dir_fin' 和 'export_dir' 设置值搜索可能存在的种子, 并通过计算 info_hash 进行确认 """ logger.info('正在搜索 %s ( info_hash: %s ) 的种子文件', self.torrent_name, self.info_hash) test_paths = [ os.path.join(self.qbt_preference.get('export_dir_fin'), '{}.torrent'.format(self.torrent_name)), os.path.join(self.qbt_preference.get('export_dir'), '{}.torrent'.format(self.torrent_name)), os.path.join(self.qbt_preference.get('export_dir_fin'), '*.torrent'), os.path.join(self.qbt_preference.get('export_dir'), '*.torrent'), ] for test_path in test_paths: test_path_glob = glob(test_path) for test_file in test_path_glob: data = bencode.bread(test_file) test_info_hash = hashlib.sha1(bencode.encode(data['info'])).hexdigest() logger.debug('测试种子 %s ,其info_hash为 %s', test_file, test_info_hash) if test_info_hash == self.info_hash: # 说明该种子文件的info_hash值与想要发布的种子info_hash值相同 logger.info('获得种子 "%s" (info_hash: %s) 的种子位置 %s', self.torrent_name, self.info_hash, test_file) self.torrent_file_path = test_file return self.torrent_file_path # 说明未搜索到,抛出错误 raise AutoseedStopException('在种子保存目录中未搜索到 %s (info_hash: %s ) 的种子,你是否未设置 种子保存位置 ??' % (self.torrent_name, self.info_hash))
def make_torrent_file(file=None, tracker=None, comment=None): """ Returns the bencoded contents of a torrent file. """ if not file: raise TypeError( "make_torrent_file requires at least one file, non given.") if not tracker: raise TypeError( "make_torrent_file requires at least one tracker, non given.") torrent = {} # We only have one tracker, so that's the announce if type(tracker) != list: torrent["announce"] = tracker # Multiple trackers, first is announce, and all go in announce-list elif type(tracker) == list: torrent["announce"] = tracker[0] # And for some reason, each needs its own list torrent["announce-list"] = [[t] for t in tracker] torrent["creation date"] = int(time()) torrent["created by"] = CLIENT_NAME if comment: torrent["comment"] = comment torrent["info"] = make_info_dict(file) return encode(torrent)
def make_torrent_file(file = None, tracker = None, comment = None): """ Returns the bencoded contents of a torrent file. """ if not file: raise TypeError("make_torrent_file requires at least one file, non given.") if not tracker: raise TypeError("make_torrent_file requires at least one tracker, non given.") torrent = {} # We only have one tracker, so that's the announce if type(tracker) != list: torrent["announce"] = tracker # Multiple trackers, first is announce, and all go in announce-list elif type(tracker) == list: torrent["announce"] = tracker[0] # And for some reason, each needs its own list torrent["announce-list"] = [[t] for t in tracker] torrent["creation date"] = int(time()) torrent["created by"] = CLIENT_NAME if comment: torrent["comment"] = comment torrent["info"] = make_info_dict(file) return encode(torrent)
async def verify_signed_dictionary( public_key: rsa.RSAPublicKey, signature: bytes, dictionary: Dict[str, Any], ) -> None: """ Returns None if success, else throws cryptography.exceptions.InvalidSignature :param public_key: RSA public_key :param signature: the signature of the dictionary :param dictionary: the actual dictionary :raises VerificationException: If the verification fails :return: None """ verifier = public_key.verifier( signature, padding.PSS( mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH, ), hashes.SHA256(), ) verifier.update(await hash(bencode.encode(dictionary))) try: verifier.verify() except InvalidSignature: raise VerificationException()
def get_info_hash(torrent): info = encode(torrent['info']) encoded_hash = sha1(info).digest() # print("orig", torrent['info']) # print("encoded", info) return encoded_hash
def send_request(request): """ Sends message to backend over socket connection and waits for a response :param request: dictionary of info to be sent to backend """ # Convert dictionary to send-able type data_string = bencode.encode(request) op_sys = platform.system() try: if op_sys == 'Windows': response_string = _tcp_send_message(data_string) else: response_string = _unix_send_message(data_string) except socket.timeout: response = { 'status': 'error', 'message': 'Connection Timeout. Check Backend Status', } return response except socket.error: response = { 'status': 'error', 'message': 'Backend Communication Error', } return response response = bencode.decode(response_string) return response
def __init__(self, info, location, file_path, tracker, block_size=16384): self.name = info['name'] self.download_dir = location self.file = FileInfo.FileInfo(file_path) self.downloaded = 0 self.uploaded = 0 if tracker is not None: self.tracker = tracker self.piece_size = info['piece length'] self.block_size = block_size self.piece_count = ceil(self.file.size / self.piece_size) # string of 20-byte hash values of each piece. self.piece_hashes = info['pieces'] self.urlInfoHash = sha1(bencode.encode(info)).digest() self.safeUrl = urllib.parse.quote(self.urlInfoHash) # list of length piece_size. self.piece_verified = None # Matrix of dimensions [piece_size][piece_size / block_size] self.block_verified = None
def tracker(request): """Peer communication access point""" res = {} try: if request.method == 'GET': data = request.GET.copy() print "Tracker: " print data.get('info_hash','').upper().encode('utf-8').encode('hex') #print Share.objects.first().info_hash data['info_hash'] = data.get('info_hash','').upper().encode('utf-8').encode('hex') plrf = PeerListRequestForm(data) if plrf.is_valid(): qs = plrf.process() res['peers'] = [{ 'peer id':i.peer_id, 'ip':i.peer_ip, 'port':i.peer_port } for i in qs if i.is_online() ] res['interval'] = 300 else: raise Http404() except Http404: res['failure reason'] = 'poorly formed request' resb = encode(res) print resb return HttpResponse(resb, content_type="text/plain")
def get_the_hash(self): # Open torrent file torrent_file = open(self.filepath, "rb") metainfo = bencode.decode(torrent_file.read()) info = metainfo['info'] thehash = hashlib.sha1(bencode.encode(info)).hexdigest().upper() logger.info('Hash: %s' % thehash) return thehash
def get_the_hash(self, filepath): # Open torrent file torrent_file = open(filepath, "rb") metainfo = bencode.decode(torrent_file.read()) info = metainfo['info'] thehash = hashlib.sha1(bencode.encode(info)).hexdigest().upper() logger.fdebug('Hash: ' + thehash) return thehash
def __init__(self, filename): self.filename = filename with open(self.filename, 'rb') as f: meta_info = f.read() self.meta_info = bencode.decode(meta_info) # main meta file info info = bencode.encode(self.meta_info['info']) self.info_hash = sha1(info).digest() # info_hash for HTTP GET request
def encode_peerlist(peerlist: List[Tuple[Any, str, int]], ) -> bytes: """ encodes peerlist into bytes to put in dht :param peerlist: list of dht peers :return: bytes of encoded peerlist """ return encode_peerlist_prefix + bencode.encode(list(peerlist))
def __init__(self, torrent_file): self.running = False self.data = read_torrent_file(torrent_file) self.info_hash = sha1(encode(self.data["info"])).digest() self.peer_id = generate_peer_id() self.handshake = generate_handshake(self.info_hash, self.peer_id)
def sign(message): key = config.get("network-key") if b"sig" in message: del message[b"sig"] data = bencode.encode(message) sig = hmac.digest(key, data, "sha256") message[b"sig"] = sig return message
async def encode(self) -> bytes: """Encode the full drop metadata file, including files, to bytes :return: The bencoded full metadata file """ h = await self.header h["files"] = self.files return bencode.encode(h)
def _calc_info_hash(self): self.info_hash = None if "info" in self._torrent_decoded.keys(): info_encoded = bencode.encode(self._torrent_decoded["info"]) if info_encoded: self.info_hash = hashlib.sha1(info_encoded).hexdigest().upper() return(self.info_hash)
def test_encodeSimpleDict(self): unencodedDict = {"first":"string","second":10} encodedDict = "d5:first6:string6:secondi10ee" result = bencode.encode(unencodedDict) self.assertEqual(result[0], 'd') self.assertEqual(result[-1], 'e') self.assertTrue("5:first6:string" in result) self.assertTrue("6:secondi10e" in result) self.assertEqual(len(encodedDict), len(result))
def test_sender_id(self): # no sender_id del self.ping_d[m.ARGS][m.ID] assert_raises(m.MsgError, servers_msg_f.incoming_msg, Datagram(bencode.encode(self.ping_d), tc.CLIENT_ADDR)) # bad ID self.ping_d[m.ARGS][m.ID] = 'a' assert_raises(m.MsgError, servers_msg_f.incoming_msg, Datagram(bencode.encode(self.ping_d), tc.CLIENT_ADDR)) self.ping_d[m.ARGS][m.ID] = 1 assert_raises(m.MsgError, servers_msg_f.incoming_msg, Datagram(bencode.encode(self.ping_d), tc.CLIENT_ADDR)) self.ping_d[m.ARGS][m.ID] = [] assert_raises(m.MsgError, servers_msg_f.incoming_msg, Datagram(bencode.encode(self.ping_d), tc.CLIENT_ADDR)) self.ping_d[m.ARGS][m.ID] = {} assert_raises(m.MsgError, servers_msg_f.incoming_msg, Datagram(bencode.encode(self.ping_d), tc.CLIENT_ADDR))
def __init__(self, torrent_file,CLIENT_ID = CLIENT_ID): self.running = False self.data = read_torrent_file(torrent_file) self.info_hash = sha1(encode(self.data["info"])).digest() self.peer_id = generate_peer_id() self.handshake = generate_handshake(self.info_hash, self.peer_id) print 'DEBUG: Torrent: __init__: self.handshake: ', self.handshake
def test_query(self): # no m.QUERY del self.ping_d[m.QUERY] assert_raises(m.MsgError, servers_msg_f.incoming_msg, Datagram(bencode.encode(self.ping_d), tc.CLIENT_ADDR)) # bad m.QUERY self.ping_d[m.QUERY] = 1 assert_raises(m.MsgError, servers_msg_f.incoming_msg, Datagram(bencode.encode(self.ping_d), tc.CLIENT_ADDR)) self.ping_d[m.QUERY] = [] assert_raises(m.MsgError, servers_msg_f.incoming_msg, Datagram(bencode.encode(self.ping_d), tc.CLIENT_ADDR)) self.ping_d[m.QUERY] = {} assert_raises(m.MsgError, servers_msg_f.incoming_msg, Datagram(bencode.encode(self.ping_d), tc.CLIENT_ADDR)) # unknown m.QUERY is not an error at this point # responder will process it and send an errror msg if necesary self.ping_d[m.QUERY] = 'a' servers_msg_f.incoming_msg(Datagram(bencode.encode(self.ping_d), tc.CLIENT_ADDR))
def test_type_error(self): # no TYPE del self.msg_d[m.TYPE] assert_raises(m.MsgError, servers_msg_f.incoming_msg, Datagram(bencode.encode(self.msg_d), tc.CLIENT_ADDR)) # invalid m.TYPE self.msg_d[m.TYPE] = 1 assert_raises(m.MsgError, servers_msg_f.incoming_msg, Datagram(bencode.encode(self.msg_d), tc.CLIENT_ADDR)) self.msg_d[m.TYPE] = [] assert_raises(m.MsgError, servers_msg_f.incoming_msg, Datagram(bencode.encode(self.msg_d), tc.CLIENT_ADDR)) self.msg_d[m.TYPE] = {} assert_raises(m.MsgError, servers_msg_f.incoming_msg, Datagram(bencode.encode(self.msg_d), tc.CLIENT_ADDR)) # unknown m.TYPE self.msg_d[m.TYPE] = 'z' assert_raises(m.MsgError, servers_msg_f.incoming_msg, Datagram(bencode.encode(self.msg_d), tc.CLIENT_ADDR))
def get_the_hash(self, filepath): import hashlib, StringIO import bencode # Open torrent file torrent_file = open(filepath, "rb") metainfo = bencode.decode(torrent_file.read()) info = metainfo['info'] thehash = hashlib.sha1(bencode.encode(info)).hexdigest().upper() return thehash