def ftp_RNTO(self, toName): fromName = self._fromName del self._fromName self.state = self.AUTHED try: fromsegs = toSegments(self.workingDirectory, fromName) tosegs = toSegments(self.workingDirectory, toName) except InvalidPath: return defer.fail(FileNotFoundError(fromName)) # TODO: return succeed((REQ_FILE_ACTN_COMPLETED_OK,))
def testNormalizer(self): for inp, outp in [('a', ['a']), ('/a', ['a']), ('/', []), ('a/b/c', ['a', 'b', 'c']), ('/a/b/c', ['a', 'b', 'c']), ('/a/', ['a']), ('a/', ['a'])]: self.assertEquals(ftp.toSegments([], inp), outp) for inp, outp in [('b', ['a', 'b']), ('b/', ['a', 'b']), ('/b', ['b']), ('/b/', ['b']), ('b/c', ['a', 'b', 'c']), ('b/c/', ['a', 'b', 'c']), ('/b/c', ['b', 'c']), ('/b/c/', ['b', 'c'])]: self.assertEquals(ftp.toSegments(['a'], inp), outp) for inp, outp in [('//', []), ('//a', ['a']), ('a//', ['a']), ('a//b', ['a', 'b'])]: self.assertEquals(ftp.toSegments([], inp), outp) for inp, outp in [('//', []), ('//b', ['b']), ('b//c', ['a', 'b', 'c'])]: self.assertEquals(ftp.toSegments(['a'], inp), outp) for inp, outp in [('..', []), ('../', []), ('a/..', ['x']), ('/a/..', []), ('/a/b/..', ['a']), ('/a/b/../', ['a']), ('/a/b/../c', ['a', 'c']), ('/a/b/../c/', ['a', 'c']), ('/a/b/../../c', ['c']), ('/a/b/../../c/', ['c']), ('/a/b/../../c/..', []), ('/a/b/../../c/../', [])]: self.assertEquals(ftp.toSegments(['x'], inp), outp) for inp in ['..', '../', 'a/../..', 'a/../../', '/..', '/../', '/a/../..', '/a/../../', '/a/b/../../..']: self.assertRaises(ftp.InvalidPath, ftp.toSegments, [], inp) for inp in ['../..', '../../', '../a/../..']: self.assertRaises(ftp.InvalidPath, ftp.toSegments, ['x'], inp)
def testNormalizer(self): for inp, outp in [ ("a", ["a"]), ("/a", ["a"]), ("/", []), ("a/b/c", ["a", "b", "c"]), ("/a/b/c", ["a", "b", "c"]), ("/a/", ["a"]), ("a/", ["a"]), ]: self.assertEquals(ftp.toSegments([], inp), outp) for inp, outp in [ ("b", ["a", "b"]), ("b/", ["a", "b"]), ("/b", ["b"]), ("/b/", ["b"]), ("b/c", ["a", "b", "c"]), ("b/c/", ["a", "b", "c"]), ("/b/c", ["b", "c"]), ("/b/c/", ["b", "c"]), ]: self.assertEquals(ftp.toSegments(["a"], inp), outp) for inp, outp in [("//", []), ("//a", ["a"]), ("a//", ["a"]), ("a//b", ["a", "b"])]: self.assertEquals(ftp.toSegments([], inp), outp) for inp, outp in [("//", []), ("//b", ["b"]), ("b//c", ["a", "b", "c"])]: self.assertEquals(ftp.toSegments(["a"], inp), outp) for inp, outp in [ ("..", []), ("../", []), ("a/..", ["x"]), ("/a/..", []), ("/a/b/..", ["a"]), ("/a/b/../", ["a"]), ("/a/b/../c", ["a", "c"]), ("/a/b/../c/", ["a", "c"]), ("/a/b/../../c", ["c"]), ("/a/b/../../c/", ["c"]), ("/a/b/../../c/..", []), ("/a/b/../../c/../", []), ]: self.assertEquals(ftp.toSegments(["x"], inp), outp) for inp in ["..", "../", "a/../..", "a/../../", "/..", "/../", "/a/../..", "/a/../../", "/a/b/../../.."]: self.assertRaises(ftp.InvalidPath, ftp.toSegments, [], inp) for inp in ["../..", "../../", "../a/../.."]: self.assertRaises(ftp.InvalidPath, ftp.toSegments, ["x"], inp)
def ftp_RETR(self, path): if self.dtpInstance is None: raise BadCmdSequenceError('PORT or PASV required before RETR') try: newsegs = toSegments(self.workingDirectory, path) except InvalidPath: return defer.fail(FileNotFoundError(path)) # XXX For now, just disable the timeout. Later we'll want to # leave it active and have the DTP connection reset it # periodically. self.setTimeout(None) # Put it back later # And away she goes if not self.binary: consumer = ASCIIConsumerWrapper(self.dtpInstance) else: consumer = self.dtpInstance pth = '/'.join(newsegs) restore_dir = tmpfile.make_dir('restore', prefix=('_'.join(newsegs) + '_')) ret = api.file_download_start(pth, restore_dir, wait_result=True) d = Deferred() d.addCallback(self._cbReadOpened, consumer) d.addErrback(self._ebReadOpened, newsegs) d.addBoth(self._enableTimeoutLater) if isinstance(ret, dict): # if ret['status'] != 'OK': # return defer.fail(FileNotFoundError(path)) self._cbRestoreDone(ret, newsegs, d) return d ret.addCallback(self._cbRestoreDone, newsegs, d) ret.addErrback(lambda err: lg.exc(err)) return d
def ftp_DELE(self, path): try: newsegs = toSegments(self.workingDirectory, path) except InvalidPath: return defer.fail(FileNotFoundError(path)) full_path = '/'.join(newsegs) ret = api.file_delete(full_path) if ret['status'] != 'OK': return defer.fail(FileNotFoundError(str(ret['errors']))) return succeed((REQ_FILE_ACTN_COMPLETED_OK,))
def ftp_MKD(self, path): try: newsegs = toSegments(self.workingDirectory, path) except InvalidPath: return defer.fail(FileNotFoundError(path)) full_path = '/'.join(newsegs) ret = api.file_create(full_path, as_folder=True) if ret['status'] != 'OK': return defer.fail(FileExistsError(str(ret['errors']))) return succeed((MKD_REPLY, path))
def ftp_SIZE(self, path): try: newsegs = toSegments(self.workingDirectory, path) except InvalidPath: return defer.fail(FileNotFoundError(path)) full_path = '/'.join(newsegs) ret = api.file_info(full_path) if ret['status'] != 'OK': return defer.fail(FileNotFoundError(path)) return succeed((FILE_STATUS, str(ret['size']), ))
def testNormalizer(self): for inp, outp in [('a', ['a']), ('/a', ['a']), ('/', []), ('a/b/c', ['a', 'b', 'c']), ('/a/b/c', ['a', 'b', 'c']), ('/a/', ['a']), ('a/', ['a'])]: self.assertEquals(ftp.toSegments([], inp), outp) for inp, outp in [('b', ['a', 'b']), ('b/', ['a', 'b']), ('/b', ['b']), ('/b/', ['b']), ('b/c', ['a', 'b', 'c']), ('b/c/', ['a', 'b', 'c']), ('/b/c', ['b', 'c']), ('/b/c/', ['b', 'c'])]: self.assertEquals(ftp.toSegments(['a'], inp), outp) for inp, outp in [('//', []), ('//a', ['a']), ('a//', ['a']), ('a//b', ['a', 'b'])]: self.assertEquals(ftp.toSegments([], inp), outp) for inp, outp in [('//', []), ('//b', ['b']), ('b//c', ['a', 'b', 'c'])]: self.assertEquals(ftp.toSegments(['a'], inp), outp) for inp, outp in [('..', []), ('../', []), ('a/..', ['x']), ('/a/..', []), ('/a/b/..', ['a']), ('/a/b/../', ['a']), ('/a/b/../c', ['a', 'c']), ('/a/b/../c/', ['a', 'c']), ('/a/b/../../c', ['c']), ('/a/b/../../c/', ['c']), ('/a/b/../../c/..', []), ('/a/b/../../c/../', [])]: self.assertEquals(ftp.toSegments(['x'], inp), outp) for inp in [ '..', '../', 'a/../..', 'a/../../', '/..', '/../', '/a/../..', '/a/../../', '/a/b/../../..' ]: self.assertRaises(ftp.InvalidPath, ftp.toSegments, [], inp) for inp in ['../..', '../../', '../a/../..']: self.assertRaises(ftp.InvalidPath, ftp.toSegments, ['x'], inp)
def ftp_STOR(self, path): if self.dtpInstance is None: raise BadCmdSequenceError('PORT or PASV required before STOR') try: newsegs = toSegments(self.workingDirectory, path) except InvalidPath: return defer.fail(FileNotFoundError(path)) # parent_path = '/' + ('/'.join(newsegs[:-1])) # parent_item = backup_fs.GetByPath(parent_path) # if not parent_item: # return defer.fail(FileNotFoundError(parent_path)) # XXX For now, just disable the timeout. Later we'll want to # leave it active and have the DTP connection reset it # periodically. self.setTimeout(None) # Put it back later # , prefix=(newsegs[-1] + '_') upload_dir = tmpfile.make_dir('backup', extension='.ftp') if not upload_dir: return defer.fail(FileNotFoundError(path)) upload_filename = os.path.join(upload_dir, newsegs[-1]) fp = filepath.FilePath(upload_filename) try: fObj = fp.open('w') except (IOError, OSError) as e: return errnoToFailure(e.errno, path) except: return defer.fail(FileNotFoundError(path)) # TODO: remove file after all # d.addCallback(lambda ignored: file.close(); and remove file) # d = Deferred() d = Deferred() d.addCallback(self._cbWriteOpened, upload_filename, newsegs) d.addErrback(self._ebWriteOpened, newsegs) d.addBoth(self._enableTimeoutLater) d.callback(_FileWriter(fObj)) # d.addCallbacks(self._cbFileRecevied, self._ebFileReceived) # fw = _FileWriter(fObj) # receive_defer = fw.receive() # receive_defer.addBoth(self._enableTimeoutLater) # receive_defer.addCallback(self._prepareConsumer) # receive_defer.addCallback(self._startFileBackup, upload_filename, newsegs, d) # receive_defer.addErrback(lambda err: d.errback(FileNotFoundError(path))) return d
def ftp_LIST(self, path=''): # Uh, for now, do this retarded thing. if self.dtpInstance is None or not self.dtpInstance.isConnected: return defer.fail( BadCmdSequenceError('must send PORT or PASV before RETR')) # Various clients send flags like -L or -al etc. We just ignore them. if path.lower() in ['-a', '-l', '-la', '-al']: path = '' try: segments = toSegments(self.workingDirectory, path) except InvalidPath: return defer.fail(FileNotFoundError(path)) pth = '/'.join(segments) ret = api.files_list(pth) if ret['status'] != 'OK': return defer.fail(FileNotFoundError(path)) lst = ret['result'] result = [] for itm in lst: if itm['path'] == 'index': continue # known_size = max(itm[7].size, 0) # if itm['versions']: # known_size = itm['size'] # else: # known_size = 1 known_size = max(itm['local_size'], 0) key_alias, _, _ = itm['key_id'].partition('$') result.append(( os.path.basename(itm['path']), [ # name known_size, # size True if itm['type'] == 'dir' else False, # folder or file ? filepath.Permissions(0o7777), # permissions 0, # hardlinks time.mktime( time.strptime(itm['latest'], '%Y-%m-%d %H:%M:%S')) if itm['latest'] else None, # time itm['customer'], # owner key_alias, # group ], )) d = Deferred() d.addCallback(self._dirListingResponse) d.callback(result) return d
def ftp_CWD(self, path): try: segments = toSegments(self.workingDirectory, path) except InvalidPath: # XXX Eh, what to fail with here? return defer.fail(FileNotFoundError(path)) pth = '/'.join(segments) d = Deferred() d.addCallback(lambda r: self._accessGrantedResponse(r, segments)) if not pth or pth == '/': d.callback(None) return d ret = api.file_info(pth, include_uploads=False, include_downloads=False) if ret['status'] != 'OK': d.errback(FileNotFoundError(path)) return d if ret['result']['type'] == 'dir': d.callback(None) else: d.errback(FileNotFoundError(path)) return d
def ftp_STOR(self, path): if self.dtpInstance is None: raise BadCmdSequenceError('PORT or PASV required before STOR') try: newsegs = toSegments(self.workingDirectory, path) print "working directory = ", self.workingDirectory print "path======", path except InvalidPath: return defer.fail(FileNotFoundError(path)) self.setTimeout(None) def enableTimeout(result): self.setTimeout(self.factory.timeOut) return result def cbOpened(file_obj): print "test1" d = file_obj.receive() print "obj receive", d print "test2" d.addCallback(cbConsumer) print "test3" d.addCallback(lambda ignored: file_obj.close()) print "test4" d.addCallbacks(cbSent, ebSent) print "test5" return d def ebOpened(err): print "testerr1" if isinstance(err.value, FTPCmdError): print "testerr2" return (err.value.errorCode, '/'.join(newsegs)) print "testerr3" log.err(err, "Unexpected error received while opening file:") return (FILE_NOT_FOUND, '/'.join(newsegs)) def cbConsumer(cons): if not self.binary: cons = ASCIIConsumerWrapper(cons) print "cons", cons d = self.dtpInstance.registerConsumer(cons) print "dtpinstance", d if self.dtpInstance.isConnected: print "reply : DATA_CNX_ALREADY_OPEN_START_XFR", DATA_CNX_ALREADY_OPEN_START_XFR self.reply(DATA_CNX_ALREADY_OPEN_START_XFR) else: print "DATA_CNX_ALREADY_OPEN_START_XFR", DATA_CNX_ALREADY_OPEN_START_XFR self.reply(FILE_STATUS_OK_OPEN_DATA_CNX) return d def cbSent(result): if callable(self.fn_uploaded): peer = self.transport.getPeer() print "peer apakah", peer self.fn_uploaded(path, peer.host) print "suksesss================" return (TXFR_COMPLETE_OK, ) def ebSent(err): print "testerr3" print "" log.err(err, "Unexpected error received during transfer:") if err.check(FTPCmdError): return err return (CNX_CLOSED_TXFR_ABORTED, ) d = self.shell.openForWriting(newsegs) print "d = ", d d.addCallbacks(cbOpened, ebOpened) print "d after callback = ", d d.addBoth(enableTimeout) print "add both ", d return d