[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
This commit is contained in:
parent
3bceb4bfc1
commit
5d96cfc72f
|
@ -6,7 +6,7 @@
|
||||||
# See LICENSE for more details.
|
# See LICENSE for more details.
|
||||||
#
|
#
|
||||||
|
|
||||||
import cgi
|
import email.message
|
||||||
import logging
|
import logging
|
||||||
import os.path
|
import os.path
|
||||||
import zlib
|
import zlib
|
||||||
|
@ -133,9 +133,10 @@ class HTTPDownloaderAgent:
|
||||||
content_disp = headers.getRawHeaders(b'content-disposition')[0].decode(
|
content_disp = headers.getRawHeaders(b'content-disposition')[0].decode(
|
||||||
'utf-8'
|
'utf-8'
|
||||||
)
|
)
|
||||||
content_disp_params = cgi.parse_header(content_disp)[1]
|
message = email.message.EmailMessage()
|
||||||
if 'filename' in content_disp_params:
|
message['content-disposition'] = content_disp
|
||||||
new_file_name = content_disp_params['filename']
|
new_file_name = message.get_filename()
|
||||||
|
if new_file_name:
|
||||||
new_file_name = sanitise_filename(new_file_name)
|
new_file_name = sanitise_filename(new_file_name)
|
||||||
new_file_name = os.path.join(
|
new_file_name = os.path.join(
|
||||||
os.path.split(self.filename)[0], new_file_name
|
os.path.split(self.filename)[0], new_file_name
|
||||||
|
@ -152,7 +153,10 @@ class HTTPDownloaderAgent:
|
||||||
self.filename = new_file_name
|
self.filename = new_file_name
|
||||||
|
|
||||||
cont_type_header = headers.getRawHeaders(b'content-type')[0].decode()
|
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.
|
# Only re-ecode text content types.
|
||||||
encoding = None
|
encoding = None
|
||||||
if cont_type.startswith('text/'):
|
if cont_type.startswith('text/'):
|
||||||
|
|
|
@ -206,10 +206,10 @@ class TestDownloadFile:
|
||||||
self.assert_contains(filename, 'This file should be called renamed')
|
self.assert_contains(filename, 'This file should be called renamed')
|
||||||
|
|
||||||
async def test_download_with_rename_sanitised(self):
|
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'))
|
filename = await download_file(url, fname('original'))
|
||||||
assert filename == fname('passwd')
|
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):
|
async def test_download_with_attachment_no_filename(self):
|
||||||
url = self.get_url('attachment')
|
url = self.get_url('attachment')
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# See LICENSE for more details.
|
# See LICENSE for more details.
|
||||||
#
|
#
|
||||||
|
|
||||||
import cgi
|
import email.message
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
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
|
Handler to take the json data as a string and pass it on to the
|
||||||
_handle_request method for further processing.
|
_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':
|
if content_type != 'application/json':
|
||||||
message = 'Invalid JSON request content-type: %s' % content_type
|
message = 'Invalid JSON request content-type: %s' % content_type
|
||||||
raise JSONException(message)
|
raise JSONException(message)
|
||||||
|
|
Loading…
Reference in New Issue