Skip to content

Commit

Permalink
Python 3: make FTP server work
Browse files Browse the repository at this point in the history
  • Loading branch information
mgedmin committed Oct 21, 2017
1 parent 0050107 commit 030b452
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 63 deletions.
8 changes: 4 additions & 4 deletions src/zope/server/ftp/server.py
Expand Up @@ -194,7 +194,7 @@ def cmd_dele(self, args):
def cmd_help(self, args):
'See IFTPCommandHandler'
self.reply('HELP_START', flush=0)
self.write('Help goes here somewhen.\r\n')
self.write(b'Help goes here somewhen.\r\n')
self.reply('HELP_END')


Expand Down Expand Up @@ -229,7 +229,7 @@ def cmd_list(self, args, long=1):
ok_reply = ('OPEN_DATA_CONN', self.type_map[self.transfer_mode])
cdc = RETRChannel(self, ok_reply)
try:
cdc.write(s)
cdc.write(s.encode('utf-8'))
cdc.close_when_done()
except OSError as err:
self.reply('ERR_NO_LIST', str(err))
Expand Down Expand Up @@ -342,7 +342,7 @@ def cmd_pasv(self, args):
assert self.async_mode
# Kill any existing passive listener first.
self.abortPassive()
local_addr = self.getsockname()[0]
local_addr = self.socket.getsockname()[0]
self.passive_listener = PassiveListener(self, local_addr)
port = self.passive_listener.port
self.reply('PASV_MODE_MSG', (','.join(local_addr.split('.')),
Expand Down Expand Up @@ -694,7 +694,7 @@ def __init__ (self, control_channel, local_addr):
# bind to an address on the interface where the
# control connection is connected.
self.bind((local_addr, 0))
self.port = self.getsockname()[1]
self.port = self.socket.getsockname()[1]
self.listen(1)

def log (self, *ignore):
Expand Down
6 changes: 3 additions & 3 deletions src/zope/server/ftp/tests/demofs.py
Expand Up @@ -184,7 +184,7 @@ def mtime(self, path):
def size(self, path):
"See zope.server.interfaces.ftp.IFileSystem"
f = self.getany(path)
return len(getattr(f, 'data', ''))
return len(getattr(f, 'data', b''))

def mkdir(self, path):
"See zope.server.interfaces.ftp.IFileSystem"
Expand Down Expand Up @@ -258,9 +258,9 @@ def writefile(self, path, instream, start=None, end=None, append=False):
raise ValueError("Negative starting file position")
prefix = f.data[:start]
if len(prefix) < start:
prefix += '\0' * (start - len(prefix))
prefix += b'\0' * (start - len(prefix))
else:
prefix = ''
prefix = b''
start=0

if end:
Expand Down
48 changes: 24 additions & 24 deletions src/zope/server/ftp/tests/fstests.py
Expand Up @@ -15,9 +15,9 @@
"""

try:
from cStringIO import StringIO
from cStringIO import StringIO as BytesIO
except ImportError:
from io import StringIO
from io import BytesIO

from zope.interface.verify import verifyObject
from zope.server.interfaces.ftp import IFileSystem
Expand All @@ -31,7 +31,7 @@ class FileSystemTests(object):
file_name = '/dir/file.txt'
unwritable_filename = '/dir/protected.txt'
dir_contents = ['file.txt', 'protected.txt']
file_contents = 'Lengthen your stride'
file_contents = b'Lengthen your stride'

def test_type(self):
self.assertEqual(self.filesystem.type(self.dir_name), 'd')
Expand All @@ -44,19 +44,19 @@ def test_names(self):
self.assertEqual(lst, self.dir_contents)

def test_readfile(self):
s = StringIO()
s = BytesIO()
self.filesystem.readfile(self.file_name, s)
self.assertEqual(s.getvalue(), self.file_contents)


def testReadPartOfFile(self):
s = StringIO()
s = BytesIO()
self.filesystem.readfile(self.file_name, s, 2)
self.assertEqual(s.getvalue(), self.file_contents[2:])


def testReadPartOfFile2(self):
s = StringIO()
s = BytesIO()
self.filesystem.readfile(self.file_name, s, 1, 5)
self.assertEqual(s.getvalue(), self.file_contents[1:5])

Expand Down Expand Up @@ -86,68 +86,68 @@ def testRename(self):


def testWriteFile(self):
s = StringIO()
s = BytesIO()
self.filesystem.readfile(self.file_name, s)
self.assertEqual(s.getvalue(), self.file_contents)

data = 'Always ' + self.file_contents
s = StringIO(data)
data = b'Always ' + self.file_contents
s = BytesIO(data)
self.filesystem.writefile(self.file_name, s)

s = StringIO()
s = BytesIO()
self.filesystem.readfile(self.file_name, s)
self.assertEqual(s.getvalue(), data)


def testAppendToFile(self):
data = ' again'
s = StringIO(data)
data = b' again'
s = BytesIO(data)
self.filesystem.writefile(self.file_name, s, append=True)

s = StringIO()
s = BytesIO()
self.filesystem.readfile(self.file_name, s)
self.assertEqual(s.getvalue(), self.file_contents + data)

def testWritePartOfFile(self):
data = '123'
s = StringIO(data)
data = b'123'
s = BytesIO(data)
self.filesystem.writefile(self.file_name, s, 3, 6)

expect = self.file_contents[:3] + data + self.file_contents[6:]

s = StringIO()
s = BytesIO()
self.filesystem.readfile(self.file_name, s)
self.assertEqual(s.getvalue(), expect)

def testWritePartOfFile_and_truncate(self):
data = '123'
s = StringIO(data)
data = b'123'
s = BytesIO(data)
self.filesystem.writefile(self.file_name, s, 3)

expect = self.file_contents[:3] + data

s = StringIO()
s = BytesIO()
self.filesystem.readfile(self.file_name, s)
self.assertEqual(s.getvalue(), expect)

def testWriteBeyondEndOfFile(self):
partlen = len(self.file_contents) - 6
data = 'daylight savings'
s = StringIO(data)
data = b'daylight savings'
s = BytesIO(data)
self.filesystem.writefile(self.file_name, s, partlen)

expect = self.file_contents[:partlen] + data

s = StringIO()
s = BytesIO()
self.filesystem.readfile(self.file_name, s)
self.assertEqual(s.getvalue(), expect)


def testWriteNewFile(self):
s = StringIO(self.file_contents)
s = BytesIO(self.file_contents)
self.filesystem.writefile(self.file_name + '.new', s)

s = StringIO()
s = BytesIO()
self.filesystem.readfile(self.file_name, s)
self.assertEqual(s.getvalue(), self.file_contents)

Expand Down
9 changes: 5 additions & 4 deletions src/zope/server/ftp/tests/test_demofs.py
Expand Up @@ -16,9 +16,9 @@
from unittest import TestCase, TestSuite, main, makeSuite

try:
from cStringIO import StringIO
from cStringIO import StringIO as BytesIO
except ImportError:
from io import StringIO
from io import BytesIO

from . import demofs
from .fstests import FileSystemTests
Expand All @@ -31,10 +31,11 @@ def setUp(self):
root.grant('bob', demofs.write)
fs = self.filesystem = demofs.DemoFileSystem(root, 'bob')
fs.mkdir(self.dir_name)
fs.writefile(self.file_name, StringIO(self.file_contents))
fs.writefile(self.unwritable_filename, StringIO("save this"))
fs.writefile(self.file_name, BytesIO(self.file_contents))
fs.writefile(self.unwritable_filename, BytesIO(b"save this"))
fs.get(self.unwritable_filename).revoke('bob', demofs.write)


def test_suite():
return TestSuite((
makeSuite(Test),
Expand Down
40 changes: 20 additions & 20 deletions src/zope/server/ftp/tests/test_ftpserver.py
Expand Up @@ -24,9 +24,9 @@
from threading import Thread, Event

try:
from cStringIO import StringIO
from cStringIO import StringIO as BytesIO
except ImportError:
from io import StringIO
from io import BytesIO

from zope.server.adjustments import Adjustments
from zope.server.ftp.tests import demofs
Expand Down Expand Up @@ -74,11 +74,11 @@ def setUp(self):
root_dir['private'].access['anonymous'] = 0

fs = demofs.DemoFileSystem(root_dir, 'foo')
fs.writefile('/test/existing', StringIO('test initial data'))
fs.writefile('/private/existing', StringIO('private initial data'))
fs.writefile('/test/existing', BytesIO(b'test initial data'))
fs.writefile('/private/existing', BytesIO(b'private initial data'))

self.__fs = fs = demofs.DemoFileSystem(root_dir, 'root')
fs.writefile('/existing', StringIO('root initial data'))
fs.writefile('/existing', BytesIO(b'root initial data'))

fs_access = demofs.DemoFileSystemAccess(root_dir, {'foo': 'bar'})

Expand Down Expand Up @@ -155,13 +155,13 @@ def getFTPConnection(self, login=1):
ftp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ftp.connect((LOCALHOST, self.port))
result = ftp.recv(10000).split()[0]
self.assertEqual(result, '220')
self.assertEqual(result, b'220')
if login:
ftp.send('USER foo\r\n')
self.assertEqual(ftp.recv(1024),
ftp.send(b'USER foo\r\n')
self.assertEqual(ftp.recv(1024).decode(),
status_messages['PASS_REQUIRED'] +'\r\n')
ftp.send('PASS bar\r\n')
self.assertEqual(ftp.recv(1024),
ftp.send(b'PASS bar\r\n')
self.assertEqual(ftp.recv(1024).decode(),
status_messages['LOGIN_SUCCESS'] +'\r\n')

return ftp
Expand All @@ -175,8 +175,8 @@ def execute(self, commands, login=1):
commands = (commands,)

for command in commands:
ftp.send('%s\r\n' %command)
result = ftp.recv(10000)
ftp.send(b'%s\r\n' % command.encode())
result = ftp.recv(10000).decode()
self.failUnless(result.endswith('\r\n'))
finally:
ftp.close()
Expand All @@ -196,11 +196,11 @@ def testAPPE(self):
try:
conn.connect(LOCALHOST, self.port)
conn.login('foo', 'bar')
fp = StringIO('Charity never faileth')
fp = BytesIO(b'Charity never faileth')
# Successful write
conn.storbinary('APPE /test/existing', fp)
self.assertEqual(self.__fs.files['test']['existing'].data,
'test initial dataCharity never faileth')
b'test initial dataCharity never faileth')
finally:
conn.close()
# Make sure no garbage was left behind.
Expand All @@ -212,7 +212,7 @@ def testAPPE_errors(self):
conn.connect(LOCALHOST, self.port)
conn.login('foo', 'bar')

fp = StringIO('Speak softly')
fp = BytesIO(b'Speak softly')

# Can't overwrite directory
self.assertRaises(
Expand Down Expand Up @@ -349,15 +349,15 @@ def testSTOR(self):
try:
conn.connect(LOCALHOST, self.port)
conn.login('foo', 'bar')
fp = StringIO('Speak softly')
fp = BytesIO(b'Speak softly')
# Can't overwrite directory
self.assertRaises(
ftplib.error_perm, conn.storbinary, 'STOR /test', fp)
fp = StringIO('Charity never faileth')
fp = BytesIO(b'Charity never faileth')
# Successful write
conn.storbinary('STOR /test/stuff', fp)
self.assertEqual(self.__fs.files['test']['stuff'].data,
'Charity never faileth')
b'Charity never faileth')
finally:
conn.close()
# Make sure no garbage was left behind.
Expand All @@ -369,10 +369,10 @@ def testSTOR_over(self):
try:
conn.connect(LOCALHOST, self.port)
conn.login('foo', 'bar')
fp = StringIO('Charity never faileth')
fp = BytesIO(b'Charity never faileth')
conn.storbinary('STOR /test/existing', fp)
self.assertEqual(self.__fs.files['test']['existing'].data,
'Charity never faileth')
b'Charity never faileth')
finally:
conn.close()
# Make sure no garbage was left behind.
Expand Down
8 changes: 4 additions & 4 deletions src/zope/server/ftp/tests/test_publisher.py
Expand Up @@ -18,9 +18,9 @@
from zope.publisher.publish import mapply

try:
from cStringIO import StringIO
from cStringIO import StringIO as BytesIO
except ImportError:
from io import StringIO
from io import BytesIO

from . import demofs
from .fstests import FileSystemTests
Expand Down Expand Up @@ -109,8 +109,8 @@ def setUp(self):
root.grant('bob', demofs.write)
fs = DemoFileSystem(root, 'bob')
fs.mkdir(self.dir_name)
fs.writefile(self.file_name, StringIO(self.file_contents))
fs.writefile(self.unwritable_filename, StringIO("save this"))
fs.writefile(self.file_name, BytesIO(self.file_contents))
fs.writefile(self.unwritable_filename, BytesIO(b"save this"))
fs.get(self.unwritable_filename).revoke('bob', demofs.write)

# import only now to prevent the testrunner from importing it too early
Expand Down
6 changes: 3 additions & 3 deletions src/zope/server/linereceiver/linecommandparser.py
Expand Up @@ -24,8 +24,8 @@ class LineCommandParser(object):
# See IStreamConsumer
completed = 0
inbuf = b''
cmd = b''
args = b''
cmd = ''
args = ''
empty = 0

max_line_length = 1024 # Not a hard limit
Expand Down Expand Up @@ -60,7 +60,7 @@ def received(self, data):
return len(s)

def parseLine(self, line):
parts = line.split(b' ', 1)
parts = line.decode('latin-1').split(' ', 1)
if len(parts) == 2:
self.cmd, self.args = parts
else:
Expand Down
2 changes: 1 addition & 1 deletion src/zope/server/linereceiver/lineserverchannel.py
Expand Up @@ -97,7 +97,7 @@ def reply(self, code, args=(), flush=1):
except:
msg = self.reply_error %code

self.write('%s\r\n' %msg)
self.write(b'%s\r\n' %msg.encode('utf-8'))

if flush:
self.flush(0)
Expand Down

0 comments on commit 030b452

Please sign in to comment.