pass
class Output:
- def __init__(self, downloadable, key):
+ def __init__(self, downloadable, key, total_length):
self.downloadable = downloadable
self._decryptor = AES.new(key=key, mode=AES.MODE_CTR,
counterstart="\x00"*16)
self._crypttext_hasher = hashutil.crypttext_hasher()
self._plaintext_hasher = hashutil.plaintext_hasher()
self.length = 0
+ self.total_length = total_length
self._segment_number = 0
self._plaintext_hash_tree = None
self._crypttext_hash_tree = None
# any memory usage beyond this.
if not self._opened:
self._opened = True
- self.downloadable.open()
+ self.downloadable.open(self.total_length)
self.downloadable.write(plaintext)
def fail(self, why):
self._size = d['size']
self._num_needed_shares = d['needed_shares']
- self._output = Output(downloadable, d['key'])
+ self._output = Output(downloadable, d['key'], self._size)
self.active_buckets = {} # k: shnum, v: bucket
self._share_buckets = [] # list of (sharenum, bucket) tuples
implements(IDownloadTarget)
def __init__(self, filename):
self._filename = filename
- def open(self):
+ def open(self, size):
self.f = open(self._filename, "wb")
return self.f
def write(self, data):
implements(IDownloadTarget)
def __init__(self):
self._data = []
- def open(self):
+ def open(self, size):
pass
def write(self, data):
self._data.append(data)
implements(IDownloadTarget)
def __init__(self, filehandle):
self._filehandle = filehandle
- def open(self):
+ def open(self, size):
pass
def write(self, data):
self._filehandle.write(data)
"""
class IDownloadTarget(Interface):
- def open():
+ def open(size):
"""Called before any calls to write() or close(). If an error
occurs before any data is available, fail() may be called without
- a previous call to open()."""
+ a previous call to open().
+
+ 'size' is the length of the file being downloaded, in bytes."""
+
def write(data):
"""Output some data to the target."""
def close():
self._content_encoding = content_encoding
self._opened = False
- def open(self):
+ def open(self, size):
self._opened = True
self._req.setHeader("content-type", self._content_type)
if self._content_encoding:
- self._req.setHeader('content-encoding', self._content_encoding)
- # TODO: it would be nice to set the size header here
+ self._req.setHeader("content-encoding", self._content_encoding)
+ self._req.setHeader("content-length", str(size))
def write(self, data):
self._req.write(data)