Handle partial downloads due to incorrect headers (fixes #1517)

This commit is contained in:
John Garland 2011-03-07 18:30:25 +11:00
parent 08843ccad5
commit a0f9689664
4 changed files with 55 additions and 17 deletions

View File

@ -229,7 +229,7 @@ class Core(component.Component):
:returns: a Deferred which returns the torrent_id as a str or None :returns: a Deferred which returns the torrent_id as a str or None
""" """
log.info("Attempting to add url %s", url) log.info("Attempting to add url %s", url)
def on_get_file(filename): def on_download_success(filename):
# We got the file, so add it to the session # We got the file, so add it to the session
f = open(filename, "rb") f = open(filename, "rb")
data = f.read() data = f.read()
@ -240,15 +240,20 @@ class Core(component.Component):
log.warning("Couldn't remove temp file: %s", e) log.warning("Couldn't remove temp file: %s", e)
return self.add_torrent_file(filename, base64.encodestring(data), options) return self.add_torrent_file(filename, base64.encodestring(data), options)
def on_get_file_error(failure): def on_download_fail(failure):
# Log the error and pass the failure onto the client if failure.check(twisted.web.client.PartialDownloadError):
log.error("Error occured downloading torrent from %s", url) result = download_file(url, tempfile.mkstemp()[1], headers=headers, force_filename=True,
log.error("Reason: %s", failure.getErrorMessage()) allow_compression=False)
return failure result.addCallbacks(on_download_success, on_download_fail)
else:
# Log the error and pass the failure onto the client
log.error("Error occured downloading torrent from %s", url)
log.error("Reason: %s", failure.getErrorMessage())
result = failure
return result
d = download_file(url, tempfile.mkstemp()[1], headers=headers, force_filename=True) d = download_file(url, tempfile.mkstemp()[1], headers=headers, force_filename=True)
d.addCallback(on_get_file) d.addCallbacks(on_download_success, on_download_fail)
d.addErrback(on_get_file_error)
return d return d
@export @export

View File

@ -53,7 +53,7 @@ class CoreTestCase(unittest.TestCase):
return d return d
def test_add_torrent_url_with_cookie(self): def test_add_torrent_url_with_cookie(self):
url = "http://deluge-torrent.org/test_torrent.php" url = "http://deluge-torrent.org/test_torrent.php?test=cookie"
options = {} options = {}
headers = { "Cookie" : "password=deluge" } headers = { "Cookie" : "password=deluge" }
info_hash = "60d5d82328b4547511fdeac9bf4d0112daa0ce00" info_hash = "60d5d82328b4547511fdeac9bf4d0112daa0ce00"
@ -66,6 +66,16 @@ class CoreTestCase(unittest.TestCase):
return d return d
def test_add_torrent_url_with_partial_download(self):
url = "http://deluge-torrent.org/test_torrent.php?test=partial"
options = {}
info_hash = "60d5d82328b4547511fdeac9bf4d0112daa0ce00"
d = self.core.add_torrent_url(url, options)
d.addCallback(self.assertEquals, info_hash)
return d
def test_add_magnet(self): def test_add_magnet(self):
info_hash = "60d5d82328b4547511fdeac9bf4d0112daa0ce00" info_hash = "60d5d82328b4547511fdeac9bf4d0112daa0ce00"
import deluge.common import deluge.common

View File

@ -46,7 +46,9 @@ import os
import pkg_resources import pkg_resources
import twisted.web.client
from deluge.ui.client import client from deluge.ui.client import client
from deluge.httpdownloader import download_file
import deluge.component as component import deluge.component as component
import listview import listview
from deluge.configmanager import ConfigManager from deluge.configmanager import ConfigManager
@ -654,14 +656,18 @@ class AddTorrentDialog(component.Component):
dialog.destroy() dialog.destroy()
def on_download_fail(result): def on_download_fail(result):
log.debug("Download failed: %s", result) if result.check(twisted.web.client.PartialDownloadError):
dialog.destroy() result = download_file(url, tmp_file, on_part, allow_compression=False)
dialogs.ErrorDialog(_("Download Failed"), _("Failed to download : %s" % url), details=result.getErrorMessage(), parent=self.dialog).run() result.addCallbacks(on_download_success, on_download_fail)
else:
log.debug("Download failed: %s", result)
dialog.destroy()
dialogs.ErrorDialog(_("Download Failed"), _("Failed to download : %s" % url),
details=result.getErrorMessage(), parent=self.dialog).run()
return result
import deluge.httpdownloader d = download_file(url, tmp_file, on_part)
d = deluge.httpdownloader.download_file(url, tmp_file, on_part) d.addCallbacks(on_download_success, on_download_fail)
d.addCallback(on_download_success)
d.addErrback(on_download_fail)
def _on_button_hash_clicked(self, widget): def _on_button_hash_clicked(self, widget):
log.debug("_on_button_hash_clicked") log.debug("_on_button_hash_clicked")

View File

@ -45,6 +45,7 @@ from types import FunctionType
from twisted.internet import reactor from twisted.internet import reactor
from twisted.internet.defer import Deferred, DeferredList from twisted.internet.defer import Deferred, DeferredList
from twisted.web import http, resource, server from twisted.web import http, resource, server
import twisted.web.client
from deluge import common, component, httpdownloader from deluge import common, component, httpdownloader
from deluge.configmanager import ConfigManager, get_config_dir from deluge.configmanager import ConfigManager, get_config_dir
@ -639,13 +640,29 @@ class WebApi(JSONComponent):
:rtype: string :rtype: string
""" """
def on_download_success(result):
log.debug("Successfully downloaded %s to %s", url, result)
return result
def on_download_fail(result):
if result.check(twisted.web.client.PartialDownloadError):
result = httpdownloader.download_file(url, tmp_file, headers=headers,
allow_compression=False)
result.addCallbacks(on_download_success, on_download_fail)
else:
log.error("Error occured downloading torrent from %s", url)
log.error("Reason: %s", result.getErrorMessage())
return result
tmp_file = os.path.join(tempfile.gettempdir(), url.split("/")[-1]) tmp_file = os.path.join(tempfile.gettempdir(), url.split("/")[-1])
log.debug("filename: %s", tmp_file) log.debug("filename: %s", tmp_file)
headers = {} headers = {}
if cookie: if cookie:
headers["Cookie"] = cookie headers["Cookie"] = cookie
log.debug("cookie: %s", cookie) log.debug("cookie: %s", cookie)
return httpdownloader.download_file(url, tmp_file, headers=headers) d = httpdownloader.download_file(url, tmp_file, headers=headers)
d.addCallbacks(on_download_success, on_download_fail)
return d
@export @export
def get_torrent_info(self, filename): def get_torrent_info(self, filename):