diff options
author | erikkay@google.com <erikkay@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-12-23 19:39:42 +0000 |
---|---|---|
committer | erikkay@google.com <erikkay@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-12-23 19:39:42 +0000 |
commit | 25963381f55ce81bf44e3d511ec44e634942204f (patch) | |
tree | 5182d1adaa98faf2c5d35c2c89687cff03a23504 /third_party/pyftpdlib/demo/throttled_ftpd.py | |
parent | bfe835e3e3d5aea1415886dec94bdc760db6cded (diff) | |
download | chromium_src-25963381f55ce81bf44e3d511ec44e634942204f.zip chromium_src-25963381f55ce81bf44e3d511ec44e634942204f.tar.gz chromium_src-25963381f55ce81bf44e3d511ec44e634942204f.tar.bz2 |
Add pyftpdlib for future ftp unit tests.
From http://codereview.chromium.org/16429/ by contributor ibrar.ahmed@gmail.com
TBR=pamg
Review URL: http://codereview.chromium.org/16454
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@7427 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party/pyftpdlib/demo/throttled_ftpd.py')
-rw-r--r-- | third_party/pyftpdlib/demo/throttled_ftpd.py | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/third_party/pyftpdlib/demo/throttled_ftpd.py b/third_party/pyftpdlib/demo/throttled_ftpd.py new file mode 100644 index 0000000..dd3395c --- /dev/null +++ b/third_party/pyftpdlib/demo/throttled_ftpd.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# throttled_ftpd.py + +"""ftpd supporting bandwidth throttling capabilities for data transfer. +""" + +import os +import time +import asyncore + +from pyftpdlib import ftpserver + + +class ThrottledDTPHandler(ftpserver.DTPHandler): + """A DTPHandler which wraps sending and receiving in a data counter + and temporarily sleeps the channel so that you burst to no more than + x Kb/sec average. + """ + + # maximum number of bytes to transmit in a second (0 == no limit) + read_limit = 0 + write_limit = 0 + + def __init__(self, sock_obj, cmd_channel): + ftpserver.DTPHandler.__init__(self, sock_obj, cmd_channel) + self._timenext = 0 + self._datacount = 0 + self._sleeping = False + self._throttler = None + + def readable(self): + return not self._sleeping and ftpserver.DTPHandler.readable(self) + + def writable(self): + return not self._sleeping and ftpserver.DTPHandler.writable(self) + + def recv(self, buffer_size): + chunk = asyncore.dispatcher.recv(self, buffer_size) + if self.read_limit: + self.throttle_bandwidth(len(chunk), self.read_limit) + return chunk + + def send(self, data): + num_sent = asyncore.dispatcher.send(self, data) + if self.write_limit: + self.throttle_bandwidth(num_sent, self.write_limit) + return num_sent + + def throttle_bandwidth(self, len_chunk, max_speed): + """A method which counts data transmitted so that you burst to + no more than x Kb/sec average. + """ + self._datacount += len_chunk + if self._datacount >= max_speed: + self._datacount = 0 + now = time.time() + sleepfor = self._timenext - now + if sleepfor > 0: + # we've passed bandwidth limits + def unsleep(): + self._sleeping = False + self._sleeping = True + self._throttler = ftpserver.CallLater(sleepfor * 2, unsleep) + self._timenext = now + 1 + + def close(self): + if self._throttler is not None and not self._throttler.cancelled: + self._throttler.cancel() + ftpserver.DTPHandler.close(self) + + +if __name__ == '__main__': + authorizer = ftpserver.DummyAuthorizer() + authorizer.add_user('user', '12345', os.getcwd(), perm='elradfmw') + authorizer.add_anonymous(os.getcwd()) + + # use the modified DTPHandler class and set a speed limit for both + # sending and receiving + dtp_handler = ThrottledDTPHandler + dtp_handler.read_limit = 30072 # 30 Kb/sec (30 * 1024) + dtp_handler.write_limit = 30072 # 30 Kb/sec (30 * 1024) + + ftp_handler = ftpserver.FTPHandler + ftp_handler.authorizer = authorizer + # have the ftp handler use the different dtp handler + ftp_handler.dtp_handler = dtp_handler + + ftpd = ftpserver.FTPServer(('', 21), ftp_handler) + ftpd.serve_forever() |