Bug 1353853 - P2 - Cache preferences when doing channel classify draft
authorThomas Nguyen <tnguyen@mozilla.com>
Fri, 07 Apr 2017 16:40:34 +0800
changeset 557751 ea38f40b0723f2692b592885daea7ae551a8c4b6
parent 557750 071e6050d8faee145ecf1f81133032c51f853825
child 623143 269378cbce9eb36aa414eb140b13ddc5ed44fef2
push id52813
push userbmo:tnguyen@mozilla.com
push dateFri, 07 Apr 2017 08:45:16 +0000
bugs1353853
milestone55.0a1
Bug 1353853 - P2 - Cache preferences when doing channel classify MozReview-Commit-ID: EDjfaWkKyx8
netwerk/base/nsChannelClassifier.cpp
--- a/netwerk/base/nsChannelClassifier.cpp
+++ b/netwerk/base/nsChannelClassifier.cpp
@@ -50,21 +50,43 @@ static LazyLogModule gChannelClassifierL
 
 // Whether channels should be annotated as being on the tracking protection
 // list.
 static bool sAnnotateChannelEnabled = false;
 // Whether the priority of the channels annotated as being on the tracking
 // protection list should be lowered.
 static bool sLowerNetworkPriority = false;
 static bool sIsInited = false;
+static bool sAllowListExample = false;
+static nsCString sTrackingWhitelist("");
+static nsCString sSkipHostname("");
 
 #undef LOG
 #define LOG(args)     MOZ_LOG(gChannelClassifierLog, LogLevel::Debug, args)
 #define LOG_ENABLED() MOZ_LOG_TEST(gChannelClassifierLog, LogLevel::Debug)
 
+#define URLCLASSIFIER_SKIP_HOSTNAME       "urlclassifier.skipHostnames"
+#define URLCLASSIFIER_TRACKINGWHITELIST   "urlclassifier.trackingWhitelistTable"
+
+static const char* kUrlClassifierPrefs[] = {
+  URLCLASSIFIER_SKIP_HOSTNAME,
+  URLCLASSIFIER_TRACKINGWHITELIST
+};
+
+static void
+UCPrefsChangedCallback(const char* aPref, void* aClosure)
+{
+  if (!strcmp(aPref, URLCLASSIFIER_SKIP_HOSTNAME)) {
+    Preferences::GetCString(URLCLASSIFIER_SKIP_HOSTNAME, &sSkipHostname);
+    ToLowerCase(sSkipHostname);
+  } else if (!strcmp(aPref, URLCLASSIFIER_TRACKINGWHITELIST)) {
+    Preferences::GetCString(URLCLASSIFIER_TRACKINGWHITELIST, &sTrackingWhitelist);
+  }
+}
+
 NS_IMPL_ISUPPORTS(nsChannelClassifier,
                   nsIURIClassifierCallback,
                   nsIObserver)
 
 nsChannelClassifier::nsChannelClassifier(nsIChannel *aChannel)
   : mIsAllowListed(false),
     mSuspendedChannel(false),
     mChannel(aChannel),
@@ -72,16 +94,21 @@ nsChannelClassifier::nsChannelClassifier
 {
   MOZ_ASSERT(mChannel);
   if (!sIsInited) {
     sIsInited = true;
     Preferences::AddBoolVarCache(&sAnnotateChannelEnabled,
                                  "privacy.trackingprotection.annotate_channels");
     Preferences::AddBoolVarCache(&sLowerNetworkPriority,
                                  "privacy.trackingprotection.lower_network_priority");
+    Preferences::AddBoolVarCache(&sAllowListExample,
+                                 "channelclassifier.allowlist_example");
+    for (size_t i = 0; i < ArrayLength(kUrlClassifierPrefs); i++) {
+      Preferences::RegisterCallback(UCPrefsChangedCallback, kUrlClassifierPrefs[i]);
+    }
   }
 }
 
 nsresult
 nsChannelClassifier::ShouldEnableTrackingProtection(bool *result)
 {
   nsresult rv = ShouldEnableTrackingProtectionInternal(mChannel, result);
   mTrackingProtectionEnabled = Some(*result);
@@ -151,18 +178,17 @@ nsChannelClassifier::ShouldEnableTrackin
 
     if (AddonMayLoad(aChannel, chanURI)) {
         return NS_OK;
     }
 
     nsCOMPtr<nsIIOService> ios = do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    const char ALLOWLIST_EXAMPLE_PREF[] = "channelclassifier.allowlist_example";
-    if (!topWinURI && Preferences::GetBool(ALLOWLIST_EXAMPLE_PREF, false)) {
+    if (!topWinURI && sAllowListExample) {
       LOG(("nsChannelClassifier[%p]: Allowlisting test domain\n", this));
       rv = ios->NewURI(NS_LITERAL_CSTRING("http://allowlisted.example.com"),
                        nullptr, nullptr, getter_AddRefs(topWinURI));
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
     // Take the host/port portion so we can allowlist by site. Also ignore the
     // scheme, since users who put sites on the allowlist probably don't expect
@@ -360,24 +386,20 @@ nsChannelClassifier::StartInternal()
     if (hasFlags) return NS_ERROR_UNEXPECTED;
 
     rv = NS_URIChainHasFlags(uri,
                              nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
                              &hasFlags);
     NS_ENSURE_SUCCESS(rv, rv);
     if (hasFlags) return NS_ERROR_UNEXPECTED;
 
-    // Skip whitelisted hostnames.
-    nsAutoCString whitelisted;
-    Preferences::GetCString("urlclassifier.skipHostnames", &whitelisted);
-    if (!whitelisted.IsEmpty()) {
-      ToLowerCase(whitelisted);
+    if (!sSkipHostname.IsEmpty()) {
       LOG(("nsChannelClassifier[%p]:StartInternal whitelisted hostnames = %s",
-           this, whitelisted.get()));
-      if (IsHostnameWhitelisted(uri, whitelisted)) {
+           this, sSkipHostname.get()));
+      if (IsHostnameWhitelisted(uri, sSkipHostname)) {
         return NS_ERROR_UNEXPECTED;
       }
     }
 
     nsCOMPtr<nsIURIClassifier> uriClassifier =
         do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv);
     if (rv == NS_ERROR_FACTORY_NOT_REGISTERED ||
         rv == NS_ERROR_NOT_AVAILABLE) {
@@ -728,20 +750,17 @@ nsChannelClassifier::IsTrackerWhiteliste
                                           const nsACString& aProvider,
                                           const nsACString& aPrefix)
 {
   nsresult rv;
   nsCOMPtr<nsIURIClassifier> uriClassifier =
     do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsAutoCString tables;
-  Preferences::GetCString("urlclassifier.trackingWhitelistTable", &tables);
-
-  if (tables.IsEmpty()) {
+  if (sTrackingWhitelist.IsEmpty()) {
     LOG(("nsChannelClassifier[%p]:IsTrackerWhitelisted whitelist disabled",
          this));
     return NS_ERROR_TRACKING_URI;
   }
 
   nsCOMPtr<nsIHttpChannelInternal> chan = do_QueryInterface(mChannel, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -775,17 +794,17 @@ nsChannelClassifier::IsTrackerWhiteliste
   nsCOMPtr<nsIURI> whitelistURI;
   rv = NS_NewURI(getter_AddRefs(whitelistURI), whitelistEntry);
   NS_ENSURE_SUCCESS(rv, rv);
 
   RefPtr<IsTrackerWhitelistedCallback> cb =
     new IsTrackerWhitelistedCallback(this, aList, aProvider, aPrefix,
                                      whitelistEntry);
 
-  return uriClassifier->AsyncClassifyLocalWithTables(whitelistURI, tables, cb);
+  return uriClassifier->AsyncClassifyLocalWithTables(whitelistURI, sTrackingWhitelist, cb);
 }
 
 NS_IMETHODIMP
 nsChannelClassifier::OnClassifyComplete(nsresult aErrorCode,
                                         const nsACString& aList,
                                         const nsACString& aProvider,
                                         const nsACString& aPrefix)
 {
@@ -912,15 +931,18 @@ nsChannelClassifier::Observe(nsISupports
 
     if (mChannel && mSuspendedChannel) {
       mSuspendedChannel = false;
       mChannel->Cancel(NS_ERROR_ABORT);
       mChannel->Resume();
     }
 
     RemoveShutdownObserver();
+    for (size_t i = 0; i < ArrayLength(kUrlClassifierPrefs); i++) {
+      Preferences::UnregisterCallback(UCPrefsChangedCallback, kUrlClassifierPrefs[i]);
+    }
   }
 
   return NS_OK;
 }
 
 } // namespace net
 } // namespace mozilla