diff --git a/deluge/tests/common_web.py b/deluge/tests/common_web.py index 8db49d243..f7da5771a 100644 --- a/deluge/tests/common_web.py +++ b/deluge/tests/common_web.py @@ -31,10 +31,8 @@ class WebServerTestBase(BaseTestCase): return self.start_webapi(None) def start_webapi(self, arg): - self.webserver_listen_port = 8999 - config_defaults = deluge.ui.web.server.CONFIG_DEFAULTS.copy() - config_defaults['port'] = self.webserver_listen_port + config_defaults['port'] = 8999 self.config = configmanager.ConfigManager('web.conf', config_defaults) self.deluge_web = DelugeWeb(daemon=False) diff --git a/deluge/tests/test_security.py b/deluge/tests/test_security.py index 6627b6956..c472d1630 100644 --- a/deluge/tests/test_security.py +++ b/deluge/tests/test_security.py @@ -133,10 +133,10 @@ class TestDaemonSecurity(BaseTestCase, DaemonBase, SecurityBaseTestCase): @pytest.mark.security class TestWebUISecurity(WebServerTestBase, SecurityBaseTestCase): def start_webapi(self, arg): - self.port = self.webserver_listen_port = 8999 + self.port = self.deluge_web.port = 8999 config_defaults = deluge.ui.web.server.CONFIG_DEFAULTS.copy() - config_defaults['port'] = self.webserver_listen_port + config_defaults['port'] = self.deluge_web.port config_defaults['https'] = True self.config = configmanager.ConfigManager('web.conf', config_defaults) diff --git a/deluge/tests/test_web_api.py b/deluge/tests/test_web_api.py index 56f86aa56..aa99fed38 100644 --- a/deluge/tests/test_web_api.py +++ b/deluge/tests/test_web_api.py @@ -58,7 +58,7 @@ class TestWebAPI(WebServerTestBase): def test_get_config(self): config = self.deluge_web.web_api.get_config() - assert self.webserver_listen_port == config['port'] + assert self.deluge_web.port == config['port'] def test_set_config(self): config = self.deluge_web.web_api.get_config() @@ -175,7 +175,7 @@ class TestWebAPI(WebServerTestBase): self.deluge_web.top_level.putChild( filename.encode(), File(common.get_test_data_file(filename)) ) - url = 'http://localhost:%d/%s' % (self.webserver_listen_port, filename) + url = 'http://localhost:%d/%s' % (self.deluge_web.port, filename) res = yield self.deluge_web.web_api.download_torrent_from_url(url) assert res.endswith(filename) @@ -191,7 +191,7 @@ class TestWebAPI(WebServerTestBase): bad_body = b'{ method": "auth.login" }' d = yield agent.request( b'POST', - b'http://127.0.0.1:%i/json' % self.webserver_listen_port, + b'http://127.0.0.1:%i/json' % self.deluge_web.port, Headers( { b'User-Agent': [b'Twisted Web Client Example'], diff --git a/deluge/tests/test_webserver.py b/deluge/tests/test_webserver.py index dd3b9ea58..69a424e77 100644 --- a/deluge/tests/test_webserver.py +++ b/deluge/tests/test_webserver.py @@ -23,8 +23,8 @@ common.disable_new_release_check() class TestWebServer(WebServerTestBase, WebServerMockBase): - @pytest_twisted.inlineCallbacks - def test_get_torrent_info(self): + @pytest_twisted.ensureDeferred + async def test_get_torrent_info(self): agent = Agent(reactor) self.mock_authentication_ignore(self.deluge_web.auth) @@ -41,15 +41,15 @@ class TestWebServer(WebServerTestBase, WebServerMockBase): b'User-Agent': ['Twisted Web Client Example'], b'Content-Type': ['application/json'], } - url = 'http://127.0.0.1:%s/json' % self.webserver_listen_port + url = 'http://127.0.0.1:%s/json' % self.deluge_web.port - d = yield agent.request( + response = await agent.request( b'POST', - url.encode('utf-8'), + url.encode(), Headers(headers), - FileBodyProducer(BytesIO(input_file.encode('utf-8'))), + FileBodyProducer(BytesIO(input_file.encode())), ) - body = yield twisted.web.client.readBody(d) + body = await twisted.web.client.readBody(response) try: json = json_lib.loads(body.decode()) diff --git a/deluge/ui/web/server.py b/deluge/ui/web/server.py index c6128ee1d..06b25923b 100644 --- a/deluge/ui/web/server.py +++ b/deluge/ui/web/server.py @@ -73,6 +73,20 @@ def rpath(*paths): return common.resource_filename('deluge.ui.web', os.path.join(*paths)) +def absolute_base_url(base): + """Returns base as absolute URL for links""" + if not base: + base = '/' + + if not base.startswith('/'): + base = '/' + base + + if not base.endswith('/'): + base += '/' + + return base + + class GetText(resource.Resource): def render(self, request): request.setHeader(b'content-type', b'text/javascript; encoding=utf-8') @@ -127,14 +141,12 @@ class Upload(resource.Resource): request.setHeader(b'content-type', b'text/html') request.setResponseCode(http.OK) - return json.dumps({'success': bool(filenames), 'files': filenames}).encode( - 'utf8' - ) + return json.dumps({'success': bool(filenames), 'files': filenames}).encode() class Render(resource.Resource): def __init__(self): - resource.Resource.__init__(self) + super().__init__() # Make a list of all the template files to check requests against. self.template_files = fnmatch.filter(os.listdir(rpath('render')), '*.html') @@ -163,7 +175,7 @@ class Render(resource.Resource): class Tracker(resource.Resource): def __init__(self): - resource.Resource.__init__(self) + super().__init__() try: self.tracker_icons = component.get('TrackerIcons') except KeyError: @@ -178,7 +190,7 @@ class Tracker(resource.Resource): request.setHeader( b'cache-control', b'public, must-revalidate, max-age=86400' ) - request.setHeader(b'content-type', icon.get_mimetype().encode('utf8')) + request.setHeader(b'content-type', icon.get_mimetype().encode()) request.setResponseCode(http.OK) request.write(icon.get_data()) request.finish() @@ -198,7 +210,7 @@ class Flag(resource.Resource): return self def render(self, request): - flag = request.country.decode('utf-8').lower() + '.png' + flag = request.country.decode().lower() + '.png' path = ('ui', 'data', 'pixmaps', 'flags', flag) filename = common.resource_filename('deluge', os.path.join(*path)) if os.path.exists(filename): @@ -454,7 +466,7 @@ class TopLevel(resource.Resource): ] def __init__(self): - resource.Resource.__init__(self) + super().__init__() self.putChild(b'css', LookupResource('Css', rpath('css'))) if os.path.isfile(rpath('js', 'gettext.js')): @@ -561,26 +573,15 @@ class TopLevel(resource.Resource): if not path: return self else: - return resource.Resource.getChild(self, path, request) + return super().getChild(path, request) def getChildWithDefault(self, path, request): # NOQA: N802 # Calculate the request base - header = request.getHeader(b'x-deluge-base') - base = header.decode('utf-8') if header else component.get('DelugeWeb').base + header = request.getHeader('x-deluge-base') + base = header if header else component.get('DelugeWeb').base + request.base = absolute_base_url(base).encode() - # validate the base parameter - if not base: - base = '/' - - if base[0] != '/': - base = '/' + base - - if base[-1] != '/': - base += '/' - - request.base = base.encode('utf-8') - - return resource.Resource.getChildWithDefault(self, path, request) + return super().getChildWithDefault(path, request) def render(self, request): uri_true = ('true', 'yes', 'on', '1') @@ -652,7 +653,7 @@ class DelugeWeb(component.Component): reactor). If False shares the process and twisted reactor from WebUI plugin or tests. """ - component.Component.__init__(self, 'DelugeWeb', depend=['Web']) + super().__init__('DelugeWeb', depend=['Web']) self.config = configmanager.ConfigManager( 'web.conf', defaults=CONFIG_DEFAULTS, file_version=2 )