mirror of
https://git.deluge-torrent.org/deluge
synced 2025-08-12 19:28:42 +00:00
[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:
parent
84802da29b
commit
ff6cec251a
9 changed files with 49 additions and 33 deletions
2
DEPENDS
2
DEPENDS
|
@ -1,6 +1,6 @@
|
||||||
=== Core ===
|
=== Core ===
|
||||||
* libtorrent (rasterbar) >= 1.1.1
|
* libtorrent (rasterbar) >= 1.1.1
|
||||||
* python >= 2.6
|
* python >= 2.7.7
|
||||||
* setuptools
|
* setuptools
|
||||||
* twisted >= 11.1
|
* twisted >= 11.1
|
||||||
* pyopenssl
|
* pyopenssl
|
||||||
|
|
|
@ -985,7 +985,7 @@ class Core(component.Component):
|
||||||
:rtype: bool
|
: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)
|
self.get_listen_port(), timeout=30)
|
||||||
|
|
||||||
def on_get_page(result):
|
def on_get_page(result):
|
||||||
|
|
|
@ -556,7 +556,7 @@ def generate_ssl_keys():
|
||||||
"""
|
"""
|
||||||
This method generates a new SSL key/cert.
|
This method generates a new SSL key/cert.
|
||||||
"""
|
"""
|
||||||
digest = 'sha256'
|
digest = b'sha256'
|
||||||
# Generate key pair
|
# Generate key pair
|
||||||
pkey = crypto.PKey()
|
pkey = crypto.PKey()
|
||||||
pkey.generate_key(crypto.TYPE_RSA, 2048)
|
pkey.generate_key(crypto.TYPE_RSA, 2048)
|
||||||
|
|
|
@ -43,6 +43,7 @@ class HTTPDownloader(client.HTTPDownloader):
|
||||||
:param headers: any optional headers to send
|
:param headers: any optional headers to send
|
||||||
:type headers: dictionary
|
:type headers: dictionary
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.part_callback = part_callback
|
self.part_callback = part_callback
|
||||||
self.current_length = 0
|
self.current_length = 0
|
||||||
self.total_length = 0
|
self.total_length = 0
|
||||||
|
@ -51,7 +52,8 @@ class HTTPDownloader(client.HTTPDownloader):
|
||||||
self.force_filename = force_filename
|
self.force_filename = force_filename
|
||||||
self.allow_compression = allow_compression
|
self.allow_compression = allow_compression
|
||||||
self.code = None
|
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)
|
client.HTTPDownloader.__init__(self, url, filename, headers=headers, agent=agent)
|
||||||
|
|
||||||
def gotStatus(self, version, status, message): # NOQA: N802
|
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
|
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 allow_compression:
|
||||||
if not headers:
|
if not headers:
|
||||||
headers = {}
|
headers = {}
|
||||||
headers['accept-encoding'] = 'deflate, gzip, x-gzip'
|
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 13.1.0 _parse() function replaced by _URI class.
|
||||||
# In Twisted 15.0.0 _URI class renamed to URI.
|
# In Twisted 15.0.0 _URI class renamed to URI.
|
||||||
if hasattr(client, '_parse'):
|
if hasattr(client, '_parse'):
|
||||||
|
|
|
@ -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__)))
|
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
|
# Add timeouts to deferreds
|
||||||
for c in callbacks:
|
for c in callbacks:
|
||||||
|
|
|
@ -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
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
|
@ -34,7 +41,7 @@ class CookieResource(Resource):
|
||||||
request.setResponseCode(FORBIDDEN)
|
request.setResponseCode(FORBIDDEN)
|
||||||
return
|
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:
|
with open(common.get_test_data_file('ubuntu-9.04-desktop-i386.iso.torrent')) as _file:
|
||||||
data = _file.read()
|
data = _file.read()
|
||||||
return data
|
return data
|
||||||
|
@ -45,8 +52,8 @@ class PartialDownload(Resource):
|
||||||
def render(self, request):
|
def render(self, request):
|
||||||
with open(common.get_test_data_file('ubuntu-9.04-desktop-i386.iso.torrent')) as _file:
|
with open(common.get_test_data_file('ubuntu-9.04-desktop-i386.iso.torrent')) as _file:
|
||||||
data = _file.read()
|
data = _file.read()
|
||||||
request.setHeader('Content-Type', len(data))
|
request.setHeader(b'Content-Type', len(data))
|
||||||
request.setHeader('Content-Type', 'application/x-bittorrent')
|
request.setHeader(b'Content-Type', b'application/x-bittorrent')
|
||||||
if request.requestHeaders.hasHeader('accept-encoding'):
|
if request.requestHeaders.hasHeader('accept-encoding'):
|
||||||
return compress(data, request)
|
return compress(data, request)
|
||||||
return data
|
return data
|
||||||
|
@ -55,8 +62,8 @@ class PartialDownload(Resource):
|
||||||
class RedirectResource(Resource):
|
class RedirectResource(Resource):
|
||||||
|
|
||||||
def render(self, request):
|
def render(self, request):
|
||||||
request.redirect('/ubuntu-9.04-desktop-i386.iso.torrent')
|
request.redirect(b'/ubuntu-9.04-desktop-i386.iso.torrent')
|
||||||
return ''
|
return b''
|
||||||
|
|
||||||
|
|
||||||
class TopLevelResource(Resource):
|
class TopLevelResource(Resource):
|
||||||
|
|
|
@ -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
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import tempfile
|
import tempfile
|
||||||
|
@ -27,7 +34,7 @@ def fname(name):
|
||||||
class RedirectResource(Resource):
|
class RedirectResource(Resource):
|
||||||
|
|
||||||
def render(self, request):
|
def render(self, request):
|
||||||
url = self.get_url()
|
url = self.get_url().encode('utf8')
|
||||||
return redirectTo(url, request)
|
return redirectTo(url, request)
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,21 +42,21 @@ class RenameResource(Resource):
|
||||||
|
|
||||||
def render(self, request):
|
def render(self, request):
|
||||||
filename = request.args.get('filename', ['renamed_file'])[0]
|
filename = request.args.get('filename', ['renamed_file'])[0]
|
||||||
request.setHeader('Content-Type', 'text/plain')
|
request.setHeader(b'Content-Type', b'text/plain')
|
||||||
request.setHeader('Content-Disposition', 'attachment; filename=' +
|
request.setHeader(b'Content-Disposition', b'attachment; filename=' +
|
||||||
filename)
|
filename)
|
||||||
return 'This file should be called ' + filename
|
return b'This file should be called ' + filename
|
||||||
|
|
||||||
|
|
||||||
class CookieResource(Resource):
|
class CookieResource(Resource):
|
||||||
|
|
||||||
def render(self, request):
|
def render(self, request):
|
||||||
request.setHeader('Content-Type', 'text/plain')
|
request.setHeader(b'Content-Type', b'text/plain')
|
||||||
if request.getCookie('password') is None:
|
if request.getCookie('password') is None:
|
||||||
return 'Password cookie not set!'
|
return b'Password cookie not set!'
|
||||||
|
|
||||||
if request.getCookie('password') == 'deluge':
|
if request.getCookie('password') == 'deluge':
|
||||||
return 'COOKIE MONSTER!'
|
return b'COOKIE MONSTER!'
|
||||||
|
|
||||||
return request.getCookie('password')
|
return request.getCookie('password')
|
||||||
|
|
||||||
|
@ -58,7 +65,7 @@ class GzipResource(Resource):
|
||||||
|
|
||||||
def render(self, request):
|
def render(self, request):
|
||||||
message = request.args.get('msg', ['EFFICIENCY!'])[0]
|
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)
|
return compress(message, request)
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,9 +78,9 @@ class PartialDownloadResource(Resource):
|
||||||
def render(self, request):
|
def render(self, request):
|
||||||
# encoding = request.requestHeaders._rawHeaders.get('accept-encoding', None)
|
# encoding = request.requestHeaders._rawHeaders.get('accept-encoding', None)
|
||||||
if self.render_count == 0:
|
if self.render_count == 0:
|
||||||
request.setHeader('content-length', '5')
|
request.setHeader(b'content-length', b'5')
|
||||||
else:
|
else:
|
||||||
request.setHeader('content-length', '3')
|
request.setHeader(b'content-length', b'3')
|
||||||
|
|
||||||
# if encoding == "deflate, gzip, x-gzip":
|
# if encoding == "deflate, gzip, x-gzip":
|
||||||
request.write('abc')
|
request.write('abc')
|
||||||
|
@ -103,7 +110,7 @@ class TopLevelResource(Resource):
|
||||||
def render(self, request):
|
def render(self, request):
|
||||||
if request.getHeader('If-Modified-Since'):
|
if request.getHeader('If-Modified-Since'):
|
||||||
request.setResponseCode(NOT_MODIFIED)
|
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):
|
class DownloadFileTestCase(unittest.TestCase):
|
||||||
|
@ -198,13 +205,13 @@ class DownloadFileTestCase(unittest.TestCase):
|
||||||
def test_download_with_gzip_encoding(self):
|
def test_download_with_gzip_encoding(self):
|
||||||
url = self.get_url('gzip?msg=success')
|
url = self.get_url('gzip?msg=success')
|
||||||
d = download_file(url, fname('gzip_encoded'))
|
d = download_file(url, fname('gzip_encoded'))
|
||||||
d.addCallback(self.assertContains, 'success')
|
d.addCallback(self.assertContains, b'success')
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def test_download_with_gzip_encoding_disabled(self):
|
def test_download_with_gzip_encoding_disabled(self):
|
||||||
url = self.get_url('gzip?msg=fail')
|
url = self.get_url('gzip?msg=fail')
|
||||||
d = download_file(url, fname('gzip_encoded'), allow_compression=False)
|
d = download_file(url, fname('gzip_encoded'), allow_compression=False)
|
||||||
d.addCallback(self.failIfContains, 'fail')
|
d.addCallback(self.failIfContains, b'fail')
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def test_page_redirect_unhandled(self):
|
def test_page_redirect_unhandled(self):
|
||||||
|
|
|
@ -33,7 +33,7 @@ class DelugeTransferProtocol(Protocol, object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._buffer = ''
|
self._buffer = b'' # TODO: Look into using bytearray instead of byte string.
|
||||||
self._message_length = 0
|
self._message_length = 0
|
||||||
self._bytes_received = 0
|
self._bytes_received = 0
|
||||||
self._bytes_sent = 0
|
self._bytes_sent = 0
|
||||||
|
@ -53,7 +53,7 @@ class DelugeTransferProtocol(Protocol, object):
|
||||||
size_data = len(compressed)
|
size_data = len(compressed)
|
||||||
# Store length as a signed integer (using 4 bytes). "!" denotes network byte order.
|
# Store length as a signed integer (using 4 bytes). "!" denotes network byte order.
|
||||||
payload_len = struct.pack('!i', size_data)
|
payload_len = struct.pack('!i', size_data)
|
||||||
header = 'D' + payload_len
|
header = b'D' + payload_len
|
||||||
self._bytes_sent += len(header) + len(compressed)
|
self._bytes_sent += len(header) + len(compressed)
|
||||||
self.transport.write(header)
|
self.transport.write(header)
|
||||||
self.transport.write(compressed)
|
self.transport.write(compressed)
|
||||||
|
@ -95,7 +95,7 @@ class DelugeTransferProtocol(Protocol, object):
|
||||||
# Read the first bytes of the message (MESSAGE_HEADER_SIZE bytes)
|
# Read the first bytes of the message (MESSAGE_HEADER_SIZE bytes)
|
||||||
header = self._buffer[:MESSAGE_HEADER_SIZE]
|
header = self._buffer[:MESSAGE_HEADER_SIZE]
|
||||||
payload_len = header[1: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]))
|
raise Exception('Invalid header format. First byte is %d' % ord(header[0]))
|
||||||
# Extract the length stored as a signed integer (using 4 bytes)
|
# Extract the length stored as a signed integer (using 4 bytes)
|
||||||
self._message_length = struct.unpack('!i', payload_len)[0]
|
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('Error occurred when parsing message header: %s.', ex)
|
||||||
log.warn('This version of Deluge cannot communicate with the sender of this data.')
|
log.warn('This version of Deluge cannot communicate with the sender of this data.')
|
||||||
self._message_length = 0
|
self._message_length = 0
|
||||||
self._buffer = ''
|
self._buffer = b''
|
||||||
|
|
||||||
def _handle_complete_message(self, data):
|
def _handle_complete_message(self, data):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -32,7 +32,7 @@ def escape(text):
|
||||||
|
|
||||||
|
|
||||||
def compress(contents, request):
|
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)
|
compress_zlib = zlib.compressobj(6, zlib.DEFLATED, zlib.MAX_WBITS + 16, zlib.DEF_MEM_LEVEL, 0)
|
||||||
contents = compress_zlib.compress(contents)
|
contents = compress_zlib.compress(contents)
|
||||||
contents += compress_zlib.flush()
|
contents += compress_zlib.flush()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue