2424# the dummy data returned by server over the data channel when
2525# RETR, LIST and NLST commands are issued
2626RETR_DATA = 'abcde12345\r \n ' * 1000
27+ RETR_TEXT = 'abcd\xe9 12345\r \n ' * 1000
2728LIST_DATA = 'foo\r \n bar\r \n '
2829NLST_DATA = 'foo\r \n bar\r \n '
2930
@@ -37,7 +38,7 @@ def __init__(self, conn, baseclass):
3738 self .baseclass .last_received_data = ''
3839
3940 def handle_read (self ):
40- self .baseclass .last_received_data += self .recv (1024 ).decode ('ascii ' )
41+ self .baseclass .last_received_data += self .recv (1024 ).decode ('latin-1 ' )
4142
4243 def handle_close (self ):
4344 # XXX: this method can be called many times in a row for a single
@@ -49,7 +50,7 @@ def handle_close(self):
4950 self .dtp_conn_closed = True
5051
5152 def push (self , what ):
52- super (DummyDTPHandler , self ).push (what .encode ('ascii ' ))
53+ super (DummyDTPHandler , self ).push (what .encode ('latin-1 ' ))
5354
5455 def handle_error (self ):
5556 raise
@@ -68,6 +69,7 @@ def __init__(self, conn):
6869 self .last_received_data = ''
6970 self .next_response = ''
7071 self .rest = None
72+ self .current_type = 'a'
7173 self .push ('220 welcome' )
7274
7375 def collect_incoming_data (self , data ):
@@ -175,7 +177,16 @@ def cmd_pwd(self, arg):
175177 self .push ('257 "pwd ok"' )
176178
177179 def cmd_type (self , arg ):
178- self .push ('200 type ok' )
180+ # ASCII type
181+ if arg .lower () == 'a' :
182+ self .current_type = 'a'
183+ self .push ('200 type ok' )
184+ # Binary type
185+ elif arg .lower () == 'i' :
186+ self .current_type = 'i'
187+ self .push ('200 type ok' )
188+ else :
189+ self .push ('504 unsupported type' )
179190
180191 def cmd_quit (self , arg ):
181192 self .push ('221 quit ok' )
@@ -194,7 +205,10 @@ def cmd_retr(self, arg):
194205 offset = int (self .rest )
195206 else :
196207 offset = 0
197- self .dtp .push (RETR_DATA [offset :])
208+ if self .current_type == 'i' :
209+ self .dtp .push (RETR_DATA [offset :])
210+ else :
211+ self .dtp .push (RETR_TEXT [offset :])
198212 self .dtp .close_when_done ()
199213 self .rest = None
200214
@@ -511,7 +525,7 @@ def callback(data):
511525 def test_retrlines (self ):
512526 received = []
513527 self .client .retrlines ('retr' , received .append )
514- self .assertEqual ('' .join (received ), RETR_DATA .replace ('\r \n ' , '' ))
528+ self .assertEqual ('' .join (received ), RETR_TEXT .replace ('\r \n ' , '' ))
515529
516530 def test_storbinary (self ):
517531 f = io .BytesIO (RETR_DATA .encode ('ascii' ))
@@ -530,7 +544,7 @@ def test_storbinary_rest(self):
530544 self .client .storbinary ('stor' , f , rest = r )
531545 self .assertEqual (self .server .handler_instance .rest , str (r ))
532546
533- def test_storlines (self ):
547+ def test_storlines_bytes (self ):
534548 f = io .BytesIO (RETR_DATA .replace ('\r \n ' , '\n ' ).encode ('ascii' ))
535549 self .client .storlines ('stor' , f )
536550 self .assertEqual (self .server .handler_instance .last_received_data , RETR_DATA )
@@ -540,6 +554,16 @@ def test_storlines(self):
540554 self .client .storlines ('stor foo' , f , callback = lambda x : flag .append (None ))
541555 self .assertTrue (flag )
542556
557+ def test_storlines_str (self ):
558+ f = io .StringIO (RETR_TEXT .replace ('\r \n ' , '\n ' ))
559+ self .client .storlines ('stor' , f )
560+ self .assertEqual (self .server .handler_instance .last_received_data , RETR_TEXT )
561+ # test new callback arg
562+ flag = []
563+ f .seek (0 )
564+ self .client .storlines ('stor foo' , f , callback = lambda x : flag .append (None ))
565+ self .assertTrue (flag )
566+
543567 def test_nlst (self ):
544568 self .client .nlst ()
545569 self .assertEqual (self .client .nlst (), NLST_DATA .split ('\r \n ' )[:- 1 ])
0 commit comments