summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMamoru TASAKA <mtasaka@fedoraproject.org>2024-08-29 08:31:25 +0200
committerCalum Lind <calumlind+deluge@gmail.com>2024-09-08 10:45:14 +0200
commit5d96cfc72f0bfa36d90afd2725aa2216b8073d66 (patch)
tree5c818e190d61ca8c001e970e3ce8e54d84a8f92b
parent[UI][Common] Wrap torrent comment and tracker status URLs in HTML (clickable) (diff)
downloaddeluge-5d96cfc72f0bfa36d90afd2725aa2216b8073d66.tar.xz
deluge-5d96cfc72f0bfa36d90afd2725aa2216b8073d66.zip
[UI] Replace deprecated cgi module with email
As PEP 594 says, cgi module is marked as deprecated in python 3.11, and will be removed in 3.13 (actually removed at least in 3.13 rc1). As suggested on PEP 594, replace cgi.parse_header with email.message.EmailMessage introduced in python 3.6. Updated test modify test_download_with_rename_sanitised - With RFC2045 specification, Content-Disposition filenames parameter containing slash (directory separator) must be quoted, so changing as such. Ref: https://peps.python.org/pep-0594/#deprecated-modules Ref: https://peps.python.org/pep-0594/#cgi Closes: https://github.com/deluge-torrent/deluge/pull/462
-rw-r--r--deluge/httpdownloader.py14
-rw-r--r--deluge/tests/test_httpdownloader.py4
-rw-r--r--deluge/ui/web/json_api.py6
3 files changed, 15 insertions, 9 deletions
diff --git a/deluge/httpdownloader.py b/deluge/httpdownloader.py
index 700ade06b..c19e3aa7e 100644
--- a/deluge/httpdownloader.py
+++ b/deluge/httpdownloader.py
@@ -6,7 +6,7 @@
# See LICENSE for more details.
#
-import cgi
+import email.message
import logging
import os.path
import zlib
@@ -133,9 +133,10 @@ class HTTPDownloaderAgent:
content_disp = headers.getRawHeaders(b'content-disposition')[0].decode(
'utf-8'
)
- content_disp_params = cgi.parse_header(content_disp)[1]
- if 'filename' in content_disp_params:
- new_file_name = content_disp_params['filename']
+ message = email.message.EmailMessage()
+ message['content-disposition'] = content_disp
+ new_file_name = message.get_filename()
+ if new_file_name:
new_file_name = sanitise_filename(new_file_name)
new_file_name = os.path.join(
os.path.split(self.filename)[0], new_file_name
@@ -152,7 +153,10 @@ class HTTPDownloaderAgent:
self.filename = new_file_name
cont_type_header = headers.getRawHeaders(b'content-type')[0].decode()
- cont_type, params = cgi.parse_header(cont_type_header)
+ message = email.message.EmailMessage()
+ message['content-type'] = cont_type_header
+ cont_type = message.get_content_type()
+ params = message['content-type'].params
# Only re-ecode text content types.
encoding = None
if cont_type.startswith('text/'):
diff --git a/deluge/tests/test_httpdownloader.py b/deluge/tests/test_httpdownloader.py
index 1c2704560..0a4695b5c 100644
--- a/deluge/tests/test_httpdownloader.py
+++ b/deluge/tests/test_httpdownloader.py
@@ -206,10 +206,10 @@ class TestDownloadFile:
self.assert_contains(filename, 'This file should be called renamed')
async def test_download_with_rename_sanitised(self):
- url = self.get_url('rename?filename=/etc/passwd')
+ url = self.get_url('rename?filename="/etc/passwd"')
filename = await download_file(url, fname('original'))
assert filename == fname('passwd')
- self.assert_contains(filename, 'This file should be called /etc/passwd')
+ self.assert_contains(filename, 'This file should be called "/etc/passwd"')
async def test_download_with_attachment_no_filename(self):
url = self.get_url('attachment')
diff --git a/deluge/ui/web/json_api.py b/deluge/ui/web/json_api.py
index 1a0e66f77..dd921c801 100644
--- a/deluge/ui/web/json_api.py
+++ b/deluge/ui/web/json_api.py
@@ -6,7 +6,7 @@
# See LICENSE for more details.
#
-import cgi
+import email.message
import json
import logging
import os
@@ -191,7 +191,9 @@ class JSON(resource.Resource, component.Component):
Handler to take the json data as a string and pass it on to the
_handle_request method for further processing.
"""
- content_type, _ = cgi.parse_header(request.getHeader(b'content-type').decode())
+ message = email.message.EmailMessage()
+ message['content-type'] = request.getHeader(b'content-type').decode()
+ content_type = message.get_content_type()
if content_type != 'application/json':
message = 'Invalid JSON request content-type: %s' % content_type
raise JSONException(message)