diff --git a/twisted/protocols/ftp.py b/twisted/protocols/ftp.py
index 19504a7..8f71621 100644
a
|
b
|
class FTP(object, basic.LineReceiver, policies.TimeoutMixin): |
1163 | 1163 | self.setTimeout(self.factory.timeOut) |
1164 | 1164 | return result |
1165 | 1165 | |
1166 | | def cbSent(result): |
1167 | | return (TXFR_COMPLETE_OK,) |
| 1166 | def cbOpened(file): |
| 1167 | """ |
| 1168 | File was opend for reading so launch the data channel transfer via |
| 1169 | the file consumer. |
| 1170 | """ |
| 1171 | d = file.receive() |
| 1172 | d.addCallback(cbConsumer) |
| 1173 | d.addCallback(lambda ignored: file.close()) |
| 1174 | d.addCallbacks(cbSent, ebSent) |
| 1175 | return d |
1168 | 1176 | |
1169 | | def ebSent(err): |
1170 | | log.msg("Unexpected error receiving file from client:") |
1171 | | log.err(err) |
1172 | | if err.check(FTPCmdError): |
1173 | | return err |
1174 | | return (CNX_CLOSED_TXFR_ABORTED,) |
| 1177 | def ebOpened(err): |
| 1178 | """ |
| 1179 | Called when failed to open the file for reading. |
| 1180 | |
| 1181 | For known errors, return the FTP error code. |
| 1182 | For all other, return a file not found error. |
| 1183 | """ |
| 1184 | if isinstance(err.value, FTPCmdError): |
| 1185 | return (err.value.errorCode, '/'.join(newsegs)) |
| 1186 | return (FILE_NOT_FOUND, '/'.join(newsegs)) |
1175 | 1187 | |
1176 | 1188 | def cbConsumer(cons): |
| 1189 | """ |
| 1190 | Called when file was opended for reading. |
| 1191 | |
| 1192 | Prepared the handler for data transfer and send the response |
| 1193 | to the command channel. |
| 1194 | """ |
1177 | 1195 | if not self.binary: |
1178 | 1196 | cons = ASCIIConsumerWrapper(cons) |
1179 | 1197 | |
… |
… |
class FTP(object, basic.LineReceiver, policies.TimeoutMixin): |
1187 | 1205 | |
1188 | 1206 | return d |
1189 | 1207 | |
1190 | | def cbOpened(file): |
1191 | | d = file.receive() |
1192 | | d.addCallback(cbConsumer) |
1193 | | d.addCallback(lambda ignored: file.close()) |
1194 | | d.addCallbacks(cbSent, ebSent) |
1195 | | return d |
| 1208 | def cbSent(result): |
| 1209 | """ |
| 1210 | Called from data transport when tranfer is done. |
| 1211 | """ |
| 1212 | return (TXFR_COMPLETE_OK,) |
1196 | 1213 | |
1197 | | def ebOpened(err): |
1198 | | if not err.check(PermissionDeniedError, FileNotFoundError, IsNotADirectoryError): |
1199 | | log.msg("Unexpected error attempting to open file for upload:") |
| 1214 | def ebSent(err): |
| 1215 | """ |
| 1216 | Called from data transport when there are errors during the |
| 1217 | transfer. |
| 1218 | """ |
| 1219 | if err.check(FTPCmdError): |
| 1220 | return err |
| 1221 | else: |
| 1222 | log.msg("Unexpected error receiving file from client:") |
1200 | 1223 | log.err(err) |
1201 | | if isinstance(err.value, FTPCmdError): |
1202 | | return (err.value.errorCode, '/'.join(newsegs)) |
1203 | | return (FILE_NOT_FOUND, '/'.join(newsegs)) |
| 1224 | return (CNX_CLOSED_TXFR_ABORTED,) |
1204 | 1225 | |
1205 | 1226 | d = self.shell.openForWriting(newsegs) |
1206 | 1227 | d.addCallbacks(cbOpened, ebOpened) |
diff --git a/twisted/test/test_ftp.py b/twisted/test/test_ftp.py
index 7ba434e..4befda0 100644
a
|
b
|
class FTPServerTestCaseAdvancedClient(FTPServerTestCase): |
541 | 541 | # Make a failing file writer. |
542 | 542 | class FailingFileWriter(ftp._FileWriter): |
543 | 543 | def receive(self): |
544 | | return defer.fail(ftp.IsNotADirectoryError("blah")) |
| 544 | return defer.fail(ftp.IsADirectoryError("blah")) |
545 | 545 | |
546 | 546 | def failingSTOR(a, b): |
547 | 547 | return defer.succeed(FailingFileWriter(None)) |
… |
… |
class FTPServerTestCaseAdvancedClient(FTPServerTestCase): |
555 | 555 | res.trap(ftp.CommandFailed) |
556 | 556 | self.assertEqual( |
557 | 557 | res.value.args[0][0], |
558 | | "550 Cannot rmd, blah is not a directory") |
| 558 | "550 blah: is a directory") |
559 | 559 | d1, d2 = self.client.storeFile('failing_file') |
560 | 560 | d2.addErrback(eb) |
561 | 561 | return defer.gatherResults([d1, d2]) |