fix #571 unable to subscribe to authenticated podcast after redirect

This commit is contained in:
Eric Le Lay 2018-12-15 16:10:00 +01:00
parent 4bc1346d45
commit f51ef5a88e
3 changed files with 38 additions and 11 deletions

View File

@ -77,7 +77,10 @@ class UnknownStatusCode(ExceptionWithData): pass
# Authentication error
class AuthenticationRequired(Exception): pass
class AuthenticationRequired(Exception):
def __init__(self, msg, url=None):
super().__init__(msg)
self.url = url
# Successful status codes
@ -158,7 +161,7 @@ class Fetcher(object):
if status == 400:
raise BadRequest('bad request')
elif status == 401:
raise AuthenticationRequired('authentication required')
raise AuthenticationRequired('authentication required', feed)
elif status == 403:
raise Unsubscribe('forbidden')
elif status == 404:

View File

@ -2489,14 +2489,15 @@ class gPodder(BuilderWidget, dbus.service.Object):
channel.save()
self._update_cover(channel)
except feedcore.AuthenticationRequired:
if url in auth_tokens:
except feedcore.AuthenticationRequired as e:
# use e.url because there might have been a redirection (#571)
if e.url in auth_tokens:
# Fail for wrong authentication data
error_messages[url] = _('Authentication failed')
failed.append(url)
error_messages[e.url] = _('Authentication failed')
failed.append(e.url)
else:
# Queue for login dialog later
authreq.append(url)
authreq.append(e.url)
continue
except feedcore.WifiLogin as error:
redirections[url] = error.data

View File

@ -10,11 +10,12 @@ import hashlib
import http.server
import re
import sys
import threading
USERNAME = 'user@example.com' # Username used for HTTP Authentication
PASSWORD = 'secret' # Password used for HTTP Authentication
HOST, PORT = 'localhost', 8000 # Hostname and port for the HTTP server
HOST, PORT, RPORT = 'localhost', 8000, 8001 # Hostname and port for the HTTP server
# When the script contents change, the feed's episodes each get a new GUID
GUID = hashlib.sha1(open(__file__, mode='rb').read()).hexdigest()
@ -22,6 +23,7 @@ GUID = hashlib.sha1(open(__file__, mode='rb').read()).hexdigest()
URL = 'http://%(HOST)s:%(PORT)s' % locals()
FEEDNAME = sys.argv[0] # The title of the RSS feed
REDIRECT = 'redirect.rss' # The path for a redirection
FEEDFILE = 'feed.rss' # The "filename" of the feed on the server
EPISODES = 'episode' # Base name for the episode files
EPISODES_EXT = '.mp3' # Extension for the episode files
@ -64,12 +66,13 @@ def mkrss(items=EP_COUNT):
def mkdata(size=SIZE):
"""Generate dummy data of a given size (in bytes)"""
return ''.join(chr(32 + (i % (127 - 32))) for i in range(size))
return b''.join(chr(32 + (i % (127 - 32))) for i in range(size))
class AuthRequestHandler(http.server.BaseHTTPRequestHandler):
FEEDFILE_PATH = '/%s' % FEEDFILE
EPISODES_PATH = '/%s' % EPISODES
REDIRECT_PATH = '/%s' % REDIRECT
def do_GET(self):
authorized = False
@ -94,6 +97,12 @@ class AuthRequestHandler(http.server.BaseHTTPRequestHandler):
elif self.path.startswith(self.EPISODES_PATH):
print('Episode request.')
is_episode = True
elif self.path == self.REDIRECT_PATH:
print('Redirect request.')
self.send_response(302)
self.send_header('Location', '%s/%s' % (URL, FEEDFILE))
self.end_headers()
return
if not authorized:
print('Not authorized - sending WWW-Authenticate header.')
@ -110,12 +119,26 @@ class AuthRequestHandler(http.server.BaseHTTPRequestHandler):
self.wfile.write(mkrss().encode('utf-8') if is_feed else mkdata())
def run(httpd):
while True:
httpd.handle_request()
if __name__ == '__main__':
httpd = http.server.HTTPServer((HOST, PORT), AuthRequestHandler)
print("""
Feed URL: %(URL)s/%(FEEDFILE)s
Redirect URL: http://%(HOST)s:%(RPORT)d/%(REDIRECT)s
Username: %(USERNAME)s
Password: %(PASSWORD)s
""" % locals())
while True:
httpd.handle_request()
httpdr = http.server.HTTPServer((HOST, RPORT), AuthRequestHandler)
t1 = threading.Thread(name='http', target=run, args=(httpd,), daemon=True)
t1.start()
t2 = threading.Thread(name='http redirect', target=run, args=(httpdr,), daemon=True)
t2.start()
try:
t1.join()
t2.join()
except KeyboardInterrupt:
pass