Exemple #1
0
 def test_dict(self):
   self.assertEqual({'a':2}, bdecode('d1:ai2ee'))
   self.assertEqual({'b':[1,2]}, bdecode('d1:bli1ei2eee'))
   
   self.assertEqual({'cow':'moo', 'spam':'eggs'}, bdecode('d3:cow3:moo4:spam4:eggse'))
   self.assertEqual({'spam':['a', 'b']}, bdecode('d4:spaml1:a1:bee'))
   self.assertEqual({'publisher':'bob', 'publisher-webpage':'www.example.com', 'publisher.location':'home' }, bdecode('d9:publisher3:bob17:publisher-webpage15:www.example.com18:publisher.location4:homee'))
Exemple #2
0
 def test_list(self):
   self.assertEqual(['a', 'c', 'e'], bdecode('l1:a1:c1:ee'))
   self.assertEqual([1,2,3], bdecode('li1ei2ei3ee'))
   self.assertEqual([1,'a',3], bdecode('li1e1:ai3ee'))
   self.assertEqual([[1,2],['a','b']], bdecode('lli1ei2eel1:a1:bee'))
   
   self.assertEqual(['spam', 'eggs'], bdecode('l4:spam4:eggse'))
Exemple #3
0
    def test_list(self):
        self.assertEqual(['a', 'c', 'e'], bdecode('l1:a1:c1:ee'))
        self.assertEqual([1, 2, 3], bdecode('li1ei2ei3ee'))
        self.assertEqual([1, 'a', 3], bdecode('li1e1:ai3ee'))
        self.assertEqual([[1, 2], ['a', 'b']], bdecode('lli1ei2eel1:a1:bee'))

        self.assertEqual(['spam', 'eggs'], bdecode('l4:spam4:eggse'))
Exemple #4
0
    def clean_torrent(self):
        torrent = self.cleaned_data["torrent"]

        # Check that the torrent is actually a torrent file and set the info_hash
        _, ext = os.path.splitext(torrent.name)
        if ext != '.torrent':
            raise forms.ValidationError('File must end with .torrent')

        try:
            data = bdecode(torrent.read())
        except ValueError:
            raise forms.ValidationError('Problem parsing torrent file')
        if 'info' not in data:
            raise forms.ValidationError('Info dict not in torrent file')

        #Verify uniqueness
        the_hash = hashlib.sha1(bencode(data['info'])).hexdigest()
        if Torrent.objects.filter(info_hash=the_hash).count() != 0:
            raise forms.ValidationError('Torrent already exists [%s]' %
                                        the_hash)

        #encode the name
        torrent.name = '%s.torrent' % hashlib.sha1(
            the_hash + settings.SECRET_KEY).hexdigest()

        return torrent
Exemple #5
0
    def __init__(self, filename, client_id):
        '''Opens file with context manager'''
        self.client_id = client_id
        self.peers = {}
        self._cached_messages = {}
        self._trackers = set()

        with io.open(filename, 'rb') as f:
            self._data = bdecode(f)

        # just so this init function doesn't get any bigger...
        self._calculate_properties()
        self._file_handler = FileHandler(self.query('name'), self.files,
                                         [p['length'] for p in self.pieces],
                                         self.piece_hashes)

        self._message_dispatch = {
            messages.Handshake: self._handshake_maker,
            messages.Bitfield: self._bitfield_maker
            }

        self._message_handlers = {
            messages.INCOMING: {
                messages.Have:
                lambda msg: self._increment_frequency(msg.index),

                messages.Bitfield: self._process_bitfield,
                messages.Piece: lambda m: self.file_handler.write(*m.payload)
                },
            messages.OUTGOING: {
                }
            }

        self._exception_handlers = {}
    async def announce(self, event: TrackerEvent):
        params = {
            'info_hash':
            urllib.parse.quote(self.file.info_hash),
            'peer_id':
            self.peer_id,
            'port':
            self.server_port,
            'uploaded':
            self.session.uploaded,
            'downloaded':
            self.file.pieces_completed * self.file.piece_size,
            'remaining':
            self.file.file_size -
            self.file.pieces_completed * self.file.piece_size,
            'compact':
            1,
            'event':
            event.name,
        }
        if self.tracker_id:
            params['trackerid'] = self.tracker_id

        url = f"{self.announce_url}?{urllib.parse.urlencode(params)}"
        try:
            timeout = aiohttp.ClientTimeout(total=REQUEST_TIMEOUT)
            async with aiohttp.ClientSession(timeout=timeout) as session:
                async with session.get(url) as response:
                    resp_bytes = await response.read()

            data, _ = bdecode(resp_bytes.decode('utf-8'), strict=False)
            if 'failure reason' in data:
                raise ValueError(data['failure reason'])
            elif 'warning message' in data:
                # LOG WARNING MESSAGE
                pass

            if isinstance(data['peers'], dict):
                peers = [(entry['ip'], entry['port'])
                         for entry in data['peers'].items()]
            else:
                # In compact mode peers is string consisting of ip & port only.  I.e.:
                # ip,port,ip,port,...

                data['peers'] = data['peers'].encode('utf-8')
                if not len(data['peers']) % 6 == 0:
                    raise ValueError()  # LOG
                peers = list(struct.iter_unpack(
                    "!IH", data['peers']))  # List[(ip: int, port: int)]

            self.tracker_id = data['tracker id']
            return data['interval'], peers

        except asyncio.TimeoutError:
            raise ConnectionAbortedError()  # TODO: Log
        except Exception as e:
            raise e  # TODO: Log
Exemple #7
0
    def test_dict(self):
        self.assertEqual({'a': 2}, bdecode('d1:ai2ee'))
        self.assertEqual({'b': [1, 2]}, bdecode('d1:bli1ei2eee'))

        self.assertEqual({
            'cow': 'moo',
            'spam': 'eggs'
        }, bdecode('d3:cow3:moo4:spam4:eggse'))
        self.assertEqual({'spam': ['a', 'b']}, bdecode('d4:spaml1:a1:bee'))
        self.assertEqual(
            {
                'publisher': 'bob',
                'publisher-webpage': 'www.example.com',
                'publisher.location': 'home'
            },
            bdecode(
                'd9:publisher3:bob17:publisher-webpage15:www.example.com18:publisher.location4:homee'
            ))
Exemple #8
0
    def handle_response(self, response):
        '''Parses response,  updates tracker data,  raises appropriate event'''

        info = bdecode(io.BytesIO(response.content))

        if 'failure reason' in info or 'warning message' in info:
            self.handle_event(events.TrackerFailure(tracker=self, info=info))
        else:
            old_peers = set(self.peer_addresses)
            self.data.update(info)
            new_peers = set(self.peer_addresses) - old_peers

            self.handle_event(events
                              .TrackerResponse(tracker=self,
                                               new_peer_addresses=new_peers))
Exemple #9
0
def download_torrent(request, object_id):
  torrent = get_object_or_404(Torrent, pk=object_id)
  
  #load the file into memory
  data = torrent.torrent.read()
  decoded_data = bdecode(data)
  
  #set the tracker, reverse announce url
  announce_url = 'http://%s%s' % (Site.objects.get_current().domain, reverse('tracker.views.announce'))
  decoded_data['announce'] = announce_url
  
  #generate a response with correct mimetype and file as the attachment
  response = HttpResponse(mimetype='application/x-bittorrent')
  response['Content-Disposition'] = 'attachment; filename=%s.torrent' % torrent.info_hash
  response.write(bencode(decoded_data))
  
  return response
Exemple #10
0
def download_torrent(request, object_id):
    torrent = get_object_or_404(Torrent, pk=object_id)

    #load the file into memory
    data = torrent.torrent.read()
    decoded_data = bdecode(data)

    #set the tracker, reverse announce url
    announce_url = 'http://%s%s' % (Site.objects.get_current().domain,
                                    reverse('tracker.views.announce'))
    decoded_data['announce'] = announce_url

    #generate a response with correct mimetype and file as the attachment
    response = HttpResponse(mimetype='application/x-bittorrent')
    response[
        'Content-Disposition'] = 'attachment; filename=%s.torrent' % torrent.info_hash
    response.write(bencode(decoded_data))

    return response
Exemple #11
0
 def clean_torrent(self):
   torrent = self.cleaned_data["torrent"]
   
   # Check that the torrent is actually a torrent file and set the info_hash
   _, ext = os.path.splitext(torrent.name)
   if ext != '.torrent':
     raise forms.ValidationError('File must end with .torrent')
   
   try:
     data = bdecode(torrent.read())
   except ValueError:
     raise forms.ValidationError('Problem parsing torrent file')
   if 'info' not in data:
     raise forms.ValidationError('Info dict not in torrent file')
   
   #Verify uniqueness
   the_hash = hashlib.sha1(bencode(data['info'])).hexdigest()
   if Torrent.objects.filter(info_hash=the_hash).count() != 0:
     raise forms.ValidationError('Torrent already exists [%s]' % the_hash)
   
   #encode the name
   torrent.name = '%s.torrent' % hashlib.sha1(the_hash + settings.SECRET_KEY).hexdigest()
   
   return torrent
Exemple #12
0
 def test_reciprical(self):
   for i in xrange(100):
     element = self.rand_element()
     self.assertEqual(bdecode(bencode(element)), element)
Exemple #13
0
 def test_str(self):
   self.assertEqual('abc', bdecode('3:abc'))
   self.assertEqual('aasdfbc', bdecode('7:aasdfbc'))
   
   self.assertEqual('spam', bdecode('4:spam'))
Exemple #14
0
 def test_reciprical(self):
     for i in xrange(100):
         element = self.rand_element()
         self.assertEqual(bdecode(bencode(element)), element)
Exemple #15
0
    def test_int(self):
        self.assertEqual(1, bdecode('i1e'))
        self.assertEqual(1832, bdecode('i1832e'))

        self.assertEqual(3, bdecode('i3e'))
Exemple #16
0
    def test_str(self):
        self.assertEqual('abc', bdecode('3:abc'))
        self.assertEqual('aasdfbc', bdecode('7:aasdfbc'))

        self.assertEqual('spam', bdecode('4:spam'))
Exemple #17
0
            raise Exception # trouver mieux?
        self.msg_dict = {'len': msg_len, 'id': msg_id, 'payload': msg_payload}

        def send(self):
            msg_send = self.msg_dict['len']
            msg_send += self.msg_dict.get('id', '')
            msg_send += self.sg_dict.get('payload', '')
            return ''.join(self.msg_dict.values) # PROBLEME D'ORDRE... GROS PBME... LIST?
            return msg_send



if __name__ == '__main__':
    import utils
    import io

    with io.open('flagfromserver.torrent', 'rb') as iostream:
        tom_torrent = Torrent(utils.bdecode(iostream))
    print(tom_torrent.tracker_info)
    print(tom_torrent.info_hash)
    print(tom_torrent.request_tracker())
    peers = tom_torrent.get_peers()
    print(peers)
    print(tom_torrent._handshake(('96.126.104.219', 62859)))

    # user repr!
    # ord and chr
    # see as number
    # check struct
    # x.decode / encode
Exemple #18
0
 def test_int(self):
   self.assertEqual(1, bdecode('i1e'))
   self.assertEqual(1832, bdecode('i1832e'))
   
   self.assertEqual(3, bdecode('i3e'))