Downloading just the .torrent file from a magnet uri. Not sure what I'm actually downloading

jamieb picture jamieb · Mar 17, 2019 · Viewed 9.3k times · Source

Given a magnet file, I'm trying to get a .torrent file using the Python bindings for libtorrent.

#!/usr/bin/env python
import libtorrent as lt
import time
import sys
import random

ses = lt.session()
r = random.randrange(10000, 49000)
ses.listen_on(r, r+50)
print("Listening on ports %s - %s." % (r, r+50))
params = {
    'save_path': '.',
    'storage_mode': lt.storage_mode_t(2),
    'paused': False,
    'auto_managed': True,
    'duplicate_is_error': True,
    'file_priorities': [0]*5
    }

link = "magnet:?xt=urn:btih:209c8226b299b308beaf2b9cd3fb49212dbd13ec&dn=Tears+of+Steel&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Ftears-of-steel.torrent"

h = lt.add_magnet_uri(ses, link, params)
ses.add_extension('ut_metadata')
ses.add_extension('ut_pex')
ses.add_extension('metadata_transfer')
ses.add_dht_router("router.utorrent.com", 6881)
ses.add_dht_router("router.bittorrent.com", 6881)
ses.add_dht_router("dht.transmissionbt.com", 6881)
ses.add_dht_router("dht.aelitis.com", 6881)
ses.start_dht()
ses.start_lsd()
ses.start_upnp()
ses.start_natpmp()

while (not h.has_metadata()):
    time.sleep(1)
    status = ses.status()
    print("Seeking metadata for torrent (%s DHT nodes online)." %  status.dht_nodes)

torinfo = h.get_torrent_info()

torfile = lt.create_torrent(h.get_torrent_info())
f = open("torrentfile.torrent", "wb")
f.write(lt.bencode(torfile.generate()))
f.close()

Several minutes later the transfer is complete and I cat the results:

[me@localhost torrent]$ cat torrentfile.torrent 
d8:announce23:udp://explodie.org:696913:announce-listll23:udp://explodie.org:696934:udp://tracker.coppersurfer.tk:696931:udp://tracker.empire-js.us:133740:udp://tracker.leechers-paradise.org:696933:udp://tracker.opentrackr.org:133726:wss://tracker.btorrent.xyz25:wss://tracker.fastcast.nz32:wss://tracker.openwebtorrent.comee13:creation datei1552857262e4:info0:e[me@localhost torrent]$ 

The expected output is a binary .torrent file that contains all the file parts and hashes, etc. Some (possibly) relevant system info:

[me@localhost torrent]$ python --version
Python 2.7.14
[me@localhost torrent]$ python -c "import libtorrent; print libtorrent.version"
1.0.10.0
[me@localhost torrent]$ uname -a
Linux ip-172-31-53-167.ec2.internal 4.14.104-95.84.amzn2.x86_64 #1 SMP Sat Mar 2 00:40:20 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

Any suggestions would be appreciated. I'm using sample code that is practically identical to snippets that are claimed to work for others. Thank you.

Answer

Arvid picture Arvid · Mar 19, 2019

This looks like an ABI issue introduced in 1.0.10.

If you look at the changelog for 1.0.10, it introduced a new type for bencoded entries (preformatted). This was to preserve invalid key ordering in torrent files (to allow for re-encoding it and produce the same info-hash).

Unfortunately this broke the ABI with previous 1.0.x releases. I fixed this in the RC_1_0 branch, for a release in 1.0.12, but apparently this was never released.

In short, it looks like your python binding library is built with a version prior to 1.0.10, but your libtorrent library was 1.0.10 or later.

As long as the python bindings and the main library are from the same release of libtorrent, you should be good.