Bug 463256 - SSL sites sometimes don't load after re-entering regular browsing mode (from Private Browsing); r=mconnor,sdwilsh
☠☠ backed out by ad96e3d1ab56 ☠ ☠
authorEhsan Akhgari <ehsan.akhgari@gmail.com>
Thu, 12 Mar 2009 12:28:09 +0330
changeset 26084 113bda3be8df2698fdd52a65b54c7d24b2eda2be
parent 26083 5a5fde47ba443f03b74586b7176a02f557a449cf
child 26085 69322c1764ffd21bd5756e54a4068fcb4c4ac077
child 26088 ad96e3d1ab56c30857baab534d1b353d121dc61f
push idunknown
push userunknown
push dateunknown
reviewersmconnor, sdwilsh
bugs463256
milestone1.9.2a1pre
Bug 463256 - SSL sites sometimes don't load after re-entering regular browsing mode (from Private Browsing); r=mconnor,sdwilsh
browser/components/privatebrowsing/src/nsPrivateBrowsingService.js
browser/components/privatebrowsing/test/browser/Makefile.in
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_sslsite_transition.js
toolkit/components/downloads/test/unit/test_privatebrowsing.js
--- a/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js
+++ b/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js
@@ -270,16 +270,28 @@ PrivateBrowsingService.prototype = {
                   getService(Ci.nsISecretDecoderRing);
         sdr.logoutAndTeardown();
     
         // clear plain HTTP auth sessions
         let authMgr = Cc['@mozilla.org/network/http-auth-manager;1'].
                       getService(Ci.nsIHttpAuthManager);
         authMgr.clearAll();
 
+        // Prevent any SSL sockets from remaining open.  Without this, SSL
+        // websites may fail to load after switching the private browsing mode
+        // because the SSL sockets may still be open while the corresponding
+        // NSS resources have been destroyed by the logoutAndTeardown call
+        // above.  See bug 463256 for more information.
+        let ios = Cc["@mozilla.org/network/io-service;1"].
+                  getService(Ci.nsIIOService);
+        if (!ios.offline) {
+          ios.offline = true;
+          ios.offline = false;
+        }
+
         if (!this._inPrivateBrowsing) {
           // Clear the error console
           let consoleService = Cc["@mozilla.org/consoleservice;1"].
                                getService(Ci.nsIConsoleService);
           consoleService.logStringMessage(null); // trigger the listeners
           consoleService.reset();
         }
         break;
--- a/browser/components/privatebrowsing/test/browser/Makefile.in
+++ b/browser/components/privatebrowsing/test/browser/Makefile.in
@@ -52,12 +52,13 @@ include $(topsrcdir)/config/rules.mk
 		browser_privatebrowsing_findbar.js \
 		browser_privatebrowsing_zoom.js \
 		browser_privatebrowsing_transition.js \
 		browser_privatebrowsing_import.js \
 		browser_privatebrowsing_crh.js \
 		browser_privatebrowsing_windowtitle.js \
 		browser_privatebrowsing_windowtitle_page.html \
 		browser_privatebrowsing_urlbarfocus.js \
+		browser_privatebrowsing_sslsite_transition.js \
 		$(NULL)
 
 libs:: $(_BROWSER_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_sslsite_transition.js
@@ -0,0 +1,83 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Private Browsing Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * Ehsan Akhgari.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ehsan Akhgari <ehsan.akhgari@gmail.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This test makes sure that SSL sites load correctly after leaving the
+// Private Browsing mode (bug 463256).
+
+function test() {
+  // initialization
+  let pb = Cc["@mozilla.org/privatebrowsing;1"].
+           getService(Ci.nsIPrivateBrowsingService);
+
+  const kTestURL = "https://example.com/";
+
+  // load an SSL site in the first tab and wait for it to finish loading
+  let tab = gBrowser.tabContainer.childNodes[0];
+  let browser = gBrowser.getBrowserForTab(tab);
+  browser.addEventListener("load", function() {
+    browser.removeEventListener("load", arguments.callee, true);
+
+    // enter the private browsing mode, and wait for the about:pb page to load
+    pb.privateBrowsingEnabled = true;
+    tab = gBrowser.tabContainer.childNodes[0];
+    browser = gBrowser.getBrowserForTab(tab);
+    browser.addEventListener("load", function() {
+      browser.removeEventListener("load", arguments.callee, true);
+
+      is(browser.contentWindow.location, "about:privatebrowsing",
+        "about:privatebrowsing should be loaded at this stage");
+
+      // leave the private browsing mode, and wait for the SSL page to load again
+      pb.privateBrowsingEnabled = false;
+      tab = gBrowser.tabContainer.childNodes[0];
+      browser = gBrowser.getBrowserForTab(tab);
+      // Note: if the page fails to load, the test will time out
+      browser.addEventListener("load", function() {
+        browser.removeEventListener("load", arguments.callee, true);
+
+        is(browser.contentWindow.location, kTestURL,
+          "The original SSL page should be loaded at this stage");
+
+        browser.contentWindow.location = "about:blank";
+        finish();
+      }, true);
+    }, true);
+  }, true);
+  browser.contentWindow.location = kTestURL;
+
+  waitForExplicitFinish();
+}
--- a/toolkit/components/downloads/test/unit/test_privatebrowsing.js
+++ b/toolkit/components/downloads/test/unit/test_privatebrowsing.js
@@ -111,17 +111,16 @@ function run_test() {
 
   let prefBranch = Cc["@mozilla.org/preferences-service;1"].
                    getService(Ci.nsIPrefBranch);
   prefBranch.setBoolPref("browser.privatebrowsing.keep_current_session", true);
 
   do_test_pending();
   let httpserv = new nsHttpServer();
   httpserv.registerDirectory("/", dirSvc.get("ProfD", Ci.nsILocalFile));
-  httpserv.start(4444);
 
   let tmpDir = Cc["@mozilla.org/file/directory_service;1"].
                getService(Ci.nsIProperties).
                get("TmpD", Ci.nsIFile);
   const nsIWBP = Ci.nsIWebBrowserPersist;
 
   // make sure we're starting with an empty DB
   do_check_eq(dm.activeDownloadCount, 0);
@@ -135,17 +134,17 @@ function run_test() {
         case dm.DOWNLOAD_FAILED:
         case dm.DOWNLOAD_CANCELED:
         case dm.DOWNLOAD_DIRTY:
         case dm.DOWNLOAD_BLOCKED_POLICY:
           // Fail!
           if (aDownload.targetFile.exists())
             aDownload.targetFile.remove(false);
           dm.removeListener(this);
-          do_throw("Download failed (name: " + aDownload.name + ", state: " + aDownload.state + ")");
+          do_throw("Download failed (name: " + aDownload.displayName + ", state: " + aDownload.state + ")");
           do_test_finished();
           break;
 
         // We need to wait until Download-C has started, because otherwise it
         // won't be resumable, so the private browsing mode won't correctly pause it.
         case dm.DOWNLOAD_DOWNLOADING:
           if (aDownload.id == downloadC && !this.handledC && this.phase == 2) {
             // Sanity check: Download-C must be resumable
@@ -237,16 +236,17 @@ function run_test() {
           do_check_true(is_download_available(downloadA, downloadASource,
             fileA, downloadAName));
 
           // Check that Download-B is not accessible
           do_check_false(is_download_available(downloadB, downloadBSource,
             fileB, downloadBName));
 
           // Create Download-C
+          httpserv.start(4444);
           dlC = addDownload({
             targetFile: fileC,
             sourceURI: downloadCSource,
             downloadName: downloadCName,
             runBeforeStart: function (aDownload) {
               // Check that Download-C is retrievable
               do_check_eq(dm.activeDownloadCount, 1);
               do_check_true(is_active_download_available(aDownload.id,