Backed out 4 changesets (bug 1502025) for X failures in netwerk/test/unit/test_network_connectivity_service.js CLOSED TREE
authorshindli <shindli@mozilla.com>
Sat, 01 Dec 2018 01:14:34 +0200
changeset 508232 d20e7d5440cb5e24bb2c4c6b6ac2e9c59e2eb4ec
parent 508231 01dc9a4352c63c58a53724b4d9a5d090e0722989
child 508233 0bbae43c6e6ef271e7287c224d98ac268b18fdbe
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1502025
milestone65.0a1
backs outbf4254adcdfedbd00b599d43b52da664dd518629
731cbca9930db52362a0a6c2c76d43597afe36b4
9bfdb64bf81e6e92999272c91f5d51c6847fb53a
99eed75874f1fa653c3cc35a509b191d16ec89fe
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
Backed out 4 changesets (bug 1502025) for X failures in netwerk/test/unit/test_network_connectivity_service.js CLOSED TREE Backed out changeset bf4254adcdfe (bug 1502025) Backed out changeset 731cbca9930d (bug 1502025) Backed out changeset 9bfdb64bf81e (bug 1502025) Backed out changeset 99eed75874f1 (bug 1502025)
modules/libpref/init/all.js
netwerk/base/NetworkConnectivityService.cpp
netwerk/base/NetworkConnectivityService.h
netwerk/base/nsINetworkConnectivityService.idl
netwerk/base/nsIOService.cpp
netwerk/base/nsIServerSocket.idl
netwerk/base/nsServerSocket.cpp
netwerk/base/nsSocketTransport2.cpp
netwerk/base/nsSocketTransport2.h
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/HttpBaseChannel.h
netwerk/protocol/http/TrackingDummyChannel.cpp
netwerk/protocol/http/nsHttp.h
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpConnectionInfo.cpp
netwerk/protocol/http/nsHttpConnectionInfo.h
netwerk/protocol/http/nsHttpConnectionMgr.cpp
netwerk/protocol/http/nsIHttpChannelInternal.idl
netwerk/protocol/viewsource/nsViewSourceChannel.cpp
netwerk/test/httpserver/httpd.js
netwerk/test/unit/test_network_connectivity_service.js
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -5460,18 +5460,16 @@ pref("network.captive-portal-service.min
 pref("network.captive-portal-service.maxInterval", 1500000); // 25 minutes
 // Every 10 checks, the delay is increased by a factor of 5
 pref("network.captive-portal-service.backoffFactor", "5.0");
 pref("network.captive-portal-service.enabled", false);
 
 pref("network.connectivity-service.enabled", true);
 pref("network.connectivity-service.DNSv4.domain", "mozilla.org");
 pref("network.connectivity-service.DNSv6.domain", "mozilla.org");
-pref("network.connectivity-service.IPv4.url", "http://detectportal.firefox.com/success.txt?ipv4");
-pref("network.connectivity-service.IPv6.url", "http://detectportal.firefox.com/success.txt?ipv6");
 
 // DNS Trusted Recursive Resolver
 // 0 - default off, 1 - race, 2 TRR first, 3 TRR only, 4 shadow, 5 off by choice
 pref("network.trr.mode", 0);
 // DNS-over-HTTP service to use, must be HTTPS://
 pref("network.trr.uri", "https://mozilla.cloudflare-dns.com/dns-query");
 // credentials to pass to DOH end-point
 pref("network.trr.credentials", "");
--- a/netwerk/base/NetworkConnectivityService.cpp
+++ b/netwerk/base/NetworkConnectivityService.cpp
@@ -2,24 +2,22 @@
  * 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/. */
 
 #include "NetworkConnectivityService.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "xpcpublic.h"
 #include "nsSocketTransport2.h"
-#include "nsIURIMutator.h"
-#include "nsINetworkLinkService.h"
 
 namespace mozilla {
 namespace net {
 
-NS_IMPL_ISUPPORTS(NetworkConnectivityService, nsIDNSListener, nsIObserver,
-                  nsINetworkConnectivityService, nsIStreamListener)
+NS_IMPL_ISUPPORTS(NetworkConnectivityService, nsINetworkConnectivityService,
+                  nsIObserver, nsIDNSListener)
 
 static StaticRefPtr<NetworkConnectivityService> gConnService;
 
 // static
 already_AddRefed<NetworkConnectivityService>
 NetworkConnectivityService::GetSingleton() {
   if (gConnService) {
     return do_AddRef(gConnService);
@@ -32,67 +30,67 @@ NetworkConnectivityService::GetSingleton
   ClearOnShutdown(&gConnService);
   return do_AddRef(gConnService);
 }
 
 nsresult NetworkConnectivityService::Init() {
   nsCOMPtr<nsIObserverService> observerService =
       mozilla::services::GetObserverService();
   observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
-  observerService->AddObserver(this, NS_NETWORK_LINK_TOPIC, false);
   observerService->AddObserver(this, "network:captive-portal-connectivity",
                                false);
 
+  // We need to schedule this for a bit later, to avoid a recursive service
+  // initialization.
+  MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(
+      NewRunnableMethod("NetworkConnectivityService::PerformChecks", this,
+                        &NetworkConnectivityService::PerformChecks)));
   return NS_OK;
 }
 
 NS_IMETHODIMP
-NetworkConnectivityService::GetDNSv4(ConnectivityState *aState) {
+NetworkConnectivityService::GetDNSv4(int32_t *aState) {
   NS_ENSURE_ARG(aState);
   *aState = mDNSv4;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-NetworkConnectivityService::GetDNSv6(ConnectivityState *aState) {
+NetworkConnectivityService::GetDNSv6(int32_t *aState) {
   NS_ENSURE_ARG(aState);
   *aState = mDNSv6;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-NetworkConnectivityService::GetIPv4(ConnectivityState *aState) {
+NetworkConnectivityService::GetIPv4(int32_t *aState) {
   NS_ENSURE_ARG(aState);
-  *aState = mIPv4;
+  *aState = nsSocketTransport::HasIPv4Connectivity()
+                ? nsINetworkConnectivityService::OK
+                : nsINetworkConnectivityService::NOT_AVAILABLE;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-NetworkConnectivityService::GetIPv6(ConnectivityState *aState) {
+NetworkConnectivityService::GetIPv6(int32_t *aState) {
   NS_ENSURE_ARG(aState);
-  *aState = mIPv6;
+  *aState = nsSocketTransport::HasIPv6Connectivity()
+                ? nsINetworkConnectivityService::OK
+                : nsINetworkConnectivityService::NOT_AVAILABLE;
   return NS_OK;
 }
 
-void NetworkConnectivityService::PerformChecks() {
-  mDNSv4 = UNKNOWN;
-  mDNSv6 = UNKNOWN;
-
-  mIPv4 = UNKNOWN;
-  mIPv6 = UNKNOWN;
-
-  RecheckDNS();
-  RecheckIPConnectivity();
-}
+void NetworkConnectivityService::PerformChecks() { RecheckDNS(); }
 
 NS_IMETHODIMP
 NetworkConnectivityService::OnLookupComplete(nsICancelable *aRequest,
                                              nsIDNSRecord *aRecord,
                                              nsresult aStatus) {
-  ConnectivityState state = aRecord ? OK : NOT_AVAILABLE;
+  int32_t state = aRecord ? nsINetworkConnectivityService::OK
+                          : nsINetworkConnectivityService::NOT_AVAILABLE;
 
   if (aRequest == mDNSv4Request) {
     mDNSv4 = state;
     mDNSv4Request = nullptr;
   } else if (aRequest == mDNSv6Request) {
     mDNSv6 = state;
     mDNSv6Request = nullptr;
   }
@@ -132,162 +130,34 @@ NetworkConnectivityService::RecheckDNS()
   return rv;
 }
 
 NS_IMETHODIMP
 NetworkConnectivityService::Observe(nsISupports *aSubject, const char *aTopic,
                                     const char16_t *aData) {
   if (!strcmp(aTopic, "network:captive-portal-connectivity")) {
     // Captive portal is cleared, so we redo the checks.
+    mDNSv4 = nsINetworkConnectivityService::UNKNOWN;
+    mDNSv6 = nsINetworkConnectivityService::UNKNOWN;
+
     PerformChecks();
   } else if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
     if (mDNSv4Request) {
       mDNSv4Request->Cancel(NS_ERROR_ABORT);
       mDNSv4Request = nullptr;
     }
     if (mDNSv6Request) {
       mDNSv6Request->Cancel(NS_ERROR_ABORT);
       mDNSv6Request = nullptr;
     }
 
     nsCOMPtr<nsIObserverService> observerService =
         mozilla::services::GetObserverService();
     observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
     observerService->RemoveObserver(this,
                                     "network:captive-portal-connectivity");
-    observerService->RemoveObserver(this, NS_NETWORK_LINK_TOPIC);
-  } else if (!strcmp(aTopic, NS_NETWORK_LINK_TOPIC) &&
-             !NS_LITERAL_STRING(NS_NETWORK_LINK_DATA_UNKNOWN).Equals(aData)) {
-    PerformChecks();
   }
 
   return NS_OK;
 }
 
-static inline already_AddRefed<nsIChannel> SetupIPCheckChannel(bool ipv4) {
-  nsresult rv;
-  nsAutoCString url;
-
-  if (ipv4) {
-    rv = Preferences::GetCString("network.connectivity-service.IPv4.url", url);
-  } else {
-    rv = Preferences::GetCString("network.connectivity-service.IPv6.url", url);
-  }
-  NS_ENSURE_SUCCESS(rv, nullptr);
-
-  nsCOMPtr<nsIURI> uri;
-  rv = NS_NewURI(getter_AddRefs(uri), url);
-  NS_ENSURE_SUCCESS(rv, nullptr);
-
-  nsCOMPtr<nsIChannel> channel;
-  rv = NS_NewChannel(
-      getter_AddRefs(channel), uri, nsContentUtils::GetSystemPrincipal(),
-      nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
-      nsIContentPolicy::TYPE_OTHER,
-      nullptr,  // aPerformanceStorage
-      nullptr,  // aLoadGroup
-      nullptr,
-      nsIRequest::LOAD_BYPASS_CACHE |    // don't read from the cache
-          nsIRequest::INHIBIT_CACHING |  // don't write the response to cache
-          nsIRequest::LOAD_ANONYMOUS);   // prevent privacy leaks
-
-  NS_ENSURE_SUCCESS(rv, nullptr);
-
-  nsCOMPtr<nsIHttpChannelInternal> internalChan = do_QueryInterface(channel);
-  NS_ENSURE_TRUE(internalChan, nullptr);
-
-  if (ipv4) {
-    internalChan->SetIPv6Disabled();
-  } else {
-    internalChan->SetIPv4Disabled();
-  }
-
-  return channel.forget();
-}
-
-NS_IMETHODIMP
-NetworkConnectivityService::RecheckIPConnectivity() {
-  bool enabled =
-      Preferences::GetBool("network.connectivity-service.enabled", false);
-  if (!enabled) {
-    return NS_OK;
-  }
-
-  if (xpc::AreNonLocalConnectionsDisabled() &&
-      !Preferences::GetBool("network.captive-portal-service.testMode", false)) {
-    return NS_OK;
-  }
-
-  if (mIPv4Channel) {
-    mIPv4Channel->Cancel(NS_ERROR_ABORT);
-    mIPv4Channel = nullptr;
-  }
-  if (mIPv6Channel) {
-    mIPv6Channel->Cancel(NS_ERROR_ABORT);
-    mIPv6Channel = nullptr;
-  }
-
-  nsresult rv;
-  mIPv4Channel = SetupIPCheckChannel(/* ipv4 = */ true);
-  if (mIPv4Channel) {
-    rv = mIPv4Channel->AsyncOpen2(this);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  mIPv6Channel = SetupIPCheckChannel(/* ipv4 = */ false);
-  if (mIPv6Channel) {
-    rv = mIPv6Channel->AsyncOpen2(this);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-NetworkConnectivityService::OnStartRequest(nsIRequest *aRequest,
-                                           nsISupports *aContext) {
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-NetworkConnectivityService::OnStopRequest(nsIRequest *aRequest,
-                                          nsISupports *aContext,
-                                          nsresult aStatusCode) {
-  if (aStatusCode == NS_ERROR_ABORT) {
-    return NS_OK;
-  }
-
-  ConnectivityState status = NS_FAILED(aStatusCode) ? NOT_AVAILABLE : OK;
-
-  if (aRequest == mIPv4Channel) {
-    mIPv4 = status;
-    mIPv4Channel = nullptr;
-  } else if (aRequest == mIPv6Channel) {
-#ifdef DEBUG
-    // Verify that the check was performed over IPv6
-    nsCOMPtr<nsIHttpChannelInternal> v6Internal = do_QueryInterface(aRequest);
-    MOZ_ASSERT(v6Internal);
-    nsAutoCString peerAddr;
-    Unused << v6Internal->GetRemoteAddress(peerAddr);
-    MOZ_ASSERT(peerAddr.Contains(':') || NS_FAILED(aStatusCode));
-#endif
-
-    mIPv6 = status;
-    mIPv6Channel = nullptr;
-  } else {
-    MOZ_ASSERT(false, "Unknown request");
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-NetworkConnectivityService::OnDataAvailable(nsIRequest *aRequest,
-                                            nsISupports *aContext,
-                                            nsIInputStream *aInputStream,
-                                            uint64_t aOffset, uint32_t aCount) {
-  nsAutoCString data;
-  Unused << NS_ReadInputStreamToString(aInputStream, data, aCount);
-  return NS_OK;
-}
-
 }  // namespace net
 }  // namespace mozilla
--- a/netwerk/base/NetworkConnectivityService.h
+++ b/netwerk/base/NetworkConnectivityService.h
@@ -7,48 +7,39 @@
 
 #include "nsINetworkConnectivityService.h"
 
 namespace mozilla {
 namespace net {
 
 class NetworkConnectivityService : public nsINetworkConnectivityService,
                                    public nsIObserver,
-                                   public nsIDNSListener,
-                                   public nsIStreamListener {
+                                   public nsIDNSListener {
  public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSINETWORKCONNECTIVITYSERVICE
   NS_DECL_NSIOBSERVER
   NS_DECL_NSIDNSLISTENER
-  NS_DECL_NSISTREAMLISTENER
-  NS_DECL_NSIREQUESTOBSERVER
 
   nsresult Init();
   static already_AddRefed<NetworkConnectivityService> GetSingleton();
 
  private:
   NetworkConnectivityService() = default;
   virtual ~NetworkConnectivityService() = default;
 
   // Calls all the check methods
   void PerformChecks();
 
   // Will be set to OK if the DNS request returned in IP of this type,
   //                NOT_AVAILABLE if that type of resolution is not available
   //                UNKNOWN if the check wasn't performed
-  ConnectivityState mDNSv4 = nsINetworkConnectivityService::UNKNOWN;
-  ConnectivityState mDNSv6 = nsINetworkConnectivityService::UNKNOWN;
-
-  ConnectivityState mIPv4 = nsINetworkConnectivityService::UNKNOWN;
-  ConnectivityState mIPv6 = nsINetworkConnectivityService::UNKNOWN;
+  int32_t mDNSv4 = nsINetworkConnectivityService::UNKNOWN;
+  int32_t mDNSv6 = nsINetworkConnectivityService::UNKNOWN;
 
   nsCOMPtr<nsICancelable> mDNSv4Request;
   nsCOMPtr<nsICancelable> mDNSv6Request;
-
-  nsCOMPtr<nsIChannel> mIPv4Channel;
-  nsCOMPtr<nsIChannel> mIPv6Channel;
 };
 
 }  // namespace net
 }  // namespace mozilla
 
 #endif  // NetworkConnectivityService_h_
--- a/netwerk/base/nsINetworkConnectivityService.idl
+++ b/netwerk/base/nsINetworkConnectivityService.idl
@@ -9,28 +9,23 @@ interface nsINetworkConnectivityService 
 {
   /**
    * Each tested feature may be in one of 3 states:
    *   UNKNOWN, if a check hasn't been performed.
    *   OK, if the feature was successfully tested
    *   NOT_AVAILABLE, if the feature is blocked by the network.
    *                  Note that the endpoints are guaranteed to support the features.
    */
-  cenum ConnectivityState: 8 {
-    UNKNOWN             = 0,
-    OK                  = 1,
-    NOT_AVAILABLE       = 2
-  };
+  const long UNKNOWN             = 0;
+  const long OK                  = 1;
+  const long NOT_AVAILABLE       = 2;
 
   /* If DNS v4/v6 queries actually work on the current network */
-  readonly attribute nsINetworkConnectivityService_ConnectivityState DNSv4;
-  readonly attribute nsINetworkConnectivityService_ConnectivityState DNSv6;
+  readonly attribute long DNSv4;
+  readonly attribute long DNSv6;
 
   /* If connecting to IPv4/v6 works on the current network */
-  readonly attribute nsINetworkConnectivityService_ConnectivityState IPv4;
-  readonly attribute nsINetworkConnectivityService_ConnectivityState IPv6;
+  readonly attribute long IPv4;
+  readonly attribute long IPv6;
 
   /* Starts the DNS request to check for DNS v4/v6 availability */
   void recheckDNS();
-
-  /* Starts HTTP requests over IPv4 and IPv6, and checks if they work */
-  void recheckIPConnectivity();
 };
--- a/netwerk/base/nsIOService.cpp
+++ b/netwerk/base/nsIOService.cpp
@@ -254,16 +254,20 @@ nsresult nsIOService::Init() {
 
   gIOService = this;
 
   InitializeNetworkLinkService();
   InitializeProtocolProxyService();
 
   SetOffline(false);
 
+  RefPtr<NetworkConnectivityService> ncs =
+      NetworkConnectivityService::GetSingleton();
+  ncs->Init();
+
   return NS_OK;
 }
 
 nsIOService::~nsIOService() {
   if (gIOService) {
     MOZ_ASSERT(gIOService == this);
     gIOService = nullptr;
   }
@@ -276,20 +280,16 @@ nsresult nsIOService::InitializeCaptiveP
   }
 
   mCaptivePortalService = do_GetService(NS_CAPTIVEPORTAL_CID);
   if (mCaptivePortalService) {
     return static_cast<CaptivePortalService *>(mCaptivePortalService.get())
         ->Initialize();
   }
 
-  RefPtr<NetworkConnectivityService> ncs =
-      NetworkConnectivityService::GetSingleton();
-  ncs->Init();
-
   return NS_OK;
 }
 
 nsresult nsIOService::InitializeSocketTransportService() {
   nsresult rv = NS_OK;
 
   if (!mSocketTransportService) {
     mSocketTransportService =
--- a/netwerk/base/nsIServerSocket.idl
+++ b/netwerk/base/nsIServerSocket.idl
@@ -55,23 +55,16 @@ interface nsIServerSocket : nsISupports
      *        This parameter may be silently limited by the operating system.
      *        Pass -1 to use the default value.
      */
     void init(in long aPort,
               in boolean aLoopbackOnly,
               in long aBackLog);
 
     /**
-     * the same as init(), but initializes an IPv6 server socket
-     */
-    void initIPv6(in long aPort,
-                  in boolean aLoopbackOnly,
-                  in long aBackLog);
-
-    /**
      * initSpecialConnection
      *
      * This method initializes a server socket and offers the ability to have
      * that socket not get terminated if Gecko is set offline.
      *
      * @param aPort
      *        The port of the server socket.  Pass -1 to indicate no preference,
      *        and a port will be selected automatically.
--- a/netwerk/base/nsServerSocket.cpp
+++ b/netwerk/base/nsServerSocket.cpp
@@ -250,35 +250,16 @@ NS_IMPL_ISUPPORTS(nsServerSocket, nsISer
 
 NS_IMETHODIMP
 nsServerSocket::Init(int32_t aPort, bool aLoopbackOnly, int32_t aBackLog) {
   return InitSpecialConnection(aPort, aLoopbackOnly ? LoopbackOnly : 0,
                                aBackLog);
 }
 
 NS_IMETHODIMP
-nsServerSocket::InitIPv6(int32_t aPort, bool aLoopbackOnly, int32_t aBackLog) {
-  PRNetAddrValue val;
-  PRNetAddr addr;
-
-  if (aPort < 0) {
-    aPort = 0;
-  }
-  if (aLoopbackOnly) {
-    val = PR_IpAddrLoopback;
-  } else {
-    val = PR_IpAddrAny;
-  }
-  PR_SetNetAddr(val, PR_AF_INET6, aPort, &addr);
-
-  mKeepWhenOffline = false;
-  return InitWithAddress(&addr, aBackLog);
-}
-
-NS_IMETHODIMP
 nsServerSocket::InitWithFilename(nsIFile *aPath, uint32_t aPermissions,
                                  int32_t aBacklog) {
 #if defined(XP_UNIX)
   nsresult rv;
 
   nsAutoCString path;
   rv = aPath->GetNativePath(path);
   if (NS_FAILED(rv)) return rv;
--- a/netwerk/base/nsSocketTransport2.cpp
+++ b/netwerk/base/nsSocketTransport2.cpp
@@ -680,16 +680,25 @@ nsSocketOutputStream::AsyncWait(nsIOutpu
   mTransport->OnOutputPending();
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // socket transport impl
 //-----------------------------------------------------------------------------
 
+// We assume we have connectivity at first.
+bool nsSocketTransport::sHasIPv4Connectivity = true;
+bool nsSocketTransport::sHasIPv6Connectivity = true;
+
+uint32_t nsSocketTransport::sIPv4FailedCounter = 0;
+uint32_t nsSocketTransport::sIPv6FailedCounter = 0;
+
+const uint32_t kFailureThreshold = 50;
+
 nsSocketTransport::nsSocketTransport()
     : mTypes(nullptr),
       mTypeCount(0),
       mPort(0),
       mProxyPort(0),
       mOriginPort(0),
       mProxyTransparent(false),
       mProxyTransparentResolvesHost(false),
@@ -1752,21 +1761,29 @@ bool nsSocketTransport::RecoverFromError
 
   } else {
     // This is only needed for telemetry.
     if (NS_SUCCEEDED(mFirstRetryError)) {
       mFirstRetryError = mCondition;
     }
     if ((mState == STATE_CONNECTING) && mDNSRecord) {
       if (mNetAddr.raw.family == AF_INET) {
+        sIPv4FailedCounter++;
+        if (sIPv4FailedCounter > kFailureThreshold) {
+          sHasIPv4Connectivity = false;
+        }
         if (mSocketTransportService->IsTelemetryEnabledAndNotSleepPhase()) {
           Telemetry::Accumulate(Telemetry::IPV4_AND_IPV6_ADDRESS_CONNECTIVITY,
                                 UNSUCCESSFUL_CONNECTING_TO_IPV4_ADDRESS);
         }
       } else if (mNetAddr.raw.family == AF_INET6) {
+        sIPv6FailedCounter++;
+        if (sIPv6FailedCounter > kFailureThreshold) {
+          sHasIPv6Connectivity = false;
+        }
         if (mSocketTransportService->IsTelemetryEnabledAndNotSleepPhase()) {
           Telemetry::Accumulate(Telemetry::IPV4_AND_IPV6_ADDRESS_CONNECTIVITY,
                                 UNSUCCESSFUL_CONNECTING_TO_IPV6_ADDRESS);
         }
       }
     }
 
     if (mConnectionFlags & RETRY_WITH_DIFFERENT_IP_FAMILY &&
@@ -2219,21 +2236,25 @@ void nsSocketTransport::OnSocketReady(PR
 
     if (status == PR_SUCCESS) {
       //
       // we are connected!
       //
       OnSocketConnected();
 
       if (mNetAddr.raw.family == AF_INET) {
+        sIPv4FailedCounter = 0;
+        sHasIPv4Connectivity = true;
         if (mSocketTransportService->IsTelemetryEnabledAndNotSleepPhase()) {
           Telemetry::Accumulate(Telemetry::IPV4_AND_IPV6_ADDRESS_CONNECTIVITY,
                                 SUCCESSFUL_CONNECTING_TO_IPV4_ADDRESS);
         }
       } else if (mNetAddr.raw.family == AF_INET6) {
+        sIPv6FailedCounter = 0;
+        sHasIPv6Connectivity = true;
         if (mSocketTransportService->IsTelemetryEnabledAndNotSleepPhase()) {
           Telemetry::Accumulate(Telemetry::IPV4_AND_IPV6_ADDRESS_CONNECTIVITY,
                                 SUCCESSFUL_CONNECTING_TO_IPV6_ADDRESS);
         }
       }
     } else {
       PRErrorCode code = PR_GetError();
 #if defined(TEST_CONNECT_ERRORS)
--- a/netwerk/base/nsSocketTransport2.h
+++ b/netwerk/base/nsSocketTransport2.h
@@ -166,16 +166,19 @@ class nsSocketTransport final : public n
   uint64_t ByteCountSent() override { return mOutput.ByteCount(); }
   static void CloseSocket(PRFileDesc *aFd, bool aTelemetryEnabled);
   static void SendPRBlockingTelemetry(
       PRIntervalTime aStart, Telemetry::HistogramID aIDNormal,
       Telemetry::HistogramID aIDShutdown,
       Telemetry::HistogramID aIDConnectivityChange,
       Telemetry::HistogramID aIDLinkChange, Telemetry::HistogramID aIDOffline);
 
+  static bool HasIPv4Connectivity() { return sHasIPv4Connectivity; }
+  static bool HasIPv6Connectivity() { return sHasIPv6Connectivity; }
+
  protected:
   virtual ~nsSocketTransport();
   void CleanupTypes();
 
  private:
   // event types
   enum {
     MSG_ENSURE_CONNECT,
@@ -463,14 +466,19 @@ class nsSocketTransport final : public n
 
   // A Fast Open callback.
   TCPFastOpen *mFastOpenCallback;
   bool mFastOpenLayerHasBufferedData;
   uint8_t mFastOpenStatus;
   nsresult mFirstRetryError;
 
   bool mDoNotRetryToConnect;
+
+  static bool sHasIPv4Connectivity;
+  static bool sHasIPv6Connectivity;
+  static uint32_t sIPv4FailedCounter;
+  static uint32_t sIPv6FailedCounter;
 };
 
 }  // namespace net
 }  // namespace mozilla
 
 #endif  // !nsSocketTransport_h__
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -4503,14 +4503,10 @@ HttpBaseChannel::GetNativeServerTiming(
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpBaseChannel::CancelForTrackingProtection() {
   return Cancel(NS_ERROR_TRACKING_URI);
 }
 
-void HttpBaseChannel::SetIPv4Disabled() { mCaps |= NS_HTTP_DISABLE_IPV4; }
-
-void HttpBaseChannel::SetIPv6Disabled() { mCaps |= NS_HTTP_DISABLE_IPV6; }
-
 }  // namespace net
 }  // namespace mozilla
--- a/netwerk/protocol/http/HttpBaseChannel.h
+++ b/netwerk/protocol/http/HttpBaseChannel.h
@@ -298,18 +298,16 @@ class HttpBaseChannel : public nsHashPro
       nsACString &aConnectionInfoHashKey) override;
   NS_IMETHOD GetIntegrityMetadata(nsAString &aIntegrityMetadata) override;
   NS_IMETHOD SetIntegrityMetadata(const nsAString &aIntegrityMetadata) override;
   NS_IMETHOD GetLastRedirectFlags(uint32_t *aValue) override;
   NS_IMETHOD SetLastRedirectFlags(uint32_t aValue) override;
   NS_IMETHOD GetNavigationStartTimeStamp(TimeStamp *aTimeStamp) override;
   NS_IMETHOD SetNavigationStartTimeStamp(TimeStamp aTimeStamp) override;
   NS_IMETHOD CancelForTrackingProtection() override;
-  virtual void SetIPv4Disabled(void) override;
-  virtual void SetIPv6Disabled(void) override;
 
   inline void CleanRedirectCacheChainIfNecessary() {
     mRedirectedCachekeys = nullptr;
   }
   NS_IMETHOD HTTPUpgrade(const nsACString &aProtocolName,
                          nsIHttpUpgradeListener *aListener) override;
 
   // nsISupportsPriority
--- a/netwerk/protocol/http/TrackingDummyChannel.cpp
+++ b/netwerk/protocol/http/TrackingDummyChannel.cpp
@@ -621,14 +621,10 @@ TrackingDummyChannel::SetNavigationStart
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 TrackingDummyChannel::CancelForTrackingProtection() {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-void TrackingDummyChannel::SetIPv4Disabled() {}
-
-void TrackingDummyChannel::SetIPv6Disabled() {}
-
 }  // namespace net
 }  // namespace mozilla
--- a/netwerk/protocol/http/nsHttp.h
+++ b/netwerk/protocol/http/nsHttp.h
@@ -116,22 +116,16 @@ enum class SpdyVersion {
 // without accidentally allowing it for websockets not over http/2
 #define NS_HTTP_ALLOW_SPDY_WITHOUT_KEEPALIVE (1 << 15)
 
 // Only permit CONNECTing to a proxy. A channel with this flag will not send an
 // http request after CONNECT or setup tls. An http upgrade handler MUST be
 // set. An ALPN header is set using the upgrade protocol.
 #define NS_HTTP_CONNECT_ONLY (1 << 16)
 
-// The connection should not use IPv4.
-#define NS_HTTP_DISABLE_IPV4 (1 << 17)
-
-// The connection should not use IPv6
-#define NS_HTTP_DISABLE_IPV6 (1 << 18)
-
 //-----------------------------------------------------------------------------
 // some default values
 //-----------------------------------------------------------------------------
 
 #define NS_HTTP_DEFAULT_PORT 80
 #define NS_HTTPS_DEFAULT_PORT 443
 
 #define NS_HTTP_HEADER_SEPS ", \t"
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -560,18 +560,16 @@ nsresult nsHttpChannel::OnBeforeConnect(
   mConnectionInfo->SetAnonymous((mLoadFlags & LOAD_ANONYMOUS) != 0);
   mConnectionInfo->SetPrivate(mPrivateBrowsing);
   mConnectionInfo->SetNoSpdy(mCaps & NS_HTTP_DISALLOW_SPDY);
   mConnectionInfo->SetBeConservative((mCaps & NS_HTTP_BE_CONSERVATIVE) ||
                                      mBeConservative);
   mConnectionInfo->SetTlsFlags(mTlsFlags);
   mConnectionInfo->SetTrrUsed(mTRR);
   mConnectionInfo->SetTrrDisabled(mCaps & NS_HTTP_DISABLE_TRR);
-  mConnectionInfo->SetIPv4Disabled(mCaps & NS_HTTP_DISABLE_IPV4);
-  mConnectionInfo->SetIPv6Disabled(mCaps & NS_HTTP_DISABLE_IPV6);
 
   // notify "http-on-before-connect" observers
   gHttpHandler->OnBeforeConnect(this);
 
   // Check if request was cancelled during http-on-before-connect.
   if (mCanceled) {
     return mStatus;
   }
@@ -810,18 +808,17 @@ void nsHttpChannel::SpeculativeConnect()
 
   nsCOMPtr<nsIInterfaceRequestor> callbacks;
   NS_NewNotificationCallbacksAggregation(mCallbacks, mLoadGroup,
                                          getter_AddRefs(callbacks));
   if (!callbacks) return;
 
   Unused << gHttpHandler->SpeculativeConnect(
       mConnectionInfo, callbacks,
-      mCaps & (NS_HTTP_DISALLOW_SPDY | NS_HTTP_DISABLE_TRR |
-               NS_HTTP_DISABLE_IPV4 | NS_HTTP_DISABLE_IPV6));
+      mCaps & (NS_HTTP_DISALLOW_SPDY | NS_HTTP_DISABLE_TRR));
 }
 
 void nsHttpChannel::DoNotifyListenerCleanup() {
   // We don't need this info anymore
   CleanRedirectCacheChainIfNecessary();
 }
 
 void nsHttpChannel::ReleaseListeners() {
--- a/netwerk/protocol/http/nsHttpConnectionInfo.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionInfo.cpp
@@ -78,18 +78,16 @@ void nsHttpConnectionInfo::Init(const ns
   mProxyInfo = proxyInfo;
   mEndToEndSSL = e2eSSL;
   mUsingConnect = false;
   mNPNToken = npnToken;
   mOriginAttributes = originAttributes;
   mTlsFlags = 0x0;
   mTrrUsed = false;
   mTrrDisabled = false;
-  mIPv4Disabled = false;
-  mIPv6Disabled = false;
 
   mUsingHttpsProxy = (proxyInfo && proxyInfo->IsHTTPS());
   mUsingHttpProxy = mUsingHttpsProxy || (proxyInfo && proxyInfo->IsHTTP());
 
   if (mUsingHttpProxy) {
     mUsingConnect = mEndToEndSSL;  // SSL always uses CONNECT
     uint32_t resolveFlags = 0;
     if (NS_SUCCEEDED(mProxyInfo->GetResolveFlags(&resolveFlags)) &&
@@ -205,24 +203,16 @@ void nsHttpConnectionInfo::BuildHashKey(
 
   if (GetTrrDisabled()) {
     // When connecting with TRR disabled, we enforce a separate connection
     // hashkey so that we also can trigger a fresh DNS resolver that then
     // doesn't use TRR as the previous connection might have.
     mHashKey.AppendLiteral("[NOTRR]");
   }
 
-  if (GetIPv4Disabled()) {
-    mHashKey.AppendLiteral("[!v4]");
-  }
-
-  if (GetIPv6Disabled()) {
-    mHashKey.AppendLiteral("[!v6]");
-  }
-
   nsAutoCString originAttributes;
   mOriginAttributes.CreateSuffix(originAttributes);
   mHashKey.Append(originAttributes);
 }
 
 void nsHttpConnectionInfo::SetOriginServer(const nsACString &host,
                                            int32_t port) {
   mOrigin = host;
@@ -247,18 +237,16 @@ nsHttpConnectionInfo *nsHttpConnectionIn
   clone->SetAnonymous(GetAnonymous());
   clone->SetPrivate(GetPrivate());
   clone->SetInsecureScheme(GetInsecureScheme());
   clone->SetNoSpdy(GetNoSpdy());
   clone->SetBeConservative(GetBeConservative());
   clone->SetTlsFlags(GetTlsFlags());
   clone->SetTrrUsed(GetTrrUsed());
   clone->SetTrrDisabled(GetTrrDisabled());
-  clone->SetIPv4Disabled(GetIPv4Disabled());
-  clone->SetIPv6Disabled(GetIPv6Disabled());
   MOZ_ASSERT(clone->Equals(this));
 
   return clone;
 }
 
 void nsHttpConnectionInfo::CloneAsDirectRoute(nsHttpConnectionInfo **outCI) {
   if (mRoutedHost.IsEmpty()) {
     *outCI = Clone();
@@ -272,19 +260,16 @@ void nsHttpConnectionInfo::CloneAsDirect
   clone->SetAnonymous(GetAnonymous());
   clone->SetPrivate(GetPrivate());
   clone->SetInsecureScheme(GetInsecureScheme());
   clone->SetNoSpdy(GetNoSpdy());
   clone->SetBeConservative(GetBeConservative());
   clone->SetTlsFlags(GetTlsFlags());
   clone->SetTrrUsed(GetTrrUsed());
   clone->SetTrrDisabled(GetTrrDisabled());
-  clone->SetIPv4Disabled(GetIPv4Disabled());
-  clone->SetIPv6Disabled(GetIPv6Disabled());
-
   clone.forget(outCI);
 }
 
 nsresult nsHttpConnectionInfo::CreateWildCard(nsHttpConnectionInfo **outParam) {
   // T???mozilla.org:443 (https:proxy.ducksong.com:3128) [specifc form]
   // TS??*:0 (https:proxy.ducksong.com:3128)   [wildcard form]
 
   if (!mUsingHttpsProxy) {
@@ -305,30 +290,16 @@ nsresult nsHttpConnectionInfo::CreateWil
 
 void nsHttpConnectionInfo::SetTrrDisabled(bool aNoTrr) {
   if (mTrrDisabled != aNoTrr) {
     mTrrDisabled = aNoTrr;
     BuildHashKey();
   }
 }
 
-void nsHttpConnectionInfo::SetIPv4Disabled(bool aNoIPv4) {
-  if (mIPv4Disabled != aNoIPv4) {
-    mIPv4Disabled = aNoIPv4;
-    BuildHashKey();
-  }
-}
-
-void nsHttpConnectionInfo::SetIPv6Disabled(bool aNoIPv6) {
-  if (mIPv6Disabled != aNoIPv6) {
-    mIPv6Disabled = aNoIPv6;
-    BuildHashKey();
-  }
-}
-
 void nsHttpConnectionInfo::SetTlsFlags(uint32_t aTlsFlags) {
   mTlsFlags = aTlsFlags;
 
   mHashKey.Replace(18, 8, nsPrintfCString("%08x", mTlsFlags));
 }
 
 bool nsHttpConnectionInfo::UsingProxy() {
   if (!mProxyInfo) return false;
--- a/netwerk/protocol/http/nsHttpConnectionInfo.h
+++ b/netwerk/protocol/http/nsHttpConnectionInfo.h
@@ -128,22 +128,16 @@ class nsHttpConnectionInfo final : publi
   void SetTrrUsed(bool aUsed) { mTrrUsed = aUsed; }
   bool GetTrrUsed() const { return mTrrUsed; }
 
   // SetTrrDisabled means don't use TRR to resolve host names for this
   // connection
   void SetTrrDisabled(bool aNoTrr);
   bool GetTrrDisabled() const { return mTrrDisabled; }
 
-  void SetIPv4Disabled(bool aNoIPv4);
-  bool GetIPv4Disabled() const { return mIPv4Disabled; }
-
-  void SetIPv6Disabled(bool aNoIPv6);
-  bool GetIPv6Disabled() const { return mIPv6Disabled; }
-
   const nsCString &GetNPNToken() { return mNPNToken; }
   const nsCString &GetUsername() { return mUsername; }
 
   const OriginAttributes &GetOriginAttributes() { return mOriginAttributes; }
 
   // Returns true for any kind of proxy (http, socks, https, etc..)
   bool UsingProxy();
 
@@ -191,18 +185,16 @@ class nsHttpConnectionInfo final : publi
   bool mEndToEndSSL;
   bool mUsingConnect;  // if will use CONNECT with http proxy
   nsCString mNPNToken;
   OriginAttributes mOriginAttributes;
 
   uint32_t mTlsFlags;
   uint16_t mTrrUsed : 1;
   uint16_t mTrrDisabled : 1;
-  uint16_t mIPv4Disabled : 1;
-  uint16_t mIPv6Disabled : 1;
 
   bool mLessThanTls13;  // This will be set to true if we negotiate less than
                         // tls1.3. If the tls version is till not know or it
                         // is 1.3 or greater the value will be false.
 
   // for RefPtr
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsHttpConnectionInfo, override)
 };
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -3943,21 +3943,17 @@ nsresult nsHttpConnectionMgr::nsHalfOpen
     tmpFlags |= nsISocketTransport::DONT_TRY_ESNI;
   }
 
   if ((mCaps & NS_HTTP_BE_CONSERVATIVE) || ci->GetBeConservative()) {
     LOG(("Setting Socket to BE_CONSERVATIVE"));
     tmpFlags |= nsISocketTransport::BE_CONSERVATIVE;
   }
 
-  if (mCaps & NS_HTTP_DISABLE_IPV4) {
-    tmpFlags |= nsISocketTransport::DISABLE_IPV4;
-  } else if (mCaps & NS_HTTP_DISABLE_IPV6) {
-    tmpFlags |= nsISocketTransport::DISABLE_IPV6;
-  } else if (mEnt->PreferenceKnown()) {
+  if (mEnt->PreferenceKnown()) {
     if (mEnt->mPreferIPv6) {
       tmpFlags |= nsISocketTransport::DISABLE_IPV4;
     } else if (mEnt->mPreferIPv4) {
       tmpFlags |= nsISocketTransport::DISABLE_IPV6;
     }
 
     // In case the host is no longer accessible via the preferred IP family,
     // try the opposite one and potentially restate the preference.
@@ -3987,19 +3983,16 @@ nsresult nsHttpConnectionMgr::nsHalfOpen
   if ((mFastOpenStatus != TFO_HTTP) && !isBackup) {
     if (mEnt->mUseFastOpen) {
       socketTransport->SetFastOpenCallback(this);
     } else {
       mFastOpenStatus = TFO_DISABLED;
     }
   }
 
-  MOZ_ASSERT(!(tmpFlags & nsISocketTransport::DISABLE_IPV4) ||
-                 !(tmpFlags & nsISocketTransport::DISABLE_IPV6),
-             "Both types should not be disabled at the same time.");
   socketTransport->SetConnectionFlags(tmpFlags);
   socketTransport->SetTlsFlags(ci->GetTlsFlags());
 
   const OriginAttributes &originAttributes =
       mEnt->mConnInfo->GetOriginAttributes();
   if (originAttributes != OriginAttributes()) {
     socketTransport->SetOriginAttributes(originAttributes);
   }
--- a/netwerk/protocol/http/nsIHttpChannelInternal.idl
+++ b/netwerk/protocol/http/nsIHttpChannelInternal.idl
@@ -353,20 +353,9 @@ interface nsIHttpChannelInternal : nsISu
     /**
      * Cancel a channel because we have determined that it needs to be blocked
      * for tracking protection.  This is an internal API that is meant to be
      * called by the channel classifier.  Please DO NOT use this API if you don't
      * know whether you should be using it.
      */
     [noscript] void cancelForTrackingProtection();
 
-    /**
-     * The channel will be loaded over IPv6, disabling IPv4.
-     */
-    [noscript, notxpcom, nostdcall]
-    void setIPv4Disabled();
-
-    /**
-     * The channel will be loaded over IPv4, disabling IPv6.
-     */
-    [noscript, notxpcom, nostdcall]
-    void setIPv6Disabled();
 };
--- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
+++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
@@ -1047,20 +1047,8 @@ nsViewSourceChannel::LogBlockedCORSReque
 
 const nsTArray<mozilla::Tuple<nsCString, nsCString>>
     &nsViewSourceChannel::PreferredAlternativeDataTypes() {
   if (mCacheInfoChannel) {
     return mCacheInfoChannel->PreferredAlternativeDataTypes();
   }
   return mEmptyArray;
 }
-
-void nsViewSourceChannel::SetIPv4Disabled() {
-  if (mHttpChannelInternal) {
-    mHttpChannelInternal->SetIPv4Disabled();
-  }
-}
-
-void nsViewSourceChannel::SetIPv6Disabled() {
-  if (mHttpChannelInternal) {
-    mHttpChannelInternal->SetIPv6Disabled();
-  }
-}
--- a/netwerk/test/httpserver/httpd.js
+++ b/netwerk/test/httpserver/httpd.js
@@ -190,19 +190,16 @@ var gThreadManager = null;
 /**
  * JavaScript constructors for commonly-used classes; precreating these is a
  * speedup over doing the same from base principles.  See the docs at
  * http://developer.mozilla.org/en/docs/Components.Constructor for details.
  */
 const ServerSocket = CC("@mozilla.org/network/server-socket;1",
                         "nsIServerSocket",
                         "init");
-const ServerSocketIPv6 = CC("@mozilla.org/network/server-socket;1",
-                            "nsIServerSocket",
-                            "initIPv6");
 const ScriptableInputStream = CC("@mozilla.org/scriptableinputstream;1",
                                  "nsIScriptableInputStream",
                                  "init");
 const Pipe = CC("@mozilla.org/pipe;1",
                 "nsIPipe",
                 "init");
 const FileInputStream = CC("@mozilla.org/network/file-input-stream;1",
                            "nsIFileInputStream",
@@ -483,38 +480,30 @@ nsHttpServer.prototype =
     // connections, plus a safety margin in case some other process is
     // talking to the server as well.
     var maxConnections = 5 + Math.max(
       Services.prefs.getIntPref("network.http.max-persistent-connections-per-server"),
       Services.prefs.getIntPref("network.http.max-persistent-connections-per-proxy"));
 
     try {
       var loopback = true;
-      if (this._host != "127.0.0.1" && this._host != "localhost" &&
-          this._host != "[::1]") {
+      if (this._host != "127.0.0.1" && this._host != "localhost") {
         loopback = false;
       }
 
       // When automatically selecting a port, sometimes the chosen port is
       // "blocked" from clients. We don't want to use these ports because
       // tests will intermittently fail. So, we simply keep trying to to
       // get a server socket until a valid port is obtained. We limit
       // ourselves to finite attempts just so we don't loop forever.
       var socket;
       for (var i = 100; i; i--) {
-        var temp = null;
-        if (this._host.includes(":")) {
-          temp = new ServerSocketIPv6(this._port,
-                                      loopback, // true = localhost, false = everybody
-                                      maxConnections);
-        } else {
-          temp = new ServerSocket(this._port,
-                                  loopback, // true = localhost, false = everybody
-                                  maxConnections);
-        }
+        var temp = new ServerSocket(this._port,
+                                    loopback, // true = localhost, false = everybody
+                                    maxConnections);
 
         var allowed = Services.io.allowPort(temp.port, "http");
         if (!allowed) {
           dumpn(">>>Warning: obtained ServerSocket listens on a blocked " +
                 "port: " + temp.port);
         }
 
         if (!allowed && this._port == -1) {
@@ -526,22 +515,22 @@ nsHttpServer.prototype =
         socket = temp;
         break;
       }
 
       if (!socket) {
         throw new Error("No socket server available. Are there no available ports?");
       }
 
+      dumpn(">>> listening on port " + socket.port + ", " + maxConnections +
+            " pending connections");
       socket.asyncListen(this);
       this._port = socket.port;
       this._identity._initialize(socket.port, host, true);
       this._socket = socket;
-      dumpn(">>> listening on port " + socket.port + ", " + maxConnections +
-            " pending connections");
     } catch (e) {
       dump("\n!!! could not start server on port " + port + ": " + e + "\n\n");
       throw Components.Exception("", Cr.NS_ERROR_NOT_AVAILABLE);
     }
   },
 
   //
   // see nsIHttpServer.stop
@@ -982,23 +971,18 @@ ServerIdentity.prototype =
     this._host = host;
     if (this._primaryPort !== -1)
       this.add("http", host, port);
     else
       this.setPrimary("http", "localhost", port);
     this._defaultPort = port;
 
     // Only add this if we're being called at server startup
-    if (addSecondaryDefault && host != "127.0.0.1") {
-      if (host.includes(":")) {
-        this.add("http", "[::1]", port);
-      } else {
-        this.add("http", "127.0.0.1", port);
-      }
-    }
+    if (addSecondaryDefault && host != "127.0.0.1")
+      this.add("http", "127.0.0.1", port);
   },
 
   /**
    * Called at server shutdown time, unsets the primary location only if it was
    * the default-assigned location and removes the default location from the
    * set of locations used.
    */
   _teardown() {
@@ -1033,17 +1017,17 @@ ServerIdentity.prototype =
    *   if any argument doesn't match the corresponding production
    */
   _validate(scheme, host, port) {
     if (scheme !== "http" && scheme !== "https") {
       dumpn("*** server only supports http/https schemes: '" + scheme + "'");
       dumpStack();
       throw Components.Exception("", Cr.NS_ERROR_ILLEGAL_VALUE);
     }
-    if (!HOST_REGEX.test(host) && host != "[::1]") {
+    if (!HOST_REGEX.test(host)) {
       dumpn("*** unexpected host: '" + host + "'");
       throw Components.Exception("", Cr.NS_ERROR_ILLEGAL_VALUE);
     }
     if (port < 0 || port > 65535) {
       dumpn("*** unexpected port: '" + port + "'");
       throw Components.Exception("", Cr.NS_ERROR_ILLEGAL_VALUE);
     }
   },
@@ -1446,32 +1430,29 @@ RequestReader.prototype =
 
       // If the Request-URI wasn't absolute, then we need to determine our host.
       // We have to determine what scheme was used to access us based on the
       // server identity data at this point, because the request just doesn't
       // contain enough data on its own to do this, sadly.
       if (!metadata._host) {
         var host, port;
         var hostPort = headers.getHeader("Host");
-        var colon = hostPort.lastIndexOf(":");
-        if (hostPort.lastIndexOf("]") > colon) {
-          colon = -1;
-        }
+        var colon = hostPort.indexOf(":");
         if (colon < 0) {
           host = hostPort;
           port = "";
         } else {
           host = hostPort.substring(0, colon);
           port = hostPort.substring(colon + 1);
         }
 
         // NB: We allow an empty port here because, oddly, a colon may be
         //     present even without a port number, e.g. "example.com:"; in this
         //     case the default port applies.
-        if ((!HOST_REGEX.test(host) && host != "[::1]") || !/^\d*$/.test(port)) {
+        if (!HOST_REGEX.test(host) || !/^\d*$/.test(port)) {
           dumpn("*** malformed hostname (" + hostPort + ") in Host " +
                 "header, 400 time");
           throw HTTP_400;
         }
 
         // If we're not given a port, we're stuck, because we don't know what
         // scheme to use to look up the correct port here, in general.  Since
         // the HTTPS case requires a tunnel/proxy and thus requires that the
--- a/netwerk/test/unit/test_network_connectivity_service.js
+++ b/netwerk/test/unit/test_network_connectivity_service.js
@@ -6,40 +6,18 @@
 
 ChromeUtils.import("resource://testing-common/httpd.js");
 ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 registerCleanupFunction(() => {
   Services.prefs.clearUserPref("network.connectivity-service.DNSv4.domain");
   Services.prefs.clearUserPref("network.connectivity-service.DNSv6.domain");
-  Services.prefs.clearUserPref("network.captive-portal-service.testMode");
-  Services.prefs.clearUserPref("network.connectivity-service.IPv4.url");
-  Services.prefs.clearUserPref("network.connectivity-service.IPv6.url");
 });
 
-let httpserver = null;
-let httpserverv6 = null;
-XPCOMUtils.defineLazyGetter(this, "URL", function() {
-  return "http://localhost:" + httpserver.identity.primaryPort + "/content";
-});
-
-XPCOMUtils.defineLazyGetter(this, "URLv6", function() {
-  return "http://[::1]:" + httpserverv6.identity.primaryPort + "/content";
-});
-
-function contentHandler(metadata, response)
-{
-  response.setHeader("Content-Type", "text/plain");
-  response.setHeader("Cache-Control", "no-cache");
-
-  const responseBody = "anybody";
-  response.bodyOutputStream.write(responseBody, responseBody.length);
-}
-
 const DEFAULT_WAIT_TIME = 200; // ms
 
 const kDNSv6Domain = (mozinfo.os == "linux")
                        ? "ip6-localhost"
                        : "localhost";
 
 add_task(async function testDNS() {
   let ncs = Cc["@mozilla.org/network/network-connectivity-service;1"]
@@ -72,39 +50,12 @@ add_task(async function testDNS() {
   equal(ncs.DNSv4, Ci.nsINetworkConnectivityService.UNKNOWN, "Check DNSv4 support (expect UNKNOWN)");
   equal(ncs.DNSv6, Ci.nsINetworkConnectivityService.UNKNOWN, "Check DNSv6 support (expect UNKNOWN)");
 
   await new Promise(resolve => do_timeout(DEFAULT_WAIT_TIME, resolve));
 
   equal(ncs.DNSv4, Ci.nsINetworkConnectivityService.OK, "Check DNSv4 support (expect OK)");
   equal(ncs.DNSv6, Ci.nsINetworkConnectivityService.OK, "Check DNSv6 support (expect OK)");
 
-  httpserver = new HttpServer();
-  httpserver.registerPathHandler("/content", contentHandler);
-  httpserver.start(-1);
-
-  httpserverv6 = new HttpServer();
-  httpserverv6.registerPathHandler("/contentt", contentHandler);
-  httpserverv6._start(-1, "[::1]");
-  // httpserverv6._start(-1, "ip6-localhost");
-
-  // Before setting the pref, this status is unknown in automation
-  equal(ncs.IPv4, Ci.nsINetworkConnectivityService.UNKNOWN, "Check IPv4 support (expect UNKNOWN)");
-  equal(ncs.IPv6, Ci.nsINetworkConnectivityService.UNKNOWN, "Check IPv6 support (expect UNKNOWN)");
-
-  Services.prefs.setBoolPref("network.captive-portal-service.testMode", true);
-  Services.prefs.setCharPref("network.connectivity-service.IPv4.url", URL);
-  Services.prefs.setCharPref("network.connectivity-service.IPv6.url", URLv6);
-  ncs.recheckIPConnectivity();
-  await new Promise(resolve => do_timeout(DEFAULT_WAIT_TIME, resolve));
-
+  // It's difficult to check when there's no connectivity in automation,
   equal(ncs.IPv4, Ci.nsINetworkConnectivityService.OK, "Check IPv4 support (expect OK)");
   equal(ncs.IPv6, Ci.nsINetworkConnectivityService.OK, "Check IPv6 support (expect OK)");
-
-  // check that the CPS status is NOT_AVAILABLE when the endpoint is down.
-  await new Promise(resolve => httpserver.stop(resolve));
-  await new Promise(resolve => httpserverv6.stop(resolve));
-  Services.obs.notifyObservers(null, "network:captive-portal-connectivity", null);
-  await new Promise(resolve => do_timeout(DEFAULT_WAIT_TIME, resolve));
-
-  equal(ncs.IPv4, Ci.nsINetworkConnectivityService.NOT_AVAILABLE, "Check IPv4 support (expect NOT_AVAILABLE)");
-  equal(ncs.IPv6, Ci.nsINetworkConnectivityService.NOT_AVAILABLE, "Check IPv6 support (expect NOT_AVAILABLE)");
 });