webish: append save=true to a GET URL to save-to-disk. Closes #222.
authorBrian Warner <warner@allmydata.com>
Wed, 12 Dec 2007 01:04:44 +0000 (18:04 -0700)
committerBrian Warner <warner@allmydata.com>
Wed, 12 Dec 2007 01:04:44 +0000 (18:04 -0700)
src/allmydata/test/test_web.py
src/allmydata/webish.py

index c3188b489b1f479d1a757c7d9e682799f9773eab..5299209c9ce001aa3ed8d94f0849f846f82bb61b 100644 (file)
@@ -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)
index 84aa6ba4b71d758e841d2955d8d9d74021becb1d..2db720d88c63097f0e6b597dc1d67f726e9fee66 100644 (file)
@@ -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