Bug 1141814 - Part2: Lower the priority of channel loading tracking resource, r=honzab
☠☠ backed out by 91924feee6b0 ☠ ☠
authorKershaw Chang <kechang@mozilla.com>
Wed, 23 Nov 2016 22:23:00 +0100
changeset 324170 76a1099ef0b4fb52822919863be2573a7cc6b967
parent 324169 504e1e32c8b84e50c2fefaafe24e2a76e8e8e106
child 324171 6c26d0bd467bb05e38055eca393f0efaa252417c
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewershonzab
bugs1141814
milestone53.0a1
Bug 1141814 - Part2: Lower the priority of channel loading tracking resource, r=honzab
netwerk/base/nsBaseChannel.cpp
netwerk/base/nsChannelClassifier.cpp
netwerk/base/nsChannelClassifier.h
netwerk/protocol/http/nsHttpChannel.cpp
--- a/netwerk/base/nsBaseChannel.cpp
+++ b/netwerk/base/nsBaseChannel.cpp
@@ -307,19 +307,19 @@ nsBaseChannel::ClassifyURI()
 {
   // For channels created in the child process, delegate to the parent to
   // classify URIs.
   if (!XRE_IsParentProcess()) {
     return;
   }
 
   if (mLoadFlags & LOAD_CLASSIFY_URI) {
-    RefPtr<nsChannelClassifier> classifier = new nsChannelClassifier();
+    RefPtr<nsChannelClassifier> classifier = new nsChannelClassifier(this);
     if (classifier) {
-      classifier->Start(this);
+      classifier->Start();
     } else {
       Cancel(NS_ERROR_OUT_OF_MEMORY);
     }
   }
 }
 
 //-----------------------------------------------------------------------------
 // nsBaseChannel::nsISupports
--- a/netwerk/base/nsChannelClassifier.cpp
+++ b/netwerk/base/nsChannelClassifier.cpp
@@ -20,16 +20,17 @@
 #include "nsIParentChannel.h"
 #include "nsIPermissionManager.h"
 #include "nsIPrivateBrowsingTrackingProtectionWhitelist.h"
 #include "nsIProtocolHandler.h"
 #include "nsIScriptError.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsISecureBrowserUI.h"
 #include "nsISecurityEventSink.h"
+#include "nsISupportsPriority.h"
 #include "nsIURL.h"
 #include "nsIWebProgressListener.h"
 #include "nsNetUtil.h"
 #include "nsPIDOMWindow.h"
 #include "nsXULAppAPI.h"
 
 #include "mozilla/ErrorNames.h"
 #include "mozilla/Logging.h"
@@ -45,25 +46,36 @@ static LazyLogModule gChannelClassifierL
 
 #undef LOG
 #define LOG(args)     MOZ_LOG(gChannelClassifierLog, LogLevel::Debug, args)
 #define LOG_ENABLED() MOZ_LOG_TEST(gChannelClassifierLog, LogLevel::Debug)
 
 NS_IMPL_ISUPPORTS(nsChannelClassifier,
                   nsIURIClassifierCallback)
 
-nsChannelClassifier::nsChannelClassifier()
+nsChannelClassifier::nsChannelClassifier(nsIChannel *aChannel)
   : mIsAllowListed(false),
-    mSuspendedChannel(false)
+    mSuspendedChannel(false),
+    mChannel(aChannel),
+    mTrackingProtectionEnabled(Nothing())
 {
+  MOZ_ASSERT(mChannel);
 }
 
 nsresult
-nsChannelClassifier::ShouldEnableTrackingProtection(nsIChannel *aChannel,
-                                                    bool *result)
+nsChannelClassifier::ShouldEnableTrackingProtection(bool *result)
+{
+  nsresult rv = ShouldEnableTrackingProtectionInternal(mChannel, result);
+  mTrackingProtectionEnabled = Some(*result);
+  return rv;
+}
+
+nsresult
+nsChannelClassifier::ShouldEnableTrackingProtectionInternal(nsIChannel *aChannel,
+                                                            bool *result)
 {
     // Should only be called in the parent process.
     MOZ_ASSERT(XRE_IsParentProcess());
 
     NS_ENSURE_ARG(result);
     *result = false;
 
     nsCOMPtr<nsILoadContext> loadContext;
@@ -247,20 +259,18 @@ nsChannelClassifier::NotifyTrackingProte
     securityUI->GetState(&state);
     state |= nsIWebProgressListener::STATE_LOADED_TRACKING_CONTENT;
     eventSink->OnSecurityChange(nullptr, state);
 
     return NS_OK;
 }
 
 void
-nsChannelClassifier::Start(nsIChannel *aChannel)
+nsChannelClassifier::Start()
 {
-  mChannel = aChannel;
-
   nsresult rv = StartInternal();
   if (NS_FAILED(rv)) {
     // If we aren't getting a callback for any reason, assume a good verdict and
     // make sure we resume the channel if necessary.
     OnClassifyComplete(NS_OK);
   }
 }
 
@@ -339,27 +349,39 @@ nsChannelClassifier::StartInternal()
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIPrincipal> principal;
     rv = securityManager->GetChannelURIPrincipal(mChannel, getter_AddRefs(principal));
     NS_ENSURE_SUCCESS(rv, rv);
 
     bool expectCallback;
     bool trackingProtectionEnabled = false;
-    (void)ShouldEnableTrackingProtection(mChannel, &trackingProtectionEnabled);
+    if (mTrackingProtectionEnabled.isNothing()) {
+      (void)ShouldEnableTrackingProtection(&trackingProtectionEnabled);
+    } else {
+      trackingProtectionEnabled = mTrackingProtectionEnabled.value();
+    }
+
+    static bool sAnnotateChannelEnabled = false;
+    static bool sIsInited = false;
+    if (!sIsInited) {
+      sIsInited = true;
+      Preferences::AddBoolVarCache(&sAnnotateChannelEnabled,
+                                   "privacy.trackingprotection.annotate_channels");
+    }
 
     if (LOG_ENABLED()) {
       nsCOMPtr<nsIURI> principalURI;
       principal->GetURI(getter_AddRefs(principalURI));
       LOG(("nsChannelClassifier[%p]: Classifying principal %s on channel with "
            "uri %s", this, principalURI->GetSpecOrDefault().get(),
            uri->GetSpecOrDefault().get()));
     }
-    rv = uriClassifier->Classify(principal, trackingProtectionEnabled, this,
-                                 &expectCallback);
+    rv = uriClassifier->Classify(principal, sAnnotateChannelEnabled | trackingProtectionEnabled,
+                                 this, &expectCallback);
     if (NS_FAILED(rv)) {
         return rv;
     }
 
     if (expectCallback) {
         // Suspend the channel, it will be resumed when we get the classifier
         // callback.
         rv = mChannel->Suspend();
@@ -662,16 +684,36 @@ nsChannelClassifier::OnClassifyComplete(
       nsAutoCString errorName;
       if (LOG_ENABLED()) {
         GetErrorName(aErrorCode, errorName);
         LOG(("nsChannelClassifier[%p]:OnClassifyComplete %s (suspended channel)",
              this, errorName.get()));
       }
       MarkEntryClassified(aErrorCode);
 
+      // The value of |mTrackingProtectionEnabled| should be assigned at
+      // |ShouldEnableTrackingProtection| before.
+      MOZ_ASSERT(mTrackingProtectionEnabled, "Should contain a value.");
+
+      if (aErrorCode == NS_ERROR_TRACKING_URI &&
+          !mTrackingProtectionEnabled.valueOr(false)) {
+        if (LOG_ENABLED()) {
+          nsCOMPtr<nsIURI> uri;
+          mChannel->GetURI(getter_AddRefs(uri));
+          LOG(("nsChannelClassifier[%p]: lower the priority of channel %p"
+               ", since %s is a tracker", this, mChannel.get(),
+               uri->GetSpecOrDefault().get()));
+        }
+        nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(mChannel);
+        if (p) {
+          p->SetPriority(nsISupportsPriority::PRIORITY_LOWEST);
+        }
+        aErrorCode = NS_OK;
+      }
+
       if (NS_FAILED(aErrorCode)) {
         if (LOG_ENABLED()) {
           nsCOMPtr<nsIURI> uri;
           mChannel->GetURI(getter_AddRefs(uri));
           LOG(("nsChannelClassifier[%p]: cancelling channel %p for %s "
                "with error code %s", this, mChannel.get(),
                uri->GetSpecOrDefault().get(), errorName.get()));
         }
--- a/netwerk/base/nsChannelClassifier.h
+++ b/netwerk/base/nsChannelClassifier.h
@@ -3,60 +3,65 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsChannelClassifier_h__
 #define nsChannelClassifier_h__
 
 #include "nsIURIClassifier.h"
 #include "nsCOMPtr.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/Maybe.h"
 
 class nsIChannel;
 class nsIHttpChannelInternal;
 class nsIDocument;
 
 namespace mozilla {
 namespace net {
 
 class nsChannelClassifier final : public nsIURIClassifierCallback
 {
 public:
-    nsChannelClassifier();
+    explicit nsChannelClassifier(nsIChannel* aChannel);
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIURICLASSIFIERCALLBACK
 
     // Calls nsIURIClassifier.Classify with the principal of the given channel,
     // and cancels the channel on a bad verdict.
-    void Start(nsIChannel *aChannel);
+    void Start();
     // Whether or not tracking protection should be enabled on this channel.
-    nsresult ShouldEnableTrackingProtection(nsIChannel *aChannel, bool *result);
+    nsresult ShouldEnableTrackingProtection(bool *result);
 
 private:
     // True if the channel is on the allow list.
     bool mIsAllowListed;
     // True if the channel has been suspended.
     bool mSuspendedChannel;
     nsCOMPtr<nsIChannel> mChannel;
+    Maybe<bool> mTrackingProtectionEnabled;
 
     ~nsChannelClassifier() {}
     // Caches good classifications for the channel principal.
     void MarkEntryClassified(nsresult status);
     bool HasBeenClassified(nsIChannel *aChannel);
     // Helper function so that we ensure we call ContinueBeginConnect once
     // Start is called. Returns NS_OK if and only if we will get a callback
     // from the classifier service.
     nsresult StartInternal();
     // Helper function to check a tracking URI against the whitelist
     nsresult IsTrackerWhitelisted();
     // Helper function to check a URI against the hostname whitelist
     bool IsHostnameWhitelisted(nsIURI *aUri, const nsACString &aWhitelisted);
     // Checks that the channel was loaded by the URI currently loaded in aDoc
     static bool SameLoadingURI(nsIDocument *aDoc, nsIChannel *aChannel);
 
+    nsresult ShouldEnableTrackingProtectionInternal(nsIChannel *aChannel,
+                                                    bool *result);
+
 public:
     // If we are blocking tracking content, update the corresponding flag in
     // the respective docshell and call nsISecurityEventSink::onSecurityChange.
     static nsresult SetBlockedTrackingContent(nsIChannel *channel);
     static nsresult NotifyTrackingProtectionDisabled(nsIChannel *aChannel);
 };
 
 } // namespace net
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -5880,22 +5880,24 @@ nsHttpChannel::BeginConnect()
     SetLoadGroupUserAgentOverride();
 
     // Check to see if we should redirect this channel elsewhere by
     // nsIHttpChannel.redirectTo API request
     if (mAPIRedirectToURI) {
         return AsyncCall(&nsHttpChannel::HandleAsyncAPIRedirect);
     }
     // Check to see if this principal exists on local blocklists.
-    RefPtr<nsChannelClassifier> channelClassifier = new nsChannelClassifier();
+    RefPtr<nsChannelClassifier> channelClassifier = new nsChannelClassifier(this);
     if (mLoadFlags & LOAD_CLASSIFY_URI) {
         nsCOMPtr<nsIURIClassifier> classifier = do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID);
         bool tpEnabled = false;
-        channelClassifier->ShouldEnableTrackingProtection(this, &tpEnabled);
-        if (classifier && tpEnabled) {
+        channelClassifier->ShouldEnableTrackingProtection(&tpEnabled);
+        bool annotateChannelEnabled =
+            Preferences::GetBool("privacy.trackingprotection.annotate_channels");
+        if (classifier && (tpEnabled || annotateChannelEnabled)) {
             // We skip speculative connections by setting mLocalBlocklist only
             // when tracking protection is enabled. Though we could do this for
             // both phishing and malware, it is not necessary for correctness,
             // since no network events will be received while the
             // nsChannelClassifier is in progress. See bug 1122691.
             nsCOMPtr<nsIURI> uri;
             rv = GetURI(getter_AddRefs(uri));
             if (NS_SUCCEEDED(rv) && uri) {
@@ -6007,17 +6009,17 @@ nsHttpChannel::BeginConnect()
         callContinueBeginConnect = false;
     }
     // nsChannelClassifier calls ContinueBeginConnect if it has not already
     // been called, after optionally cancelling the channel once we have a
     // remote verdict. We call a concrete class instead of an nsI* that might
     // be overridden.
     LOG(("nsHttpChannel::Starting nsChannelClassifier %p [this=%p]",
          channelClassifier.get(), this));
-    channelClassifier->Start(this);
+    channelClassifier->Start();
     if (callContinueBeginConnect) {
         return ContinueBeginConnectWithResult();
     }
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHttpChannel::GetEncodedBodySize(uint64_t *aEncodedBodySize)