Bug 794606 - Make resuming a download correctly share the privacy status of the original download. r=mak
☠☠ backed out by 1267ae44c023 ☠ ☠
authorJosh Matthews <josh@joshmatthews.net>
Thu, 04 Oct 2012 15:08:28 -0400
changeset 115581 e5269e137290782c7f11d98078aaf6112e1b0581
parent 115580 61dbc8b4ca76a46d9cee120fdf187c10bbcca367
child 115582 e94dbc151121ef4fefeda5a2655238c0d6c6f065
push id1
push usersledru@mozilla.com
push dateThu, 04 Dec 2014 17:57:20 +0000
reviewersmak
bugs794606
milestone18.0a1
Bug 794606 - Make resuming a download correctly share the privacy status of the original download. r=mak
toolkit/components/downloads/nsDownloadManager.cpp
toolkit/components/downloads/test/unit/head_download_manager.js
toolkit/components/downloads/test/unit/test_private_resume.js
toolkit/components/downloads/test/unit/xpcshell.ini
--- a/toolkit/components/downloads/nsDownloadManager.cpp
+++ b/toolkit/components/downloads/nsDownloadManager.cpp
@@ -2984,16 +2984,21 @@ nsDownload::Resume()
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Create a new channel for the source URI
   nsCOMPtr<nsIChannel> channel;
   nsCOMPtr<nsIInterfaceRequestor> ir(do_QueryInterface(wbp));
   rv = NS_NewChannel(getter_AddRefs(channel), mSource, nullptr, nullptr, ir);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  nsCOMPtr<nsIPrivateBrowsingChannel> pbChannel = do_QueryInterface(channel);
+  if (pbChannel) {
+    pbChannel->SetPrivate(mDownloadManager->mInPrivateBrowsing);
+  }
+
   // Make sure we can get a file, either the temporary or the real target, for
   // both purposes of file size and a target to write to
   nsCOMPtr<nsIFile> targetLocalFile(mTempFile);
   if (!targetLocalFile) {
     rv = GetTargetFile(getter_AddRefs(targetLocalFile));
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
--- a/toolkit/components/downloads/test/unit/head_download_manager.js
+++ b/toolkit/components/downloads/test/unit/head_download_manager.js
@@ -106,16 +106,17 @@ function addDownload(aParams)
                 .createInstance(Ci.nsIWebBrowserPersist);
   persist.persistFlags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
                          nsIWBP.PERSIST_FLAGS_BYPASS_CACHE |
                          nsIWBP.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
 
   // it is part of the active downloads the moment addDownload is called
   gDownloadCount++;
 
+  let dm = downloadUtils.downloadManager;
   var dl = dm.addDownload(Ci.nsIDownloadManager.DOWNLOAD_TYPE_DOWNLOAD,
                           createURI(aParams.sourceURI),
                           createURI(aParams.targetFile), aParams.downloadName, null,
                           Math.round(Date.now() * 1000), null, persist, aParams.isPrivate);
 
   // This will throw if it isn't found, and that would mean test failure, so no
   // try catch block
   var test = dm.getDownload(dl.id);
new file mode 100644
--- /dev/null
+++ b/toolkit/components/downloads/test/unit/test_private_resume.js
@@ -0,0 +1,124 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+this.__defineGetter__("pb", function () {
+  delete this.pb;
+  try {
+    return this.pb = Cc["@mozilla.org/privatebrowsing;1"].
+                     getService(Ci.nsIPrivateBrowsingService);
+  } catch (e) {}
+  return this.pb = null;
+});
+
+// Public request gets times=0 cookie, completes
+// Private request gets times=1 cookie, canceled
+// Private resumed request sends times=1 cookie, completes
+
+function run_test() {
+  do_test_pending();
+  let httpserv = new HttpServer();
+
+  Services.prefs.setBoolPref("browser.privatebrowsing.keep_current_session", true);
+
+  let times = 0;
+  httpserv.registerPathHandler("/head_download_manager.js", function (meta, response) {
+    response.setHeader("Content-Type", "text/plain", false);
+    response.setStatusLine("1.1", !meta.hasHeader('range') ? 200 : 206);
+
+    // Set a cookie if none is sent with the request. Public and private requests
+    // should therefore receive different cookies, so we can tell if the resumed
+    // request is actually treated as private or not.
+    if (!meta.hasHeader('Cookie')) {
+      do_check_true(times == 0 || times == 1);
+      response.setHeader('Set-Cookie', 'times=' + times++);
+    } else {
+      do_check_eq(times, 2);
+      do_check_eq(meta.getHeader('Cookie'), 'times=1');
+    }
+    let full = "";
+    let body = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; //60
+    for (var i = 0; i < 1000; i++) {
+      full += body;      
+    }
+    response.write(full);
+  });
+  httpserv.start(4444);
+
+  let state = 0;
+
+  let listener = {
+    onDownloadStateChange: function(aState, aDownload) {
+      switch (aDownload.state) {
+        case downloadUtils.downloadManager.DOWNLOAD_DOWNLOADING:
+          // We only care about the private download
+          if (state != 1)
+            break;
+
+          state++;
+          do_check_true(aDownload.resumable);
+
+          downloadUtils.downloadManager.pauseDownload(aDownload.id);
+          do_check_eq(aDownload.state, downloadUtils.downloadManager.DOWNLOAD_PAUSED);
+
+          do_execute_soon(function() {
+            downloadUtils.downloadManager.resumeDownload(aDownload.id);
+          });
+          break;
+
+        case downloadUtils.downloadManager.DOWNLOAD_FINISHED:
+          if (state == 0) {
+            do_execute_soon(function() {
+              // Perform an identical request but in private mode.
+              // It should receive a different cookie than the
+              // public request.
+
+              state++;
+                              
+              pb.privateBrowsingEnabled = true;
+
+              addDownload({
+                isPrivate: pb.privateBrowsingEnabled,
+                sourceURI: downloadCSource,
+                downloadName: downloadCName + "!!!",
+                runBeforeStart: function (aDownload) {
+                  // Check that dl is retrievable
+                  do_check_eq(downloadUtils.downloadManager.activeDownloadCount, 1);
+                }
+              });
+            });
+          } else if (state == 2) {
+            // We're done here.
+            do_execute_soon(function() {
+              pb.privateBrowsingEnabled = false;
+              Services.prefs.clearUserPref("browser.privatebrowsing.keep_current_session");
+              httpserv.stop(do_test_finished);
+            });
+          }
+          break;
+
+        default:
+          break;
+      }
+    },
+    onStateChange: function(a, b, c, d, e) { },
+    onProgressChange: function(a, b, c, d, e, f, g) { },
+    onSecurityChange: function(a, b, c, d) { }
+  };
+
+  downloadUtils.downloadManager.addListener(listener);
+
+  const downloadCSource = "http://localhost:4444/head_download_manager.js";
+  const downloadCName = "download-C";
+
+  // First a public download that completes without interruption.
+  let dl = addDownload({
+    isPrivate: pb.privateBrowsingEnabled,
+    sourceURI: downloadCSource,
+    downloadName: downloadCName,
+    runBeforeStart: function (aDownload) {
+      // Check that dl is retrievable
+      do_check_eq(downloadUtils.downloadManager.activeDownloadCount, 1);
+    }
+  });
+}
\ No newline at end of file
--- a/toolkit/components/downloads/test/unit/xpcshell.ini
+++ b/toolkit/components/downloads/test/unit/xpcshell.ini
@@ -16,13 +16,14 @@ skip-if = os == "android"
 [test_download_manager.js]
 [test_download_samename.js]
 # Bug 676989: test hangs consistently on Android
 skip-if = os == "android" 
 [test_history_expiration.js]
 [test_memory_db_support.js]
 [test_offline_support.js]
 [test_old_download_files_removed.js]
+[test_private_resume.js]
 [test_privatebrowsing.js]
 [test_privatebrowsing_cancel.js]
 [test_removeDownloadsByTimeframe.js]
 [test_resume.js]
 [test_sleep_wake.js]