Bug 1282124 - Remove nsILoadInfo.usePrivateBrowsing and the SEC_FORCE_PRIVATE_BROWSING flag; r=smaug,jryans
authorJames Andreou <jandreou25@gmail.com>
Tue, 30 Aug 2016 17:54:58 -0400
changeset 315399 31c6da3081bffa6aed799d100566dcd09e1cfac0
parent 315398 c9e65e3bf84a6229e79c1a0246a99b54a426f262
child 315400 9429b90c5754982ad3564da4c1b7a11f772e2566
push id82156
push usereakhgari@mozilla.com
push dateTue, 27 Sep 2016 20:57:06 +0000
treeherdermozilla-inbound@31c6da3081bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, jryans
bugs1282124
milestone52.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 1282124 - Remove nsILoadInfo.usePrivateBrowsing and the SEC_FORCE_PRIVATE_BROWSING flag; r=smaug,jryans
devtools/shared/DevToolsUtils.js
docshell/base/nsDocShell.cpp
dom/html/HTMLMediaElement.cpp
image/imgLoader.cpp
image/imgLoader.h
image/test/unit/test_private_channel.js
netwerk/base/LoadInfo.cpp
netwerk/base/nsILoadInfo.idl
netwerk/base/nsNetUtil.cpp
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/test/unit/test_cacheflags.js
--- a/devtools/shared/DevToolsUtils.js
+++ b/devtools/shared/DevToolsUtils.js
@@ -375,17 +375,18 @@ exports.defineLazyGetter(this, "NetworkH
  *        An object with the following optional properties:
  *        - loadFromCache: if false, will bypass the cache and
  *          always load fresh from the network (default: true)
  *        - policy: the nsIContentPolicy type to apply when fetching the URL
  *                  (only works when loading from system principal)
  *        - window: the window to get the loadGroup from
  *        - charset: the charset to use if the channel doesn't provide one
  *        - principal: the principal to use, if omitted, the request is loaded
- *                     with the system principal
+ *                     with a codebase principal corresponding to the url being
+ *                     loaded, using the origin attributes of the window, if any.
  *        - cacheKey: when loading from cache, use this key to retrieve a cache
  *                    specific to a given SHEntry. (Allows loading POST
  *                    requests from cache)
  * @returns Promise that resolves with an object with the following members on
  *          success:
  *           - content: the document at that URL, as a string,
  *           - contentType: the content type of the document
  *
@@ -521,61 +522,54 @@ function mainThreadFetch(aURL, aOptions 
  * Opens a channel for given URL. Tries a bit harder than NetUtil.newChannel.
  *
  * @param {String} url - The URL to open a channel for.
  * @param {Object} options - The options object passed to @method fetch.
  * @return {nsIChannel} - The newly created channel. Throws on failure.
  */
 function newChannelForURL(url, { policy, window, principal }) {
   var securityFlags = Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL;
-  if (window) {
-    // Respect private browsing.
-    var req = window.QueryInterface(Ci.nsIInterfaceRequestor)
-                    .getInterface(Ci.nsIWebNavigation)
-                    .QueryInterface(Ci.nsIDocumentLoader)
-                    .loadGroup;
-    if (req) {
-      var nc = req.notificationCallbacks;
-      if (nc) {
-        try {
-          var lc = nc.getInterface(Ci.nsILoadContext);
-          if (lc) {
-            if (lc.usePrivateBrowsing) {
-              securityFlags |= Ci.nsILoadInfo.SEC_FORCE_PRIVATE_BROWSING;
-            }
-          }
-        } catch (ex) {}
-      }
-    }
+
+  let uri;
+  try {
+    uri = Services.io.newURI(url, null, null);
+  } catch (e) {
+    // In the xpcshell tests, the script url is the absolute path of the test
+    // file, which will make a malformed URI error be thrown. Add the file
+    // scheme to see if it helps.
+    uri = Services.io.newURI("file://" + url, null, null);
   }
-
   let channelOptions = {
     contentPolicyType: policy,
     securityFlags: securityFlags,
-    uri: url
+    uri: uri
   };
-  if (principal) {
-    // contentPolicyType is required when loading with a custom principal
-    if (!channelOptions.contentPolicyType) {
-      channelOptions.contentPolicyType = Ci.nsIContentPolicy.TYPE_OTHER;
+  let prin = principal;
+  if (!prin) {
+    let oa = {};
+    if (window) {
+      oa = window.document.nodePrincipal.originAttributes;
     }
-    channelOptions.loadingPrincipal = principal;
-  } else {
-    channelOptions.loadUsingSystemPrincipal = true;
+    prin = Services.scriptSecurityManager
+                   .createCodebasePrincipal(uri, oa);
   }
+  // contentPolicyType is required when specifying a principal
+  if (!channelOptions.contentPolicyType) {
+    channelOptions.contentPolicyType = Ci.nsIContentPolicy.TYPE_OTHER;
+  }
+  channelOptions.loadingPrincipal = prin;
 
   try {
     return NetUtil.newChannel(channelOptions);
   } catch (e) {
-    // In the xpcshell tests, the script url is the absolute path of the test
-    // file, which will make a malformed URI error be thrown. Add the file
-    // scheme to see if it helps.
-    channelOptions.uri = "file://" + url;
-
-    return NetUtil.newChannel(channelOptions);
+    // In xpcshell tests on Windows, nsExternalProtocolHandler::NewChannel()
+    // can throw NS_ERROR_UNKNOWN_PROTOCOL if the external protocol isn't
+    // supported by Windows, so we also need to handle the exception here if
+    // parsing the URL above doesn't throw.
+    return newChannelForURL("file://" + url, { policy, window, principal });
   }
 }
 
 // Fetch is defined differently depending on whether we are on the main thread
 // or a worker thread.
 if (!this.isWorker) {
   exports.fetch = mainThreadFetch;
 } else {
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -10852,20 +10852,16 @@ nsDocShell::DoURILoad(nsIURI* aURI,
 
   if (inherit) {
     securityFlags |= nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
   }
   if (isSandBoxed) {
     securityFlags |= nsILoadInfo::SEC_SANDBOXED;
   }
 
-  if (UsePrivateBrowsing()) {
-    securityFlags |= nsILoadInfo::SEC_FORCE_PRIVATE_BROWSING;
-  }
-
   nsCOMPtr<nsILoadInfo> loadInfo =
     (aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT) ?
       new LoadInfo(loadingWindow, triggeringPrincipal,
                    securityFlags) :
       new LoadInfo(loadingPrincipal, triggeringPrincipal, loadingNode,
                    securityFlags, aContentPolicyType);
 
   if (aPrincipalToInherit) {
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -560,26 +560,16 @@ public:
       securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
     }
 
     MOZ_ASSERT(aElement->IsAnyOfHTMLElements(nsGkAtoms::audio, nsGkAtoms::video));
     nsContentPolicyType contentPolicyType = aElement->IsHTMLElement(nsGkAtoms::audio)
       ? nsIContentPolicy::TYPE_INTERNAL_AUDIO :
         nsIContentPolicy::TYPE_INTERNAL_VIDEO;
 
-    nsCOMPtr<nsIDocShell> docShell = aElement->OwnerDoc()->GetDocShell();
-    if (docShell) {
-      nsDocShell* docShellPtr = nsDocShell::Cast(docShell);
-      bool privateBrowsing;
-      docShellPtr->GetUsePrivateBrowsing(&privateBrowsing);
-      if (privateBrowsing) {
-        securityFlags |= nsILoadInfo::SEC_FORCE_PRIVATE_BROWSING;
-      }
-    }
-
     nsCOMPtr<nsILoadGroup> loadGroup = aElement->GetDocumentLoadGroup();
     nsCOMPtr<nsIChannel> channel;
     nsresult rv = NS_NewChannel(getter_AddRefs(channel),
                                 aElement->mLoadingSrc,
                                 static_cast<Element*>(aElement),
                                 securityFlags,
                                 contentPolicyType,
                                 loadGroup,
--- a/image/imgLoader.cpp
+++ b/image/imgLoader.cpp
@@ -724,20 +724,16 @@ NewImageChannel(nsIChannel** aResult,
     : nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
   if (aCORSMode == imgIRequest::CORS_ANONYMOUS) {
     securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
   } else if (aCORSMode == imgIRequest::CORS_USE_CREDENTIALS) {
     securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
   }
   securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
 
-  if (aRespectPrivacy) {
-    securityFlags |= nsILoadInfo::SEC_FORCE_PRIVATE_BROWSING;
-  }
-
   // Note we are calling NS_NewChannelWithTriggeringPrincipal() here with a
   // node and a principal. This is for things like background images that are
   // specified by user stylesheets, where the document is being styled, but
   // the principal is that of the user stylesheet.
   if (requestingNode && aLoadingPrincipal) {
     rv = NS_NewChannelWithTriggeringPrincipal(aResult,
                                               aURI,
                                               requestingNode,
@@ -758,16 +754,32 @@ NewImageChannel(nsIChannel** aResult,
     rv = NS_NewChannel(aResult,
                        aURI,
                        nsContentUtils::GetSystemPrincipal(),
                        securityFlags,
                        aPolicyType,
                        nullptr,   // loadGroup
                        callbacks,
                        aLoadFlags);
+
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    // Use the OriginAttributes from the loading principal, if one is available,
+    // and adjust the private browsing ID based on what kind of load the caller
+    // has asked us to perform.
+    NeckoOriginAttributes neckoAttrs;
+    if (aLoadingPrincipal) {
+      neckoAttrs.InheritFromDocToNecko(BasePrincipal::Cast(aLoadingPrincipal)->OriginAttributesRef());
+    }
+    neckoAttrs.mPrivateBrowsingId = aRespectPrivacy ? 1 : 0;
+
+    nsCOMPtr<nsILoadInfo> loadInfo = (*aResult)->GetLoadInfo();
+    rv = loadInfo->SetOriginAttributes(neckoAttrs);
   }
 
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   // only inherit if we have a principal
   *aForcePrincipalCheckForCacheEntry =
--- a/image/imgLoader.h
+++ b/image/imgLoader.h
@@ -250,19 +250,16 @@ public:
    * Get the normal image loader instance that is used by gecko code, creating
    * it if necessary.
    */
   static imgLoader* NormalLoader();
 
   /**
    * Get the Private Browsing image loader instance that is used by gecko code,
    * creating it if necessary.
-   *
-   * The nsIChannel objects that this instance creates are created with the
-   * nsILoadInfo::SEC_FORCE_PRIVATE_BROWSING flag.
    */
   static imgLoader* PrivateBrowsingLoader();
 
   /**
    * Gecko code should use NormalLoader() or PrivateBrowsingLoader() to get the
    * appropriate image loader.
    *
    * This constructor is public because the XPCOM module code that creates
--- a/image/test/unit/test_private_channel.js
+++ b/image/test/unit/test_private_channel.js
@@ -28,44 +28,47 @@ function imageHandler(metadata, response
   var body = "iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII=";
   response.bodyOutputStream.write(body, body.length);
 }
 
 var requests = [];
 var listeners = [];
 
 function NotificationCallbacks(isPrivate) {
+  this.originAttributes.privateBrowsingId = isPrivate ? 1 : 0;
   this.usePrivateBrowsing = isPrivate;
 }
 
 NotificationCallbacks.prototype = {
   QueryInterface: function (iid) {
     if (iid.equals(Ci.nsISupports) ||
         iid.equals(Ci.nsILoadContext))
       return this;
     throw Cr.NS_ERROR_NO_INTERFACE;
   },
   getInterface: function(iid) {
     if (iid.equals(Ci.nsILoadContext))
       return this;
     throw Cr.NS_ERROR_NO_INTERFACE;
   },
-  originAttributes: {}
+  originAttributes: {
+    privateBrowsingId: 0
+  }
 };
 
 var gImgPath = 'http://localhost:' + server.identity.primaryPort + '/image.png';
 
 function setup_chan(path, isPrivate, callback) {
   var uri = NetUtil.newURI(gImgPath);
   var securityFlags = Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL;
-  if (isPrivate) {
-    securityFlags |= Ci.nsILoadInfo.SEC_FORCE_PRIVATE_BROWSING;
-  }
-  var chan =  NetUtil.newChannel({uri: uri, loadUsingSystemPrincipal: true,
-                                  securityFlags: securityFlags});
+  var principal = Services.scriptSecurityManager
+                          .createCodebasePrincipal(uri, {privateBrowsingId: isPrivate ? 1 : 0});
+  var chan =  NetUtil.newChannel({uri: uri, loadingPrincipal: principal,
+                                  securityFlags: securityFlags,
+                                  contentPolicyType: Ci.nsIContentPolicy.TYPE_INTERNAL_IMAGE});
   chan.notificationCallbacks = new NotificationCallbacks(isPrivate);
   var channelListener = new ChannelListener();
   chan.asyncOpen2(channelListener);
 
   var listener = new ImageListener(null, callback);
   var outlistener = {};
   var loader = isPrivate ? gPrivateLoader : gPublicLoader;
   var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
--- a/netwerk/base/LoadInfo.cpp
+++ b/netwerk/base/LoadInfo.cpp
@@ -172,41 +172,41 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
           aLoadingPrincipal->GetPreloadCsp(getter_AddRefs(preloadCSP));
           if (preloadCSP) {
             preloadCSP->RequireSRIForType(externalType, &mEnforceSRI);
           }
         }
       }
     }
 
-  if (!(mSecurityFlags & nsILoadInfo::SEC_FORCE_PRIVATE_BROWSING)) {
-    if (aLoadingContext) {
-      nsCOMPtr<nsILoadContext> loadContext =
-        aLoadingContext->OwnerDoc()->GetLoadContext();
-      if (loadContext) {
-        bool usePrivateBrowsing;
-        nsresult rv = loadContext->GetUsePrivateBrowsing(&usePrivateBrowsing);
-        if (NS_SUCCEEDED(rv) && usePrivateBrowsing) {
-          mSecurityFlags |= nsILoadInfo::SEC_FORCE_PRIVATE_BROWSING;
-        }
+  InheritOriginAttributes(mLoadingPrincipal, mOriginAttributes);
+
+  // We need to do this after inheriting the document's origin attributes
+  // above, in case the loading principal ends up being the system principal.
+  if (aLoadingContext) {
+    nsCOMPtr<nsILoadContext> loadContext =
+      aLoadingContext->OwnerDoc()->GetLoadContext();
+    nsCOMPtr<nsIDocShell> docShell = aLoadingContext->OwnerDoc()->GetDocShell();
+    if (loadContext && docShell &&
+        docShell->ItemType() == nsIDocShellTreeItem::typeContent) {
+      bool usePrivateBrowsing;
+      nsresult rv = loadContext->GetUsePrivateBrowsing(&usePrivateBrowsing);
+      if (NS_SUCCEEDED(rv)) {
+        mOriginAttributes.SyncAttributesWithPrivateBrowsing(usePrivateBrowsing);
       }
     }
   }
 
-  InheritOriginAttributes(mLoadingPrincipal, mOriginAttributes);
-
   // For chrome docshell, the mPrivateBrowsingId remains 0 even its
   // UsePrivateBrowsing() is true, so we only update the mPrivateBrowsingId in
   // origin attributes if the type of the docshell is content.
   if (aLoadingContext) {
     nsCOMPtr<nsIDocShell> docShell = aLoadingContext->OwnerDoc()->GetDocShell();
     if (docShell) {
-      if (docShell->ItemType() == nsIDocShellTreeItem::typeContent) {
-        mOriginAttributes.SyncAttributesWithPrivateBrowsing(GetUsePrivateBrowsing());
-      } else if (docShell->ItemType() == nsIDocShellTreeItem::typeChrome) {
+      if (docShell->ItemType() == nsIDocShellTreeItem::typeChrome) {
         MOZ_ASSERT(mOriginAttributes.mPrivateBrowsingId == 0,
                    "chrome docshell shouldn't have mPrivateBrowsingId set.");
       }
     }
   }
 }
 
 /* Constructor takes an outer window, but no loadingNode or loadingPrincipal.
@@ -259,20 +259,17 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* a
   mParentOuterWindowID = parent ? parent->WindowID() : 0;
 
   // get the docshell from the outerwindow, and then get the originattributes
   nsCOMPtr<nsIDocShell> docShell = aOuterWindow->GetDocShell();
   MOZ_ASSERT(docShell);
   const DocShellOriginAttributes attrs =
     nsDocShell::Cast(docShell)->GetOriginAttributes();
 
-  if (docShell->ItemType() == nsIDocShellTreeItem::typeContent) {
-    MOZ_ASSERT(GetUsePrivateBrowsing() == (attrs.mPrivateBrowsingId != 0),
-               "docshell and mSecurityFlags have different value for PrivateBrowsing().");
-  } else if (docShell->ItemType() == nsIDocShellTreeItem::typeChrome) {
+  if (docShell->ItemType() == nsIDocShellTreeItem::typeChrome) {
     MOZ_ASSERT(attrs.mPrivateBrowsingId == 0,
                "chrome docshell shouldn't have mPrivateBrowsingId set.");
   }
 
   mOriginAttributes.InheritFromDocShellToNecko(attrs);
 }
 
 LoadInfo::LoadInfo(const LoadInfo& rhs)
@@ -582,24 +579,16 @@ NS_IMETHODIMP
 LoadInfo::GetDontFollowRedirects(bool* aResult)
 {
   *aResult =
     (mSecurityFlags & nsILoadInfo::SEC_DONT_FOLLOW_REDIRECTS);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-LoadInfo::GetUsePrivateBrowsing(bool* aUsePrivateBrowsing)
-{
-  *aUsePrivateBrowsing = (mSecurityFlags &
-                          nsILoadInfo::SEC_FORCE_PRIVATE_BROWSING);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 LoadInfo::GetLoadErrorPage(bool* aResult)
 {
   *aResult =
     (mSecurityFlags & nsILoadInfo::SEC_LOAD_ERROR_PAGE);
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/netwerk/base/nsILoadInfo.idl
+++ b/netwerk/base/nsILoadInfo.idl
@@ -170,29 +170,20 @@ interface nsILoadInfo : nsISupports
    *
    * Note: If this flag is set and the channel response is a redirect, then
    * the response body might not be available.
    * This can happen if the redirect was cached.
    */
   const unsigned long SEC_DONT_FOLLOW_REDIRECTS = (1<<12);
 
   /**
-   * Force private browsing. Setting this flag the private browsing can be
-   * enforce even when a loading is not happening in the context of a document.
-   *
-   * If the flag is true, even if a document context is present,
-   * GetUsePrivateBrowsing will always return true.
-   */
-  const unsigned long SEC_FORCE_PRIVATE_BROWSING = (1<<13);
-
-  /**
    * Load an error page, it should be one of following : about:neterror,
    * about:certerror, about:blocked, or about:tabcrashed.
    */
-  const unsigned long SEC_LOAD_ERROR_PAGE = (1<<14);
+  const unsigned long SEC_LOAD_ERROR_PAGE = (1<<13);
 
   /**
    * This is the principal of the network request's caller/requester where
    * the resulting resource will be used. I.e. it is the principal which
    * will get access to the result of the request. (Where "get access to"
    * might simply mean "embed" depending on the type of resource that is
    * loaded).
    *
@@ -346,23 +337,16 @@ interface nsILoadInfo : nsISupports
 
   /**
    * If aboutBlankInherits is true, then about:blank should inherit
    * the principal.
    */
   [infallible] readonly attribute boolean aboutBlankInherits;
 
   /**
-   * If usePrivateBrowsing is true, private browsing will be used.
-   * This value equals to originAttributes.privateBrowsingId in *content*
-   * side.
-   */
-  [infallible] readonly attribute boolean usePrivateBrowsing;
-
-  /**
    * If allowChrome is true, then use nsIScriptSecurityManager::ALLOW_CHROME
    * when calling CheckLoadURIWithPrincipal().
    */
   [infallible] readonly attribute boolean allowChrome;
 
   /**
    * If disallowScript is true, then use nsIScriptSecurityManager::DISALLOW_SCRIPT
    * when calling CheckLoadURIWithPrincipal().
--- a/netwerk/base/nsNetUtil.cpp
+++ b/netwerk/base/nsNetUtil.cpp
@@ -2419,31 +2419,22 @@ NS_CompareLoadInfoAndLoadContext(nsIChan
   if (NS_FAILED(rv)) {
     return NS_ERROR_UNEXPECTED;
   }
 
   OriginAttributes originAttrsLoadInfo = loadInfo->GetOriginAttributes();
   DocShellOriginAttributes originAttrsLoadContext;
   loadContext->GetOriginAttributes(originAttrsLoadContext);
 
-  bool loadInfoUsePB = loadInfo->GetUsePrivateBrowsing();
-  bool loadContextUsePB = false;
-  rv = loadContext->GetUsePrivateBrowsing(&loadContextUsePB);
-  if (NS_FAILED(rv)) {
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  LOG(("NS_CompareLoadInfoAndLoadContext - loadInfo: %d, %d, %d, %d, %d; "
-       "loadContext: %d %d, %d, %d, %d. [channel=%p]",
+  LOG(("NS_CompareLoadInfoAndLoadContext - loadInfo: %d, %d, %d, %d; "
+       "loadContext: %d %d, %d, %d. [channel=%p]",
        originAttrsLoadInfo.mAppId, originAttrsLoadInfo.mInIsolatedMozBrowser,
        originAttrsLoadInfo.mUserContextId, originAttrsLoadInfo.mPrivateBrowsingId,
-       loadInfoUsePB,
        loadContextAppId, loadContextIsInBE,
        originAttrsLoadContext.mUserContextId, originAttrsLoadContext.mPrivateBrowsingId,
-       loadContextUsePB,
        aChannel));
 
   MOZ_ASSERT(originAttrsLoadInfo.mAppId == loadContextAppId,
              "AppId in the loadContext and in the loadInfo are not the "
              "same!");
 
   MOZ_ASSERT(originAttrsLoadInfo.mInIsolatedMozBrowser ==
              loadContextIsInBE,
@@ -2455,20 +2446,16 @@ NS_CompareLoadInfoAndLoadContext(nsIChan
              "The value of mUserContextId in the loadContext and in the "
              "loadInfo are not the same!");
 
   MOZ_ASSERT(originAttrsLoadInfo.mPrivateBrowsingId ==
              originAttrsLoadContext.mPrivateBrowsingId,
              "The value of mPrivateBrowsingId in the loadContext and in the "
              "loadInfo are not the same!");
 
-  MOZ_ASSERT(loadInfoUsePB == loadContextUsePB,
-             "The value of usePrivateBrowsing in the loadContext and in the loadInfo "
-             "are not the same!");
-
   return NS_OK;
 }
 
 namespace mozilla {
 namespace net {
 
 bool
 InScriptableRange(int64_t val)
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -1790,19 +1790,16 @@ HttpChannelChild::AsyncOpen(nsIStreamLis
              mLoadInfo->GetSecurityMode() == 0 ||
              mLoadInfo->GetInitialSecurityCheckDone() ||
              (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL &&
               nsContentUtils::IsSystemPrincipal(mLoadInfo->LoadingPrincipal())),
              "security flags in loadInfo but asyncOpen2() not called");
 
   LOG(("HttpChannelChild::AsyncOpen [this=%p uri=%s]\n", this, mSpec.get()));
 
-  MOZ_ASSERT(mLoadInfo->GetUsePrivateBrowsing() == (mLoadInfo->GetOriginAttributes().mPrivateBrowsingId != 0),
-             "PrivateBrowsing mismatch on LoadInfo.");
-
 #ifdef DEBUG
   CheckPrivateBrowsing();
 #endif
 
   if (mCanceled)
     return mStatus;
 
   NS_ENSURE_TRUE(gNeckoChild != nullptr, NS_ERROR_FAILURE);
--- a/netwerk/test/unit/test_cacheflags.js
+++ b/netwerk/test/unit/test_cacheflags.js
@@ -1,10 +1,11 @@
 Cu.import("resource://testing-common/httpd.js");
 Cu.import("resource://gre/modules/NetUtil.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpserver = new HttpServer();
 httpserver.start(-1);
 
 // Need to randomize, because apparently no one clears our cache
 var suffix = Math.random();
 var httpBase = "http://localhost:" + httpserver.identity.primaryPort;
 var httpsBase = "http://localhost:4445";
@@ -18,49 +19,53 @@ var test404Path = "/test404" + suffix;
 
 // We attach this to channel when we want to test Private Browsing mode
 function LoadContext(usePrivateBrowsing) {
   this.usePrivateBrowsing = usePrivateBrowsing;
   this.originAttributes.privateBrowsingId = usePrivateBrowsing ? 1 : 0;
 }
 
 LoadContext.prototype = {
-  originAttributes: {},
+  originAttributes: {
+    privateBrowsingId : 0
+  },
   usePrivateBrowsing: false,
   // don't bother defining rest of nsILoadContext fields: don't need 'em
 
   QueryInterface: function(iid) {
     if (iid.equals(Ci.nsILoadContext))
       return this;
     throw Cr.NS_ERROR_NO_INTERFACE;
   },
 
   getInterface: function(iid) {
     if (iid.equals(Ci.nsILoadContext))
       return this;
     throw Cr.NS_ERROR_NO_INTERFACE;
   },
-
-  originAttributes: {}
 };
 
-PrivateBrowsingLoadContext = new LoadContext(true);
+var PrivateBrowsingLoadContext = new LoadContext(true);
 
 function make_channel(url, flags, usePrivateBrowsing) {
   var securityFlags = Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL;
-  if (usePrivateBrowsing) {
-    securityFlags |= Ci.nsILoadInfo.SEC_FORCE_PRIVATE_BROWSING;
-  }
-  var req = NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true,
-                                securityFlags: securityFlags});
+
+  var uri = Services.io.newURI(url, null, null);
+  var principal = Services.scriptSecurityManager.createCodebasePrincipal(uri,
+    { privateBrowsingId : usePrivateBrowsing ? 1 : 0 });
+
+  var req = NetUtil.newChannel({uri: uri,
+                                loadingPrincipal: principal,
+                                securityFlags: securityFlags,
+                                contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER});
+
   req.loadFlags = flags;
   if (usePrivateBrowsing) {
     req.notificationCallbacks = PrivateBrowsingLoadContext;
   }
-  req.loadInfo.originAttributes = {privateBrowsingId: usePrivateBrowsing ? 1 : 0};
   return req;
 }
 
 function Test(path, flags, expectSuccess, readFromCache, hitServer, 
               usePrivateBrowsing /* defaults to false */) {
   this.path = path;
   this.flags = flags;
   this.expectSuccess = expectSuccess;