Bug 1374114 - Add a pref to disable ftp. r?valentin draft
authorJonathan Kingston <jkt@mozilla.com>
Sun, 26 Nov 2017 20:46:31 +0000
changeset 737991 a3b1219de2f968289258ea5465ccc1fe310ff0cc
parent 737939 6602576987baec9edbaaad117114ba5227db6261
push id96819
push userbmo:jkt@mozilla.com
push dateThu, 25 Jan 2018 15:14:45 +0000
reviewersvalentin
bugs1374114
milestone60.0a1
Bug 1374114 - Add a pref to disable ftp. r?valentin MozReview-Commit-ID: ckzZ8bOKlk
modules/libpref/init/all.js
netwerk/protocol/ftp/nsFtpProtocolHandler.cpp
netwerk/protocol/ftp/nsFtpProtocolHandler.h
toolkit/components/places/tests/unifiedcomplete/test_search_suggestions.js
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1850,16 +1850,17 @@ pref("network.http.focused_window_transa
 pref("network.http.active_tab_priority", true);
 
 // default values for FTP
 // in a DSCP environment this should be 40 (0x28, or AF11), per RFC-4594,
 // Section 4.8 "High-Throughput Data Service Class", and 80 (0x50, or AF22)
 // per Section 4.7 "Low-Latency Data Service Class".
 pref("network.ftp.data.qos", 0);
 pref("network.ftp.control.qos", 0);
+pref("network.ftp.enabled", true);
 
 // The max time to spend on xpcom events between two polls in ms.
 pref("network.sts.max_time_for_events_between_two_polls", 100);
 
 // During shutdown we limit PR_Close calls. If time exceeds this pref (in ms)
 // let sockets just leak.
 pref("network.sts.max_time_for_pr_close_during_shutdown", 5000);
 // </http>
--- a/netwerk/protocol/ftp/nsFtpProtocolHandler.cpp
+++ b/netwerk/protocol/ftp/nsFtpProtocolHandler.cpp
@@ -35,25 +35,27 @@ LazyLogModule gFTPLog("nsFtp");
 #undef LOG
 #define LOG(args) MOZ_LOG(gFTPLog, mozilla::LogLevel::Debug, args)
 
 //-----------------------------------------------------------------------------
 
 #define IDLE_TIMEOUT_PREF     "network.ftp.idleConnectionTimeout"
 #define IDLE_CONNECTION_LIMIT 8 /* TODO pref me */
 
+#define ENABLED_PREF          "network.ftp.enabled"
 #define QOS_DATA_PREF         "network.ftp.data.qos"
 #define QOS_CONTROL_PREF      "network.ftp.control.qos"
 
 nsFtpProtocolHandler *gFtpHandler = nullptr;
 
 //-----------------------------------------------------------------------------
 
 nsFtpProtocolHandler::nsFtpProtocolHandler()
     : mIdleTimeout(-1)
+    , mEnabled(true)
     , mSessionId(0)
     , mControlQoSBits(0x00)
     , mDataQoSBits(0x00)
 {
     LOG(("FTP:creating handler @%p\n", this));
 
     gFtpHandler = this;
 }
@@ -86,30 +88,37 @@ nsFtpProtocolHandler::Init()
 
         rv = branch->GetIntPref(IDLE_TIMEOUT_PREF, &mIdleTimeout);
         if (NS_FAILED(rv))
             mIdleTimeout = 5*60; // 5 minute default
 
         rv = branch->AddObserver(IDLE_TIMEOUT_PREF, this, true);
         if (NS_FAILED(rv)) return rv;
 
-	int32_t val;
-	rv = branch->GetIntPref(QOS_DATA_PREF, &val);
-	if (NS_SUCCEEDED(rv))
-	    mDataQoSBits = (uint8_t) clamped(val, 0, 0xff);
+        rv = branch->GetBoolPref(ENABLED_PREF, &mEnabled);
+        if (NS_FAILED(rv))
+            mEnabled = true;
+
+        rv = branch->AddObserver(ENABLED_PREF, this, true);
+        if (NS_FAILED(rv)) return rv;
 
-	rv = branch->AddObserver(QOS_DATA_PREF, this, true);
-	if (NS_FAILED(rv)) return rv;
+      	int32_t val;
+      	rv = branch->GetIntPref(QOS_DATA_PREF, &val);
+      	if (NS_SUCCEEDED(rv))
+      	    mDataQoSBits = (uint8_t) clamped(val, 0, 0xff);
 
-	rv = branch->GetIntPref(QOS_CONTROL_PREF, &val);
-	if (NS_SUCCEEDED(rv))
-	    mControlQoSBits = (uint8_t) clamped(val, 0, 0xff);
+      	rv = branch->AddObserver(QOS_DATA_PREF, this, true);
+      	if (NS_FAILED(rv)) return rv;
 
-	rv = branch->AddObserver(QOS_CONTROL_PREF, this, true);
-	if (NS_FAILED(rv)) return rv;
+      	rv = branch->GetIntPref(QOS_CONTROL_PREF, &val);
+      	if (NS_SUCCEEDED(rv))
+      	    mControlQoSBits = (uint8_t) clamped(val, 0, 0xff);
+
+      	rv = branch->AddObserver(QOS_CONTROL_PREF, this, true);
+      	if (NS_FAILED(rv)) return rv;
     }
 
     nsCOMPtr<nsIObserverService> observerService =
         mozilla::services::GetObserverService();
     if (observerService) {
         observerService->AddObserver(this,
                                      "network:offline-about-to-go-offline",
                                      true);
@@ -149,16 +158,19 @@ nsFtpProtocolHandler::GetProtocolFlags(u
 }
 
 NS_IMETHODIMP
 nsFtpProtocolHandler::NewURI(const nsACString &aSpec,
                              const char *aCharset,
                              nsIURI *aBaseURI,
                              nsIURI **result)
 {
+    if (!mEnabled) {
+        return NS_ERROR_UNKNOWN_PROTOCOL;
+    }
     nsAutoCString spec(aSpec);
     spec.Trim(" \t\n\r"); // Match NS_IsAsciiWhitespace instead of HTML5
 
     char *fwdPtr = spec.BeginWriting();
 
     // now unescape it... %xx reduced inline to resulting character
 
     int32_t len = NS_UnescapeURL(fwdPtr);
@@ -375,16 +387,20 @@ nsFtpProtocolHandler::Observe(nsISupport
         if (!branch) {
             NS_ERROR("no prefbranch");
             return NS_ERROR_UNEXPECTED;
         }
         int32_t val;
         nsresult rv = branch->GetIntPref(IDLE_TIMEOUT_PREF, &val);
         if (NS_SUCCEEDED(rv))
             mIdleTimeout = val;
+        bool enabled;
+        rv = branch->GetBoolPref(ENABLED_PREF, &enabled);
+        if (NS_SUCCEEDED(rv))
+            mEnabled = enabled;
 
 	rv = branch->GetIntPref(QOS_DATA_PREF, &val);
 	if (NS_SUCCEEDED(rv))
 	    mDataQoSBits = (uint8_t) clamped(val, 0, 0xff);
 
 	rv = branch->GetIntPref(QOS_CONTROL_PREF, &val);
 	if (NS_SUCCEEDED(rv))
 	    mControlQoSBits = (uint8_t) clamped(val, 0, 0xff);
--- a/netwerk/protocol/ftp/nsFtpProtocolHandler.h
+++ b/netwerk/protocol/ftp/nsFtpProtocolHandler.h
@@ -60,16 +60,17 @@ private:
     };
 
     static void Timeout(nsITimer *aTimer, void *aClosure);
     void ClearAllConnections();
 
     nsTArray<timerStruct*> mRootConnectionList;
 
     int32_t mIdleTimeout;
+    bool mEnabled;
 
     // When "clear active logins" is performed, all idle connection are dropped
     // and mSessionId is incremented. When nsFtpState wants to insert idle
     // connection we refuse to cache if its mSessionId is different (i.e.
     // control connection had been created before last "clear active logins" was
     // performed.
     uint32_t mSessionId;
 
--- a/toolkit/components/places/tests/unifiedcomplete/test_search_suggestions.js
+++ b/toolkit/components/places/tests/unifiedcomplete/test_search_suggestions.js
@@ -868,29 +868,99 @@ add_task(async function avoid_http_url_s
       {
         uri: makeActionURI("visiturl", { url: "http://https/", input: "https:" }),
         style: [ "action", "visiturl", "heuristic" ],
         title: "http://https/",
       },
     ],
   });
 
+  // Check FTP enabled
+  Services.prefs.setBoolPref("network.ftp.enabled", true);
+  registerCleanupFunction(() => Services.prefs.clearUserPref("network.ftp.enabled"));
+
   await check_autocomplete({
     search: "ftp:",
     searchParam: "enable-actions",
     matches: [
       {
         uri: makeActionURI("visiturl", { url: "http://ftp/", input: "ftp:" }),
         style: [ "action", "visiturl", "heuristic" ],
         title: "http://ftp/",
       },
     ],
   });
 
   await check_autocomplete({
+    search: "ftp:/",
+    searchParam: "enable-actions",
+    matches: [
+      {
+        uri: makeActionURI("visiturl", { url: "http://ftp/", input: "ftp:/" }),
+        style: [ "action", "visiturl", "heuristic" ],
+        title: "http://ftp/",
+      },
+    ],
+  });
+
+  await check_autocomplete({
+    search: "ftp://",
+    searchParam: "enable-actions",
+    matches: [
+      makeSearchMatch("ftp://", { engineName: ENGINE_NAME, heuristic: true }),
+    ],
+  });
+
+  await check_autocomplete({
+    search: "ftp://test",
+    searchParam: "enable-actions",
+    matches: [
+      {
+        uri: makeActionURI("visiturl", { url: "ftp://test/", input: "ftp://test" }),
+        style: [ "action", "visiturl", "heuristic" ],
+        title: "ftp://test/",
+      },
+    ],
+  });
+
+  // Check FTP disabled
+  Services.prefs.setBoolPref("network.ftp.enabled", false);
+  await check_autocomplete({
+    search: "ftp:",
+    searchParam: "enable-actions",
+    matches: [
+      makeSearchMatch("ftp:", { engineName: ENGINE_NAME, heuristic: true }),
+    ],
+  });
+
+  await check_autocomplete({
+    search: "ftp:/",
+    searchParam: "enable-actions",
+    matches: [
+      makeSearchMatch("ftp:/", { engineName: ENGINE_NAME, heuristic: true }),
+    ],
+  });
+
+  await check_autocomplete({
+    search: "ftp://",
+    searchParam: "enable-actions",
+    matches: [
+      makeSearchMatch("ftp://", { engineName: ENGINE_NAME, heuristic: true }),
+    ],
+  });
+
+  await check_autocomplete({
+    search: "ftp://test",
+    searchParam: "enable-actions",
+    matches: [
+      makeSearchMatch("ftp://test", { engineName: ENGINE_NAME, heuristic: true }),
+    ],
+  });
+
+  await check_autocomplete({
     search: "http:/",
     searchParam: "enable-actions",
     matches: [
       {
         uri: makeActionURI("visiturl", { url: "http://http/", input: "http:/" }),
         style: [ "action", "visiturl", "heuristic" ],
         title: "http://http/",
       },
@@ -905,52 +975,32 @@ add_task(async function avoid_http_url_s
         uri: makeActionURI("visiturl", { url: "http://https/", input: "https:/" }),
         style: [ "action", "visiturl", "heuristic" ],
         title: "http://https/",
       },
     ],
   });
 
   await check_autocomplete({
-    search: "ftp:/",
-    searchParam: "enable-actions",
-    matches: [
-      {
-        uri: makeActionURI("visiturl", { url: "http://ftp/", input: "ftp:/" }),
-        style: [ "action", "visiturl", "heuristic" ],
-        title: "http://ftp/",
-      },
-    ],
-  });
-
-  await check_autocomplete({
     search: "http://",
     searchParam: "enable-actions",
     matches: [
       makeSearchMatch("http://", { engineName: ENGINE_NAME, heuristic: true }),
     ],
   });
 
   await check_autocomplete({
     search: "https://",
     searchParam: "enable-actions",
     matches: [
       makeSearchMatch("https://", { engineName: ENGINE_NAME, heuristic: true }),
     ],
   });
 
   await check_autocomplete({
-    search: "ftp://",
-    searchParam: "enable-actions",
-    matches: [
-      makeSearchMatch("ftp://", { engineName: ENGINE_NAME, heuristic: true }),
-    ],
-  });
-
-  await check_autocomplete({
     search: "http://www",
     searchParam: "enable-actions",
     matches: [
       {
         uri: makeActionURI("visiturl", { url: "http://www/", input: "http://www" }),
         style: [ "action", "visiturl", "heuristic" ],
         title: "http://www/",
       },
@@ -989,28 +1039,16 @@ add_task(async function avoid_http_url_s
         uri: makeActionURI("visiturl", { url: "https://test/", input: "https://test" }),
         style: [ "action", "visiturl", "heuristic" ],
         title: "https://test/",
       },
     ],
   });
 
   await check_autocomplete({
-    search: "ftp://test",
-    searchParam: "enable-actions",
-    matches: [
-      {
-        uri: makeActionURI("visiturl", { url: "ftp://test/", input: "ftp://test" }),
-        style: [ "action", "visiturl", "heuristic" ],
-        title: "ftp://test/",
-      },
-    ],
-  });
-
-  await check_autocomplete({
     search: "http://www.test",
     searchParam: "enable-actions",
     matches: [
       {
         uri: makeActionURI("visiturl", { url: "http://www.test/", input: "http://www.test" }),
         style: [ "action", "visiturl", "heuristic" ],
         title: "http://www.test/",
       },