webish: append save=true to a GET URL to save-to-disk. Closes .

This commit is contained in:
Brian Warner 2007-12-11 18:04:44 -07:00
parent bcf2ed8f64
commit 74820cc3de
2 changed files with 20 additions and 3 deletions
src/allmydata

@ -344,6 +344,13 @@ class Web(WebMixin, unittest.TestCase):
d.addCallback(self.failUnlessIsBarDotTxt)
return d
def test_GET_FILEURL_save(self):
d = self.GET(self.public_url + "/foo/bar.txt?save=bar.txt")
# TODO: look at the headers, expect a Content-Disposition: attachment
# header.
d.addCallback(self.failUnlessIsBarDotTxt)
return d
def test_GET_FILEURL_download(self):
d = self.GET(self.public_url + "/foo/bar.txt?t=download")
d.addCallback(self.failUnlessIsBarDotTxt)

@ -360,12 +360,13 @@ class Directory(rend.Page):
class WebDownloadTarget:
implements(IDownloadTarget, IConsumer)
def __init__(self, req, content_type, content_encoding):
def __init__(self, req, content_type, content_encoding, save_to_file):
self._req = req
self._content_type = content_type
self._content_encoding = content_encoding
self._opened = False
self._producer = None
self._save_to_file = save_to_file
def registerProducer(self, producer, streaming):
self._req.registerProducer(producer, streaming)
@ -378,6 +379,12 @@ class WebDownloadTarget:
if self._content_encoding:
self._req.setHeader("content-encoding", self._content_encoding)
self._req.setHeader("content-length", str(size))
if self._save_to_file is not None:
# tell the browser to save the file rather display it
# TODO: quote save_to_file properly
self._req.setHeader("content-disposition",
'attachment; filename="%s"'
% self._save_to_file)
def write(self, data):
self._req.write(data)
@ -425,8 +432,11 @@ class FileDownloader(resource.Resource):
static.File.contentTypes,
static.File.contentEncodings,
defaultType="text/plain")
d = self._filenode.download(WebDownloadTarget(req, type, encoding))
save_to_file = None
if "save" in req.args:
save_to_file = self._name
wdt = WebDownloadTarget(req, type, encoding, save_to_file)
d = self._filenode.download(wdt)
# exceptions during download are handled by the WebDownloadTarget
d.addErrback(lambda why: None)
return server.NOT_DONE_YET