Bug 974406 - Bookmarking UI doesn't work correctly to HSTS pages. r=gavin
authorMarco Bonardo <mbonardo@mozilla.com>
Sat, 01 Mar 2014 14:37:23 +0100
changeset 171358 6487c3f33df9e5140abffba78caded6e3b434734
parent 171357 cbe54c837281b1a0780a3343e3001235efb45343
child 171359 4aefac76b1b9ab2d6a299f67ac9f8a58ca87195c
push id40447
push usermak77@bonardo.net
push dateSat, 01 Mar 2014 13:38:12 +0000
treeherdermozilla-inbound@6487c3f33df9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgavin
bugs974406
milestone30.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 974406 - Bookmarking UI doesn't work correctly to HSTS pages. r=gavin
browser/base/content/test/general/browser.ini
browser/base/content/test/general/browser_star_hsts.js
browser/base/content/test/general/browser_star_hsts.sjs
toolkit/components/places/PlacesUtils.jsm
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -11,16 +11,17 @@ support-files =
   blockPluginVulnerableNoUpdate.xml
   blockPluginVulnerableUpdatable.xml
   browser_bug479408_sample.html
   browser_bug678392-1.html
   browser_bug678392-2.html
   browser_clearplugindata.html
   browser_clearplugindata_noage.html
   browser_registerProtocolHandler_notification.html
+  browser_star_hsts.sjs
   browser_tab_dragdrop2_frame1.xul
   bug564387.html
   bug564387_video1.ogv
   bug564387_video1.ogv^headers^
   bug592338.html
   bug792517-2.html
   bug792517.html
   bug792517.sjs
@@ -316,16 +317,17 @@ skip-if = true  # disabled until the tre
                 # back to the clear recent history dialog (sanitize.xul), if
                 # it ever is (bug 480169)
 [browser_save_link-perwindowpb.js]
 [browser_save_private_link_perwindowpb.js]
 skip-if = os == "linux" # bug 857427
 [browser_save_video.js]
 [browser_scope.js]
 [browser_selectTabAtIndex.js]
+[browser_star_hsts.js]
 [browser_subframe_favicons_not_used.js]
 [browser_tabDrop.js]
 [browser_tabMatchesInAwesomebar_perwindowpb.js]
 [browser_tab_drag_drop_perwindow.js]
 [browser_tab_dragdrop.js]
 [browser_tab_dragdrop2.js]
 [browser_tabbar_big_widgets.js]
 skip-if = os == "linux" || os == "mac" # No tabs in titlebar on linux
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/general/browser_star_hsts.js
@@ -0,0 +1,114 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+let secureURL = "https://example.com/browser/browser/base/content/test/general/browser_star_hsts.sjs";
+let unsecureURL = "http://example.com/browser/browser/base/content/test/general/browser_star_hsts.sjs";
+
+add_task(function* test_star_redirect() {
+  registerCleanupFunction(function() {
+    // Ensure to remove example.com from the HSTS list.
+    let sss = Cc["@mozilla.org/ssservice;1"]
+                .getService(Ci.nsISiteSecurityService);
+    sss.removeState(Ci.nsISiteSecurityService.HEADER_HSTS,
+                    NetUtil.newURI("http://example.com/"), 0);
+    PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
+    gBrowser.removeCurrentTab();
+  });
+
+  let tab = gBrowser.selectedTab = gBrowser.addTab();
+  // This will add the page to the HSTS cache.
+  yield promiseTabLoadEvent(tab, secureURL, secureURL);
+  // This should transparently be redirected to the secure page.
+  yield promiseTabLoadEvent(tab, unsecureURL, secureURL);
+
+  yield promiseStarState(BookmarkingUI.STATUS_UNSTARRED);
+
+  let promiseBookmark = promiseOnItemAdded(gBrowser.currentURI);
+  BookmarkingUI.star.click();
+  // This resolves on the next tick, so the star should have already been
+  // updated at that point.
+  yield promiseBookmark;
+
+  is(BookmarkingUI.status, BookmarkingUI.STATUS_STARRED, "The star is starred");
+});
+
+/**
+ * Waits for the star to reflect the expected state.
+ */
+function promiseStarState(aValue) {
+  let deferred = Promise.defer();
+  let expectedStatus = aValue ? BookmarkingUI.STATUS_STARRED
+                              : BookmarkingUI.STATUS_UNSTARRED;
+  (function checkState() {
+    if (BookmarkingUI.status == BookmarkingUI.STATUS_UPDATING ||
+        BookmarkingUI.status != expectedStatus) {
+      info("Waiting for star button change.");
+      setTimeout(checkState, 1000);
+    } else {
+      deferred.resolve();
+    }
+  })();
+  return deferred.promise;
+}
+
+/**
+ * Starts a load in an existing tab and waits for it to finish (via some event).
+ *
+ * @param aTab
+ *        The tab to load into.
+ * @param aUrl
+ *        The url to load.
+ * @param [optional] aFinalURL
+ *        The url to wait for, same as aURL if not defined.
+ * @return {Promise} resolved when the event is handled.
+ */
+function promiseTabLoadEvent(aTab, aURL, aFinalURL)
+{
+  if (!aFinalURL)
+    aFinalURL = aURL;
+  let deferred = Promise.defer();
+  info("Wait for load tab event");
+  aTab.linkedBrowser.addEventListener("load", function load(event) {
+    if (event.originalTarget != aTab.linkedBrowser.contentDocument ||
+        event.target.location.href == "about:blank" ||
+        event.target.location.href != aFinalURL) {
+      info("skipping spurious load event");
+      return;
+    }
+    aTab.linkedBrowser.removeEventListener("load", load, true);
+    info("Tab load event received");
+    deferred.resolve();
+  }, true, true);
+  aTab.linkedBrowser.loadURI(aURL);
+  return deferred.promise;
+}
+
+/**
+ * Waits for a bookmark to be added for the given uri.
+ */
+function promiseOnItemAdded(aExpectedURI) {
+  let defer = Promise.defer();
+  let bookmarksObserver = {
+    onItemAdded: function (aItemId, aFolderId, aIndex, aItemType, aURI) {
+      info("Added a bookmark to " + aURI.spec);
+      PlacesUtils.bookmarks.removeObserver(bookmarksObserver);
+      if (aURI.equals(aExpectedURI))
+        defer.resolve();
+      else
+        defer.reject(new Error("Added an unexpected bookmark"));
+    },
+    onBeginUpdateBatch: function () {},
+    onEndUpdateBatch: function () {},
+    onItemRemoved: function () {},
+    onItemChanged: function () {},
+    onItemVisited: function () {},
+    onItemMoved: function () {},
+    QueryInterface: XPCOMUtils.generateQI([
+      Ci.nsINavBookmarkObserver,
+    ])
+  };
+  info("Waiting for a bookmark to be added");
+  PlacesUtils.bookmarks.addObserver(bookmarksObserver, false);
+  return defer.promise;
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/general/browser_star_hsts.sjs
@@ -0,0 +1,13 @@
+/* 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/. */
+
+function handleRequest(request, response)
+{
+  let page = "<!DOCTYPE html><html><body><p>HSTS page</p></body></html>";
+  response.setStatusLine(request.httpVersion, "200", "OK");
+  response.setHeader("Strict-Transport-Security", "max-age=60");
+  response.setHeader("Content-Type", "text/html", false);
+  response.setHeader("Content-Length", page.length + "", false);
+  response.write(page);
+}
--- a/toolkit/components/places/PlacesUtils.jsm
+++ b/toolkit/components/places/PlacesUtils.jsm
@@ -1931,25 +1931,25 @@ TransactionItemCache.prototype = {
     this._parentId || -1,
   keyword: null,
   title: null,
   dateAdded: null,
   lastModified: null,
   postData: null,
   itemType: null,
   set uri(v)
-    this._uri = (v instanceof Ci.nsIURI ? NetUtil.newURI(v.spec) : null),
+    this._uri = (v instanceof Ci.nsIURI ? v.clone() : null),
   get uri()
     this._uri || null,
   set feedURI(v)
-    this._feedURI = (v instanceof Ci.nsIURI ? NetUtil.newURI(v.spec) : null),
+    this._feedURI = (v instanceof Ci.nsIURI ? v.clone() : null),
   get feedURI()
     this._feedURI || null,
   set siteURI(v)
-    this._siteURI = (v instanceof Ci.nsIURI ? NetUtil.newURI(v.spec) : null),
+    this._siteURI = (v instanceof Ci.nsIURI ? v.clone() : null),
   get siteURI()
     this._siteURI || null,
   set index(v)
     this._index = (parseInt(v) >= 0 ? v : null),
   // Index can be 0.
   get index()
     this._index != null ? this._index : PlacesUtils.bookmarks.DEFAULT_INDEX,
   set annotations(v)