[Core] Cleanup temp files in add_torrent_url

Temporary torrent files are not deleted by add_torrent_url. Not as big a
problem as with tracker icons pages but should be removed after use.

Fixed by updating the method to use async and a try..finally cleanup
block.

Perhaps could be refactored to not require temporary files and instead
store the downloaded torrent as object for passing to add_torrent_file.

Trac: https://dev.deluge-torrent.org/ticket/3167
This commit is contained in:
Calum Lind 2022-05-01 14:48:16 +01:00
parent 68c75ccc05
commit 7f0a380576
No known key found for this signature in database
GPG Key ID: 90597A687B836BA3
2 changed files with 20 additions and 19 deletions

View File

@ -518,7 +518,8 @@ class Core(component.Component):
return task.deferLater(reactor, 0, add_torrents)
@export
def add_torrent_url(
@maybe_coroutine
async def add_torrent_url(
self, url: str, options: dict, headers: dict = None
) -> 'defer.Deferred[Optional[str]]':
"""Adds a torrent from a URL. Deluge will attempt to fetch the torrent
@ -534,26 +535,24 @@ class Core(component.Component):
"""
log.info('Attempting to add URL %s', url)
def on_download_success(filename):
# We got the file, so add it to the session
tmp_fd, tmp_file = tempfile.mkstemp(prefix='deluge_url.', suffix='.torrent')
try:
filename = await download_file(
url, tmp_file, headers=headers, force_filename=True
)
except Exception:
log.error('Failed to add torrent from URL %s', url)
raise
else:
with open(filename, 'rb') as _file:
data = _file.read()
try:
os.remove(filename)
except OSError as ex:
log.warning('Could not remove temp file: %s', ex)
return self.add_torrent_file(filename, b64encode(data), options)
def on_download_fail(failure):
# Log the error and pass the failure onto the client
log.error('Failed to add torrent from URL %s', url)
return failure
tmp_fd, tmp_file = tempfile.mkstemp(prefix='deluge_url.', suffix='.torrent')
os.close(tmp_fd)
d = download_file(url, tmp_file, headers=headers, force_filename=True)
d.addCallbacks(on_download_success, on_download_fail)
return d
finally:
try:
os.close(tmp_fd)
os.remove(tmp_file)
except OSError as ex:
log.warning(f'Unable to delete temp file {tmp_file}: , {ex}')
@export
def add_torrent_magnet(self, uri: str, options: dict) -> str:

View File

@ -4,6 +4,7 @@
# See LICENSE for more details.
#
import os
from base64 import b64encode
from hashlib import sha1 as sha
@ -175,7 +176,7 @@ class TestCore(BaseTestCase):
self.core.add_torrent_file(filename, False, options)
@pytest_twisted.inlineCallbacks
def test_add_torrent_url(self):
def test_add_torrent_url(self, mock_mkstemp):
url = (
'http://localhost:%d/ubuntu-9.04-desktop-i386.iso.torrent'
% self.listen_port
@ -185,6 +186,7 @@ class TestCore(BaseTestCase):
torrent_id = yield self.core.add_torrent_url(url, options)
assert torrent_id == info_hash
assert not os.path.isfile(mock_mkstemp[1])
@pytest_twisted.ensureDeferred
async def test_add_torrent_url_with_cookie(self):