[TrackerIcon] Use httpdownloader page redirect handling
User reported infinite redirecting when attempting to fetch tracker icon. Fixed by allowing httpdownloader and RedirectAgent to handle page redirects including catching infinite redirects Trac: https://dev.deluge-torrent.org/ticket/3167 See-also: https://github.com/twisted/twisted/blob/5c24e9/src/twisted/web/client.py#L168
This commit is contained in:
parent
61a83bbd20
commit
96a0825add
|
@ -13,7 +13,7 @@ from tempfile import mkstemp
|
||||||
from urllib.parse import urljoin, urlparse
|
from urllib.parse import urljoin, urlparse
|
||||||
|
|
||||||
from twisted.internet import defer, threads
|
from twisted.internet import defer, threads
|
||||||
from twisted.web.error import PageRedirect
|
from twisted.python.failure import Failure
|
||||||
from twisted.web.resource import ForbiddenResource, NoResource
|
from twisted.web.resource import ForbiddenResource, NoResource
|
||||||
|
|
||||||
from deluge.component import Component
|
from deluge.component import Component
|
||||||
|
@ -208,7 +208,6 @@ class TrackerIcons(Component):
|
||||||
d.addCallbacks(
|
d.addCallbacks(
|
||||||
self.on_download_page_complete,
|
self.on_download_page_complete,
|
||||||
self.on_download_page_fail,
|
self.on_download_page_fail,
|
||||||
errbackArgs=(host,),
|
|
||||||
)
|
)
|
||||||
d.addCallback(self.parse_html_page)
|
d.addCallback(self.parse_html_page)
|
||||||
d.addCallbacks(
|
d.addCallbacks(
|
||||||
|
@ -242,7 +241,7 @@ class TrackerIcons(Component):
|
||||||
log.debug('Downloading %s %s', host, url)
|
log.debug('Downloading %s %s', host, url)
|
||||||
tmp_fd, tmp_file = mkstemp(prefix='deluge_ticon.')
|
tmp_fd, tmp_file = mkstemp(prefix='deluge_ticon.')
|
||||||
os.close(tmp_fd)
|
os.close(tmp_fd)
|
||||||
return download_file(url, tmp_file, force_filename=True, handle_redirects=False)
|
return download_file(url, tmp_file, force_filename=True)
|
||||||
|
|
||||||
def on_download_page_complete(self, page):
|
def on_download_page_complete(self, page):
|
||||||
"""
|
"""
|
||||||
|
@ -256,33 +255,18 @@ class TrackerIcons(Component):
|
||||||
log.debug('Finished downloading %s', page)
|
log.debug('Finished downloading %s', page)
|
||||||
return page
|
return page
|
||||||
|
|
||||||
def on_download_page_fail(self, f, host):
|
def on_download_page_fail(self, failure: 'Failure') -> 'Failure':
|
||||||
"""
|
"""Runs any download failure clean-up functions
|
||||||
Recovers from download error
|
|
||||||
|
|
||||||
:param f: the failure that occurred
|
Args:
|
||||||
:type f: Failure
|
failure: The failure that occurred.
|
||||||
:param host: the name of the host whose page failed to download
|
|
||||||
:type host: string
|
|
||||||
:returns: a Deferred if recovery was possible
|
|
||||||
else the original failure
|
|
||||||
:rtype: Deferred or Failure
|
|
||||||
"""
|
|
||||||
error_msg = f.getErrorMessage()
|
|
||||||
log.debug('Error downloading page: %s', error_msg)
|
|
||||||
d = f
|
|
||||||
if f.check(PageRedirect):
|
|
||||||
# Handle redirect errors
|
|
||||||
location = urljoin(self.host_to_url(host), error_msg.split(' to ')[1])
|
|
||||||
self.redirects[host] = url_to_host(location)
|
|
||||||
d = self.download_page(host, url=location)
|
|
||||||
d.addCallbacks(
|
|
||||||
self.on_download_page_complete,
|
|
||||||
self.on_download_page_fail,
|
|
||||||
errbackArgs=(host,),
|
|
||||||
)
|
|
||||||
|
|
||||||
return d
|
Returns:
|
||||||
|
The original failure.
|
||||||
|
|
||||||
|
"""
|
||||||
|
log.debug(f'Error downloading page: {failure.getErrorMessage()}')
|
||||||
|
return failure
|
||||||
|
|
||||||
@proxy(threads.deferToThread)
|
@proxy(threads.deferToThread)
|
||||||
def parse_html_page(self, page):
|
def parse_html_page(self, page):
|
||||||
|
@ -425,22 +409,7 @@ class TrackerIcons(Component):
|
||||||
error_msg = f.getErrorMessage()
|
error_msg = f.getErrorMessage()
|
||||||
log.debug('Error downloading icon from %s: %s', host, error_msg)
|
log.debug('Error downloading icon from %s: %s', host, error_msg)
|
||||||
d = f
|
d = f
|
||||||
if f.check(PageRedirect):
|
if f.check(NoResource, ForbiddenResource) and icons:
|
||||||
# Handle redirect errors
|
|
||||||
location = urljoin(self.host_to_url(host), error_msg.split(' to ')[1])
|
|
||||||
d = self.download_icon(
|
|
||||||
[(location, extension_to_mimetype(location.rpartition('.')[2]))]
|
|
||||||
+ icons,
|
|
||||||
host,
|
|
||||||
)
|
|
||||||
if not icons:
|
|
||||||
d.addCallbacks(
|
|
||||||
self.on_download_icon_complete,
|
|
||||||
self.on_download_icon_fail,
|
|
||||||
callbackArgs=(host,),
|
|
||||||
errbackArgs=(host,),
|
|
||||||
)
|
|
||||||
elif f.check(NoResource, ForbiddenResource) and icons:
|
|
||||||
d = self.download_icon(icons, host)
|
d = self.download_icon(icons, host)
|
||||||
elif f.check(NoIconsError):
|
elif f.check(NoIconsError):
|
||||||
# No icons, try favicon.ico as an act of desperation
|
# No icons, try favicon.ico as an act of desperation
|
||||||
|
|
Loading…
Reference in New Issue