[Core] Markup byte-strings to fix httpdownloader and core tests

* Twisted methods require byte-string arguments.
 * The headers str conversion in httpdownloader _download_file was
   incorrent and left the dict key still as unicode so replaced with
   a dict comprehension (py2.7 requirement).
This commit is contained in:
Calum Lind 2017-02-12 11:26:31 +00:00
parent 84802da29b
commit ff6cec251a
9 changed files with 49 additions and 33 deletions

View File

@ -1,6 +1,6 @@
=== Core ===
* libtorrent (rasterbar) >= 1.1.1
* python >= 2.6
* python >= 2.7.7
* setuptools
* twisted >= 11.1
* pyopenssl

View File

@ -985,7 +985,7 @@ class Core(component.Component):
:rtype: bool
"""
d = getPage('http://deluge-torrent.org/test_port.php?port=%s' %
d = getPage(b'http://deluge-torrent.org/test_port.php?port=%s' %
self.get_listen_port(), timeout=30)
def on_get_page(result):

View File

@ -556,7 +556,7 @@ def generate_ssl_keys():
"""
This method generates a new SSL key/cert.
"""
digest = 'sha256'
digest = b'sha256'
# Generate key pair
pkey = crypto.PKey()
pkey.generate_key(crypto.TYPE_RSA, 2048)

View File

@ -43,6 +43,7 @@ class HTTPDownloader(client.HTTPDownloader):
:param headers: any optional headers to send
:type headers: dictionary
"""
self.part_callback = part_callback
self.current_length = 0
self.total_length = 0
@ -51,7 +52,8 @@ class HTTPDownloader(client.HTTPDownloader):
self.force_filename = force_filename
self.allow_compression = allow_compression
self.code = None
agent = 'Deluge/%s (http://deluge-torrent.org)' % get_version()
agent = b'Deluge/%s (http://deluge-torrent.org)' % get_version()
client.HTTPDownloader.__init__(self, url, filename, headers=headers, agent=agent)
def gotStatus(self, version, status, message): # NOQA: N802
@ -165,17 +167,17 @@ def _download_file(url, filename, callback=None, headers=None, force_filename=Fa
t.w.e.Error: for all other HTTP response errors
"""
url = str(url)
filename = str(filename)
if headers:
for key, value in headers.items():
headers[str(key)] = str(value)
if allow_compression:
if not headers:
headers = {}
headers['accept-encoding'] = 'deflate, gzip, x-gzip'
url = url.encode('utf8')
filename = filename.encode('utf8')
if headers:
headers = {k.encode('utf8'): v.encode('utf8') for k, v in headers.items()}
# In Twisted 13.1.0 _parse() function replaced by _URI class.
# In Twisted 15.0.0 _URI class renamed to URI.
if hasattr(client, '_parse'):

View File

@ -287,7 +287,7 @@ def start_process(script, callbacks, logfile=None, print_stderr=True):
"""
cwd = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
process_protocol = ProcessOutputHandler(script, callbacks, logfile, print_stderr)
process_protocol = ProcessOutputHandler(script.encode('utf8'), callbacks, logfile, print_stderr)
# Add timeouts to deferreds
for c in callbacks:

View File

@ -1,3 +1,10 @@
# -*- coding: utf-8 -*-
#
# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# the additional special exception to link portions of this program with the OpenSSL library.
# See LICENSE for more details.
#
from __future__ import unicode_literals
import base64
@ -34,7 +41,7 @@ class CookieResource(Resource):
request.setResponseCode(FORBIDDEN)
return
request.setHeader('Content-Type', 'application/x-bittorrent')
request.setHeader(b'Content-Type', b'application/x-bittorrent')
with open(common.get_test_data_file('ubuntu-9.04-desktop-i386.iso.torrent')) as _file:
data = _file.read()
return data
@ -45,8 +52,8 @@ class PartialDownload(Resource):
def render(self, request):
with open(common.get_test_data_file('ubuntu-9.04-desktop-i386.iso.torrent')) as _file:
data = _file.read()
request.setHeader('Content-Type', len(data))
request.setHeader('Content-Type', 'application/x-bittorrent')
request.setHeader(b'Content-Type', len(data))
request.setHeader(b'Content-Type', b'application/x-bittorrent')
if request.requestHeaders.hasHeader('accept-encoding'):
return compress(data, request)
return data
@ -55,8 +62,8 @@ class PartialDownload(Resource):
class RedirectResource(Resource):
def render(self, request):
request.redirect('/ubuntu-9.04-desktop-i386.iso.torrent')
return ''
request.redirect(b'/ubuntu-9.04-desktop-i386.iso.torrent')
return b''
class TopLevelResource(Resource):

View File

@ -1,3 +1,10 @@
# -*- coding: utf-8 -*-
#
# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# the additional special exception to link portions of this program with the OpenSSL library.
# See LICENSE for more details.
#
from __future__ import unicode_literals
import tempfile
@ -27,7 +34,7 @@ def fname(name):
class RedirectResource(Resource):
def render(self, request):
url = self.get_url()
url = self.get_url().encode('utf8')
return redirectTo(url, request)
@ -35,21 +42,21 @@ class RenameResource(Resource):
def render(self, request):
filename = request.args.get('filename', ['renamed_file'])[0]
request.setHeader('Content-Type', 'text/plain')
request.setHeader('Content-Disposition', 'attachment; filename=' +
request.setHeader(b'Content-Type', b'text/plain')
request.setHeader(b'Content-Disposition', b'attachment; filename=' +
filename)
return 'This file should be called ' + filename
return b'This file should be called ' + filename
class CookieResource(Resource):
def render(self, request):
request.setHeader('Content-Type', 'text/plain')
request.setHeader(b'Content-Type', b'text/plain')
if request.getCookie('password') is None:
return 'Password cookie not set!'
return b'Password cookie not set!'
if request.getCookie('password') == 'deluge':
return 'COOKIE MONSTER!'
return b'COOKIE MONSTER!'
return request.getCookie('password')
@ -58,7 +65,7 @@ class GzipResource(Resource):
def render(self, request):
message = request.args.get('msg', ['EFFICIENCY!'])[0]
request.setHeader('Content-Type', 'text/plain')
request.setHeader(b'Content-Type', b'text/plain')
return compress(message, request)
@ -71,9 +78,9 @@ class PartialDownloadResource(Resource):
def render(self, request):
# encoding = request.requestHeaders._rawHeaders.get('accept-encoding', None)
if self.render_count == 0:
request.setHeader('content-length', '5')
request.setHeader(b'content-length', b'5')
else:
request.setHeader('content-length', '3')
request.setHeader(b'content-length', b'3')
# if encoding == "deflate, gzip, x-gzip":
request.write('abc')
@ -103,7 +110,7 @@ class TopLevelResource(Resource):
def render(self, request):
if request.getHeader('If-Modified-Since'):
request.setResponseCode(NOT_MODIFIED)
return '<h1>Deluge HTTP Downloader tests webserver here</h1>'
return b'<h1>Deluge HTTP Downloader tests webserver here</h1>'
class DownloadFileTestCase(unittest.TestCase):
@ -198,13 +205,13 @@ class DownloadFileTestCase(unittest.TestCase):
def test_download_with_gzip_encoding(self):
url = self.get_url('gzip?msg=success')
d = download_file(url, fname('gzip_encoded'))
d.addCallback(self.assertContains, 'success')
d.addCallback(self.assertContains, b'success')
return d
def test_download_with_gzip_encoding_disabled(self):
url = self.get_url('gzip?msg=fail')
d = download_file(url, fname('gzip_encoded'), allow_compression=False)
d.addCallback(self.failIfContains, 'fail')
d.addCallback(self.failIfContains, b'fail')
return d
def test_page_redirect_unhandled(self):

View File

@ -33,7 +33,7 @@ class DelugeTransferProtocol(Protocol, object):
"""
def __init__(self):
self._buffer = ''
self._buffer = b'' # TODO: Look into using bytearray instead of byte string.
self._message_length = 0
self._bytes_received = 0
self._bytes_sent = 0
@ -53,7 +53,7 @@ class DelugeTransferProtocol(Protocol, object):
size_data = len(compressed)
# Store length as a signed integer (using 4 bytes). "!" denotes network byte order.
payload_len = struct.pack('!i', size_data)
header = 'D' + payload_len
header = b'D' + payload_len
self._bytes_sent += len(header) + len(compressed)
self.transport.write(header)
self.transport.write(compressed)
@ -95,7 +95,7 @@ class DelugeTransferProtocol(Protocol, object):
# Read the first bytes of the message (MESSAGE_HEADER_SIZE bytes)
header = self._buffer[:MESSAGE_HEADER_SIZE]
payload_len = header[1:MESSAGE_HEADER_SIZE]
if header[0] != 'D':
if header[0] != b'D':
raise Exception('Invalid header format. First byte is %d' % ord(header[0]))
# Extract the length stored as a signed integer (using 4 bytes)
self._message_length = struct.unpack('!i', payload_len)[0]
@ -107,7 +107,7 @@ class DelugeTransferProtocol(Protocol, object):
log.warn('Error occurred when parsing message header: %s.', ex)
log.warn('This version of Deluge cannot communicate with the sender of this data.')
self._message_length = 0
self._buffer = ''
self._buffer = b''
def _handle_complete_message(self, data):
"""

View File

@ -32,7 +32,7 @@ def escape(text):
def compress(contents, request):
request.setHeader('content-encoding', 'gzip')
request.setHeader(b'content-encoding', b'gzip')
compress_zlib = zlib.compressobj(6, zlib.DEFLATED, zlib.MAX_WBITS + 16, zlib.DEF_MEM_LEVEL, 0)
contents = compress_zlib.compress(contents)
contents += compress_zlib.flush()