summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCalum Lind <calumlind+deluge@gmail.com>2022-01-08 18:54:15 +0000
committerCalum Lind <calumlind+deluge@gmail.com>2022-01-08 19:43:40 +0000
commite50927f5759bc4752baf231ad464f34852587822 (patch)
treeac3b37f1770595073686b9fec777b1ebb78fe610
parent79b7e6093f42de5a2dbf429f781fd3606a8f9e2e (diff)
downloaddeluge-e50927f5759bc4752baf231ad464f34852587822.tar.gz
deluge-e50927f5759bc4752baf231ad464f34852587822.tar.bz2
deluge-e50927f5759bc4752baf231ad464f34852587822.zip
[GTK] Fix unable to prefetch magnet in thinclient
A UnicodeDecodeError is raised in transfer module when attempting to prefetch a magnet. This is result of passing a Python dict containing text bytes and raw bytes that cannot be decoded as utf-8 in rencode when recieving the message. This could be handled in rencode by returning raw bytes if decoding fails (perhaps with a strict mode?) however better to follow convention of encoding raw bytes in base64 in API calls. Fixed by retaining bencoding and encoding with base64 when sending result. Resolves: https://github.com/deluge-torrent/deluge/pull/334
-rw-r--r--deluge/core/core.py4
-rw-r--r--deluge/core/torrentmanager.py7
-rw-r--r--deluge/tests/test_core.py2
-rw-r--r--deluge/tests/test_torrentmanager.py63
-rw-r--r--deluge/ui/gtk3/addtorrentdialog.py4
5 files changed, 45 insertions, 35 deletions
diff --git a/deluge/core/core.py b/deluge/core/core.py
index 4fa75a414..0563318a5 100644
--- a/deluge/core/core.py
+++ b/deluge/core/core.py
@@ -432,12 +432,14 @@ class Core(component.Component):
Used by UIs to get magnet files for selection before adding to session.
+ The metadata is bencoded and for transfer base64 encoded.
+
Args:
magnet (str): The magnet URI.
timeout (int): Number of seconds to wait before canceling request.
Returns:
- Deferred: A tuple of (torrent_id (str), metadata (dict)) for the magnet.
+ Deferred: A tuple of (torrent_id (str), metadata (str)) for the magnet.
"""
diff --git a/deluge/core/torrentmanager.py b/deluge/core/torrentmanager.py
index 1a12fbc9f..1bc05365c 100644
--- a/deluge/core/torrentmanager.py
+++ b/deluge/core/torrentmanager.py
@@ -13,6 +13,7 @@ import operator
import os
import pickle
import time
+from base64 import b64encode
from collections import namedtuple
from tempfile import gettempdir
@@ -396,12 +397,12 @@ class TorrentManager(component.Component):
else:
self.session.remove_torrent(torrent_handle, 1)
- metadata = None
+ metadata = b''
if isinstance(torrent_info, lt.torrent_info):
log.debug('prefetch metadata received')
- metadata = lt.bdecode(torrent_info.metadata())
+ metadata = torrent_info.metadata()
- return torrent_id, metadata
+ return torrent_id, b64encode(metadata)
def _build_torrent_options(self, options):
"""Load default options and update if needed."""
diff --git a/deluge/tests/test_core.py b/deluge/tests/test_core.py
index f33f60c4c..f24fb2e0d 100644
--- a/deluge/tests/test_core.py
+++ b/deluge/tests/test_core.py
@@ -317,7 +317,7 @@ class CoreTestCase(BaseTestCase):
def test_prefetch_metadata_existing(self):
"""Check another call with same magnet returns existing deferred."""
magnet = 'magnet:?xt=urn:btih:ab570cdd5a17ea1b61e970bb72047de141bce173'
- expected = ('ab570cdd5a17ea1b61e970bb72047de141bce173', None)
+ expected = ('ab570cdd5a17ea1b61e970bb72047de141bce173', b'')
def on_result(result):
self.assertEqual(result, expected)
diff --git a/deluge/tests/test_torrentmanager.py b/deluge/tests/test_torrentmanager.py
index d719889ba..f22f5be8b 100644
--- a/deluge/tests/test_torrentmanager.py
+++ b/deluge/tests/test_torrentmanager.py
@@ -15,6 +15,7 @@ from twisted.internet import defer, task
from twisted.trial import unittest
from deluge import component
+from deluge.bencode import bencode
from deluge.common import windows_check
from deluge.core.core import Core
from deluge.core.rpcserver import RPCServer
@@ -82,34 +83,38 @@ class TorrentmanagerTestCase(BaseTestCase):
expected = (
'ab570cdd5a17ea1b61e970bb72047de141bce173',
- {
- b'piece length': 32768,
- b'sha1': (
- b'2\xce\xb6\xa8"\xd7\xf0\xd4\xbf\xdc^K\xba\x1bh'
- b'\x9d\xc5\xb7\xac\xdd'
- ),
- b'name': b'azcvsupdater_2.6.2.jar',
- b'private': 0,
- b'pieces': (
- b"\xdb\x04B\x05\xc3'\xdab\xb8su97\xa9u"
- b'\xca<w\\\x1ef\xd4\x9b\x16\xa9}\xc0\x9f:\xfd'
- b'\x97qv\x83\xa2"\xef\x9d7\x0by!\rl\xe5v\xb7'
- b'\x18{\xf7/"P\xe9\x8d\x01D\x9e8\xbd\x16\xe3'
- b'\xfb-\x9d\xaa\xbcM\x11\xba\x92\xfc\x13F\xf0'
- b'\x1c\x86x+\xc8\xd0S\xa9\x90`\xa1\xe4\x82\xe8'
- b'\xfc\x08\xf7\xe3\xe5\xf6\x85\x1c%\xe7%\n\xed'
- b'\xc0\x1f\xa1;\x9a\xea\xcf\x90\x0c/F>\xdf\xdagA'
- b'\xc42|\xda\x82\xf5\xa6b\xa1\xb8#\x80wI\xd8f'
- b'\xf8\xbd\xacW\xab\xc3s\xe0\xbbw\xf2K\xbe\xee'
- b'\xa8rG\xe1W\xe8\xb7\xc2i\xf3\xd8\xaf\x9d\xdc'
- b'\xd0#\xf4\xc1\x12u\xcd\x0bE?:\xe8\x9c\x1cu'
- b'\xabb(oj\r^\xd5\xd5A\x83\x88\x9a\xa1J\x1c?'
- b'\xa1\xd6\x8c\x83\x9e&'
- ),
- b'length': 307949,
- b'name.utf-8': b'azcvsupdater_2.6.2.jar',
- b'ed2k': b'>p\xefl\xfa]\x95K\x1b^\xc2\\;;e\xb7',
- },
+ b64encode(
+ bencode(
+ {
+ b'piece length': 32768,
+ b'sha1': (
+ b'2\xce\xb6\xa8"\xd7\xf0\xd4\xbf\xdc^K\xba\x1bh'
+ b'\x9d\xc5\xb7\xac\xdd'
+ ),
+ b'name': b'azcvsupdater_2.6.2.jar',
+ b'private': 0,
+ b'pieces': (
+ b"\xdb\x04B\x05\xc3'\xdab\xb8su97\xa9u"
+ b'\xca<w\\\x1ef\xd4\x9b\x16\xa9}\xc0\x9f:\xfd'
+ b'\x97qv\x83\xa2"\xef\x9d7\x0by!\rl\xe5v\xb7'
+ b'\x18{\xf7/"P\xe9\x8d\x01D\x9e8\xbd\x16\xe3'
+ b'\xfb-\x9d\xaa\xbcM\x11\xba\x92\xfc\x13F\xf0'
+ b'\x1c\x86x+\xc8\xd0S\xa9\x90`\xa1\xe4\x82\xe8'
+ b'\xfc\x08\xf7\xe3\xe5\xf6\x85\x1c%\xe7%\n\xed'
+ b'\xc0\x1f\xa1;\x9a\xea\xcf\x90\x0c/F>\xdf\xdagA'
+ b'\xc42|\xda\x82\xf5\xa6b\xa1\xb8#\x80wI\xd8f'
+ b'\xf8\xbd\xacW\xab\xc3s\xe0\xbbw\xf2K\xbe\xee'
+ b'\xa8rG\xe1W\xe8\xb7\xc2i\xf3\xd8\xaf\x9d\xdc'
+ b'\xd0#\xf4\xc1\x12u\xcd\x0bE?:\xe8\x9c\x1cu'
+ b'\xabb(oj\r^\xd5\xd5A\x83\x88\x9a\xa1J\x1c?'
+ b'\xa1\xd6\x8c\x83\x9e&'
+ ),
+ b'length': 307949,
+ b'name.utf-8': b'azcvsupdater_2.6.2.jar',
+ b'ed2k': b'>p\xefl\xfa]\x95K\x1b^\xc2\\;;e\xb7',
+ }
+ )
+ ),
)
self.assertEqual(expected, self.successResultOf(d))
@@ -117,7 +122,7 @@ class TorrentmanagerTestCase(BaseTestCase):
magnet = 'magnet:?xt=urn:btih:ab570cdd5a17ea1b61e970bb72047de141bce173'
d = self.tm.prefetch_metadata(magnet, 30)
self.clock.advance(30)
- expected = ('ab570cdd5a17ea1b61e970bb72047de141bce173', None)
+ expected = ('ab570cdd5a17ea1b61e970bb72047de141bce173', b'')
return d.addCallback(self.assertEqual, expected)
@pytest.mark.todo
diff --git a/deluge/ui/gtk3/addtorrentdialog.py b/deluge/ui/gtk3/addtorrentdialog.py
index 1c94a1e08..cf3851d6c 100644
--- a/deluge/ui/gtk3/addtorrentdialog.py
+++ b/deluge/ui/gtk3/addtorrentdialog.py
@@ -8,7 +8,7 @@
import logging
import os
-from base64 import b64encode
+from base64 import b64decode, b64encode
from xml.sax.saxutils import escape as xml_escape
from xml.sax.saxutils import unescape as xml_unescape
@@ -16,6 +16,7 @@ from gi.repository import Gtk
from gi.repository.GObject import TYPE_INT64, TYPE_UINT64
import deluge.component as component
+from deluge.bencode import bdecode
from deluge.common import (
create_magnet_uri,
decode_bytes,
@@ -268,6 +269,7 @@ class AddTorrentDialog(component.Component):
return
if metadata:
+ metadata = bdecode(b64decode(metadata))
info = TorrentInfo.from_metadata(metadata, [[t] for t in trackers])
self.files[info_hash] = info.files
self.infos[info_hash] = info.filedata