Bug 1502774 - Part 1: Remove XPCOM component registrations for HTTP authenticator classes r=valentin
☠☠ backed out by af20bba72e84 ☠ ☠
authorEhsan Akhgari <ehsan@mozilla.com>
Mon, 29 Oct 2018 14:40:29 +0000
changeset 499757 b403c3c786eebc231f1069612a1c820440b798fe
parent 499756 a855f0c51b4103db426f06e8a16f1e609dee998b
child 499758 07648e9d8400ee9b0c5ac84c76d8c2f7de94db83
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvalentin
bugs1502774
milestone65.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 1502774 - Part 1: Remove XPCOM component registrations for HTTP authenticator classes r=valentin Differential Revision: https://phabricator.services.mozilla.com/D10025
extensions/auth/nsAuthFactory.cpp
extensions/auth/nsHttpNegotiateAuth.cpp
extensions/auth/nsHttpNegotiateAuth.h
netwerk/build/nsNetModule.cpp
netwerk/protocol/http/moz.build
netwerk/protocol/http/nsHttpBasicAuth.cpp
netwerk/protocol/http/nsHttpBasicAuth.h
netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
netwerk/protocol/http/nsHttpDigestAuth.cpp
netwerk/protocol/http/nsHttpDigestAuth.h
netwerk/protocol/http/nsHttpNTLMAuth.cpp
netwerk/protocol/http/nsHttpNTLMAuth.h
netwerk/protocol/http/nsHttpTransaction.cpp
netwerk/protocol/http/nsIHttpAuthenticator.idl
--- a/extensions/auth/nsAuthFactory.cpp
+++ b/extensions/auth/nsAuthFactory.cpp
@@ -2,28 +2,16 @@
  * 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 "mozilla/ModuleUtils.h"
 #include "nsAuth.h"
 
 //-----------------------------------------------------------------------------
 
-#define NS_HTTPNEGOTIATEAUTH_CID                   \
-{ /* 75c80fd0-accb-432c-af59-ec60668c3990 */       \
-  0x75c80fd0,                                      \
-  0xaccb,                                          \
-  0x432c,                                          \
-  {0xaf, 0x59, 0xec, 0x60, 0x66, 0x8c, 0x39, 0x90} \
-}
-
-#include "nsHttpNegotiateAuth.h"
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpNegotiateAuth)
-//-----------------------------------------------------------------------------
-
 #define NS_NEGOTIATEAUTH_CID                       \
 { /* 96ec4163-efc8-407a-8735-007fb26be4e8 */       \
   0x96ec4163,                                      \
   0xefc8,                                          \
   0x407a,                                          \
   {0x87, 0x35, 0x00, 0x7f, 0xb2, 0x6b, 0xe4, 0xe8} \
 }
 #define NS_GSSAUTH_CID                             \
@@ -179,46 +167,43 @@ NS_DEFINE_NAMED_CID(NS_GSSAUTH_CID);
 NS_DEFINE_NAMED_CID(NS_NEGOTIATEAUTH_CID);
 #if defined( USE_SSPI )
 NS_DEFINE_NAMED_CID(NS_NEGOTIATEAUTHSSPI_CID);
 NS_DEFINE_NAMED_CID(NS_KERBAUTHSSPI_CID);
 NS_DEFINE_NAMED_CID(NS_SYSNTLMAUTH_CID);
 #else
 NS_DEFINE_NAMED_CID(NS_SAMBANTLMAUTH_CID);
 #endif
-NS_DEFINE_NAMED_CID(NS_HTTPNEGOTIATEAUTH_CID);
 NS_DEFINE_NAMED_CID(NS_AUTHSASL_CID);
 
 
 static const mozilla::Module::CIDEntry kAuthCIDs[] = {
   { &kNS_GSSAUTH_CID, false, nullptr, nsKerbGSSAPIAuthConstructor },
   { &kNS_NEGOTIATEAUTH_CID, false, nullptr, nsGSSAPIAuthConstructor },
 #if defined( USE_SSPI )
   { &kNS_NEGOTIATEAUTHSSPI_CID, false, nullptr, nsAuthSSPIConstructor },
   { &kNS_KERBAUTHSSPI_CID, false, nullptr, nsKerbSSPIAuthConstructor },
   { &kNS_SYSNTLMAUTH_CID, false, nullptr, nsSysNTLMAuthConstructor },
 #else
   { &kNS_SAMBANTLMAUTH_CID, false, nullptr, nsSambaNTLMAuthConstructor },
 #endif
-  { &kNS_HTTPNEGOTIATEAUTH_CID, false, nullptr, nsHttpNegotiateAuthConstructor },
   { &kNS_AUTHSASL_CID, false, nullptr, nsAuthSASLConstructor },
   { nullptr }
 };
 
 static const mozilla::Module::ContractIDEntry kAuthContracts[] = {
   { NS_AUTH_MODULE_CONTRACTID_PREFIX "kerb-gss", &kNS_GSSAUTH_CID },
   { NS_AUTH_MODULE_CONTRACTID_PREFIX "negotiate-gss", &kNS_NEGOTIATEAUTH_CID },
 #if defined( USE_SSPI )
   { NS_AUTH_MODULE_CONTRACTID_PREFIX "negotiate-sspi", &kNS_NEGOTIATEAUTHSSPI_CID },
   { NS_AUTH_MODULE_CONTRACTID_PREFIX "kerb-sspi", &kNS_KERBAUTHSSPI_CID },
   { NS_AUTH_MODULE_CONTRACTID_PREFIX "sys-ntlm", &kNS_SYSNTLMAUTH_CID },
 #elif !defined(XP_MACOSX)
   { NS_AUTH_MODULE_CONTRACTID_PREFIX "sys-ntlm", &kNS_SAMBANTLMAUTH_CID },
 #endif
-  { NS_HTTP_AUTHENTICATOR_CONTRACTID_PREFIX "negotiate", &kNS_HTTPNEGOTIATEAUTH_CID },
   { NS_AUTH_MODULE_CONTRACTID_PREFIX "sasl-gssapi", &kNS_AUTHSASL_CID },
   { nullptr }
 };
 
 //-----------------------------------------------------------------------------
 mozilla::LazyLogModule gNegotiateLog("negotiateauth");
 
 // setup nspr logging ...
--- a/extensions/auth/nsHttpNegotiateAuth.cpp
+++ b/extensions/auth/nsHttpNegotiateAuth.cpp
@@ -44,29 +44,32 @@
 #include "nsIChannel.h"
 #include "nsNetUtil.h"
 #include "nsThreadUtils.h"
 #include "nsIHttpAuthenticatorCallback.h"
 #include "mozilla/Mutex.h"
 #include "nsICancelable.h"
 #include "nsUnicharUtils.h"
 #include "mozilla/net/HttpAuthUtils.h"
+#include "mozilla/ClearOnShutdown.h"
 
 using mozilla::Base64Decode;
 
 //-----------------------------------------------------------------------------
 
 static const char kNegotiate[] = "Negotiate";
 static const char kNegotiateAuthTrustedURIs[] = "network.negotiate-auth.trusted-uris";
 static const char kNegotiateAuthDelegationURIs[] = "network.negotiate-auth.delegation-uris";
 static const char kNegotiateAuthAllowProxies[] = "network.negotiate-auth.allow-proxies";
 static const char kNegotiateAuthAllowNonFqdn[] = "network.negotiate-auth.allow-non-fqdn";
 static const char kNegotiateAuthSSPI[] = "network.auth.use-sspi";
 static const char kSSOinPBmode[] = "network.auth.private-browsing-sso";
 
+mozilla::StaticRefPtr<nsHttpNegotiateAuth> nsHttpNegotiateAuth::gSingleton;
+
 #define kNegotiateLen  (sizeof(kNegotiate)-1)
 #define DEFAULT_THREAD_TIMEOUT_MS 30000
 
 //-----------------------------------------------------------------------------
 
 // Return false when the channel comes from a Private browsing window.
 static bool
 TestNotInPBMode(nsIHttpAuthenticableChannel *authChannel, bool proxyAuth)
@@ -100,16 +103,31 @@ TestNotInPBMode(nsIHttpAuthenticableChan
             dontRememberHistory) {
             return true;
         }
     }
 
     return false;
 }
 
+already_AddRefed<nsIHttpAuthenticator>
+nsHttpNegotiateAuth::GetOrCreate()
+{
+    nsCOMPtr<nsIHttpAuthenticator> authenticator;
+    if (gSingleton) {
+      authenticator = gSingleton;
+    } else {
+      gSingleton = new nsHttpNegotiateAuth();
+      mozilla::ClearOnShutdown(&gSingleton);
+      authenticator = gSingleton;
+    }
+
+    return authenticator.forget();
+}
+
 NS_IMETHODIMP
 nsHttpNegotiateAuth::GetAuthFlags(uint32_t *flags)
 {
     //
     // Negotiate Auth creds should not be reused across multiple requests.
     // Only perform the negotiation when it is explicitly requested by the
     // server.  Thus, do *NOT* use the "REUSABLE_CREDENTIALS" flag here.
     //
@@ -377,22 +395,18 @@ class GetNextTokenRunnable final : publi
                                                    mContinuationState.forget());
         }
 
         NS_IMETHODIMP ObtainCredentialsAndFlags(char **aCreds, uint32_t *aFlags)
         {
             nsresult rv;
 
             // Use negotiate service to call GenerateCredentials outside of main thread
-            nsAutoCString contractId;
-            contractId.AssignLiteral(NS_HTTP_AUTHENTICATOR_CONTRACTID_PREFIX);
-            contractId.AppendLiteral("negotiate");
             nsCOMPtr<nsIHttpAuthenticator> authenticator =
-              do_GetService(contractId.get(), &rv);
-            NS_ENSURE_SUCCESS(rv, rv);
+              new nsHttpNegotiateAuth();
 
             nsISupports *sessionState = mSessionState;
             nsISupports *continuationState = mContinuationState;
             // The continuationState is for the sake of completeness propagated
             // to the caller (despite it is not changed in any GenerateCredentials
             // implementation).
             //
             // The only implementation that use sessionState is the
--- a/extensions/auth/nsHttpNegotiateAuth.h
+++ b/extensions/auth/nsHttpNegotiateAuth.h
@@ -5,31 +5,37 @@
 
 #ifndef nsHttpNegotiateAuth_h__
 #define nsHttpNegotiateAuth_h__
 
 #include "nsIHttpAuthenticator.h"
 #include "nsIURI.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/LazyIdleThread.h"
+#include "mozilla/StaticPtr.h"
 
 // The nsHttpNegotiateAuth class provides responses for the GSS-API Negotiate method
 // as specified by Microsoft in draft-brezak-spnego-http-04.txt
 
 class nsHttpNegotiateAuth final : public nsIHttpAuthenticator
 {
 public:
     NS_DECL_THREADSAFE_ISUPPORTS
     NS_DECL_NSIHTTPAUTHENTICATOR
 
+    static already_AddRefed<nsIHttpAuthenticator> GetOrCreate();
+
 private:
     ~nsHttpNegotiateAuth() {}
 
     // returns the value of the given boolean pref
     bool TestBoolPref(const char *pref);
 
     // tests if the host part of an uri is fully qualified
     bool TestNonFqdn(nsIURI *uri);
 
     // Thread for GenerateCredentialsAsync
     RefPtr<mozilla::LazyIdleThread> mNegotiateThread;
+
+    // Singleton pointer
+    static mozilla::StaticRefPtr<nsHttpNegotiateAuth> gSingleton;
 };
 #endif /* nsHttpNegotiateAuth_h__ */
--- a/netwerk/build/nsNetModule.cpp
+++ b/netwerk/build/nsNetModule.cpp
@@ -228,32 +228,26 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsFi
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsFtpProtocolHandler, Init)
 
 // http/https
 #include "nsHttpHandler.h"
 #include "Http2Compression.h"
 #undef LOG
 #undef LOG_ENABLED
 #include "nsHttpAuthManager.h"
-#include "nsHttpBasicAuth.h"
-#include "nsHttpDigestAuth.h"
-#include "nsHttpNTLMAuth.h"
 #include "nsHttpActivityDistributor.h"
 #include "ThrottleQueue.h"
 #undef LOG
 #undef LOG_ENABLED
 namespace mozilla {
 namespace net {
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpNTLMAuth)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsHttpHandler, nsHttpHandler::GetInstance)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHttpsHandler, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHttpAuthManager, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpActivityDistributor)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpBasicAuth)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpDigestAuth)
 NS_GENERIC_FACTORY_CONSTRUCTOR(ThrottleQueue)
 } // namespace net
 } // namespace mozilla
 
 #include "mozilla/net/Dashboard.h"
 namespace mozilla {
 namespace net {
   NS_GENERIC_FACTORY_CONSTRUCTOR(Dashboard)
@@ -679,19 +673,16 @@ NS_DEFINE_NAMED_CID(NS_MULTIMIXEDCONVERT
 NS_DEFINE_NAMED_CID(NS_UNKNOWNDECODER_CID);
 NS_DEFINE_NAMED_CID(NS_BINARYDETECTOR_CID);
 NS_DEFINE_NAMED_CID(NS_HTTPCOMPRESSCONVERTER_CID);
 NS_DEFINE_NAMED_CID(MOZITXTTOHTMLCONV_CID);
 NS_DEFINE_NAMED_CID(NS_MIMEHEADERPARAM_CID);
 NS_DEFINE_NAMED_CID(NS_FILEPROTOCOLHANDLER_CID);
 NS_DEFINE_NAMED_CID(NS_HTTPPROTOCOLHANDLER_CID);
 NS_DEFINE_NAMED_CID(NS_HTTPSPROTOCOLHANDLER_CID);
-NS_DEFINE_NAMED_CID(NS_HTTPBASICAUTH_CID);
-NS_DEFINE_NAMED_CID(NS_HTTPDIGESTAUTH_CID);
-NS_DEFINE_NAMED_CID(NS_HTTPNTLMAUTH_CID);
 NS_DEFINE_NAMED_CID(NS_HTTPAUTHMANAGER_CID);
 NS_DEFINE_NAMED_CID(NS_HTTPACTIVITYDISTRIBUTOR_CID);
 NS_DEFINE_NAMED_CID(NS_THROTTLEQUEUE_CID);
 NS_DEFINE_NAMED_CID(NS_FTPPROTOCOLHANDLER_CID);
 NS_DEFINE_NAMED_CID(NS_RESPROTOCOLHANDLER_CID);
 NS_DEFINE_NAMED_CID(NS_EXTENSIONPROTOCOLHANDLER_CID);
 NS_DEFINE_NAMED_CID(NS_SUBSTITUTINGURL_CID);
 NS_DEFINE_NAMED_CID(NS_SUBSTITUTINGURLMUTATOR_CID);
@@ -786,19 +777,16 @@ static const mozilla::Module::CIDEntry k
     { &kNS_UNKNOWNDECODER_CID, false, nullptr, CreateNewUnknownDecoderFactory },
     { &kNS_BINARYDETECTOR_CID, false, nullptr, CreateNewBinaryDetectorFactory },
     { &kNS_HTTPCOMPRESSCONVERTER_CID, false, nullptr, CreateNewHTTPCompressConvFactory },
     { &kMOZITXTTOHTMLCONV_CID, false, nullptr, CreateNewTXTToHTMLConvFactory },
     { &kNS_MIMEHEADERPARAM_CID, false, nullptr, nsMIMEHeaderParamImplConstructor },
     { &kNS_FILEPROTOCOLHANDLER_CID, false, nullptr, nsFileProtocolHandlerConstructor },
     { &kNS_HTTPPROTOCOLHANDLER_CID, false, nullptr, mozilla::net::nsHttpHandlerConstructor },
     { &kNS_HTTPSPROTOCOLHANDLER_CID, false, nullptr, mozilla::net::nsHttpsHandlerConstructor },
-    { &kNS_HTTPBASICAUTH_CID, false, nullptr, mozilla::net::nsHttpBasicAuthConstructor },
-    { &kNS_HTTPDIGESTAUTH_CID, false, nullptr, mozilla::net::nsHttpDigestAuthConstructor },
-    { &kNS_HTTPNTLMAUTH_CID, false, nullptr, mozilla::net::nsHttpNTLMAuthConstructor },
     { &kNS_HTTPAUTHMANAGER_CID, false, nullptr, mozilla::net::nsHttpAuthManagerConstructor },
     { &kNS_HTTPACTIVITYDISTRIBUTOR_CID, false, nullptr, mozilla::net::nsHttpActivityDistributorConstructor },
     { &kNS_THROTTLEQUEUE_CID, false, nullptr, mozilla::net::ThrottleQueueConstructor },
     { &kNS_FTPPROTOCOLHANDLER_CID, false, nullptr, nsFtpProtocolHandlerConstructor },
     { &kNS_RESPROTOCOLHANDLER_CID, false, nullptr, nsResProtocolHandlerConstructor },
     { &kNS_EXTENSIONPROTOCOLHANDLER_CID, false, nullptr, mozilla::ExtensionProtocolHandlerConstructor },
     { &kNS_SUBSTITUTINGURL_CID, false, nullptr, mozilla::SubstitutingURLMutatorConstructor }, // do_CreateInstance returns mutator
     { &kNS_SUBSTITUTINGURLMUTATOR_CID, false, nullptr, mozilla::SubstitutingURLMutatorConstructor },
@@ -900,19 +888,16 @@ static const mozilla::Module::ContractID
     { NS_ISTREAMCONVERTER_KEY COMPRESS_TO_UNCOMPRESSED, &kNS_HTTPCOMPRESSCONVERTER_CID },
     { NS_ISTREAMCONVERTER_KEY XCOMPRESS_TO_UNCOMPRESSED, &kNS_HTTPCOMPRESSCONVERTER_CID },
     { NS_ISTREAMCONVERTER_KEY DEFLATE_TO_UNCOMPRESSED, &kNS_HTTPCOMPRESSCONVERTER_CID },
     { MOZ_TXTTOHTMLCONV_CONTRACTID, &kMOZITXTTOHTMLCONV_CID },
     { NS_MIMEHEADERPARAM_CONTRACTID, &kNS_MIMEHEADERPARAM_CID },
     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "file", &kNS_FILEPROTOCOLHANDLER_CID },
     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &kNS_HTTPPROTOCOLHANDLER_CID },
     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "https", &kNS_HTTPSPROTOCOLHANDLER_CID },
-    { NS_HTTP_AUTHENTICATOR_CONTRACTID_PREFIX "basic", &kNS_HTTPBASICAUTH_CID },
-    { NS_HTTP_AUTHENTICATOR_CONTRACTID_PREFIX "digest", &kNS_HTTPDIGESTAUTH_CID },
-    { NS_HTTP_AUTHENTICATOR_CONTRACTID_PREFIX "ntlm", &kNS_HTTPNTLMAUTH_CID },
     { NS_HTTPAUTHMANAGER_CONTRACTID, &kNS_HTTPAUTHMANAGER_CID },
     { NS_HTTPACTIVITYDISTRIBUTOR_CONTRACTID, &kNS_HTTPACTIVITYDISTRIBUTOR_CID },
     { NS_THROTTLEQUEUE_CONTRACTID, &kNS_THROTTLEQUEUE_CID },
     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "ftp", &kNS_FTPPROTOCOLHANDLER_CID },
     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "resource", &kNS_RESPROTOCOLHANDLER_CID },
     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "moz-extension", &kNS_EXTENSIONPROTOCOLHANDLER_CID },
     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "about", &kNS_ABOUTPROTOCOLHANDLER_CID },
     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "moz-safe-about", &kNS_SAFEABOUTPROTOCOLHANDLER_CID },
--- a/netwerk/protocol/http/moz.build
+++ b/netwerk/protocol/http/moz.build
@@ -128,16 +128,17 @@ EXTRA_JS_MODULES += [
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '/dom/base',
+    '/extensions/auth',
     '/netwerk/base',
     '/netwerk/cookie',
 ]
 
 EXTRA_COMPONENTS += [
     'UAOverridesBootstrapper.js',
     'UAOverridesBootstrapper.manifest',
     'WellKnownOpportunisticUtils.js',
--- a/netwerk/protocol/http/nsHttpBasicAuth.cpp
+++ b/netwerk/protocol/http/nsHttpBasicAuth.cpp
@@ -5,20 +5,38 @@
 
 // HttpLog.h should generally be included first
 #include "HttpLog.h"
 
 #include "nsHttpBasicAuth.h"
 #include "plstr.h"
 #include "nsString.h"
 #include "mozilla/Base64.h"
+#include "mozilla/ClearOnShutdown.h"
 
 namespace mozilla {
 namespace net {
 
+StaticRefPtr<nsHttpBasicAuth> nsHttpBasicAuth::gSingleton;
+
+already_AddRefed<nsIHttpAuthenticator>
+nsHttpBasicAuth::GetOrCreate()
+{
+    nsCOMPtr<nsIHttpAuthenticator> authenticator;
+    if (gSingleton) {
+      authenticator = gSingleton;
+    } else {
+      gSingleton = new nsHttpBasicAuth();
+      ClearOnShutdown(&gSingleton);
+      authenticator = gSingleton;
+    }
+
+    return authenticator.forget();
+}
+
 //-----------------------------------------------------------------------------
 // nsHttpBasicAuth::nsISupports
 //-----------------------------------------------------------------------------
 
 NS_IMPL_ISUPPORTS(nsHttpBasicAuth, nsIHttpAuthenticator)
 
 //-----------------------------------------------------------------------------
 // nsHttpBasicAuth::nsIHttpAuthenticator
--- a/netwerk/protocol/http/nsHttpBasicAuth.h
+++ b/netwerk/protocol/http/nsHttpBasicAuth.h
@@ -2,31 +2,38 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
 #ifndef nsBasicAuth_h__
 #define nsBasicAuth_h__
 
 #include "nsIHttpAuthenticator.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/StaticPtr.h"
 
 namespace mozilla { namespace net {
 
 //-----------------------------------------------------------------------------
 // The nsHttpBasicAuth class produces HTTP Basic-auth responses for a username/
 // (optional)password pair, BASE64("user:pass").
 //-----------------------------------------------------------------------------
 
 class nsHttpBasicAuth : public nsIHttpAuthenticator
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIHTTPAUTHENTICATOR
 
     nsHttpBasicAuth() = default;
+
+    static already_AddRefed<nsIHttpAuthenticator> GetOrCreate();
+
 private:
     virtual ~nsHttpBasicAuth() = default;
+
+    static StaticRefPtr<nsHttpBasicAuth> gSingleton;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif // !nsHttpBasicAuth_h__
--- a/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
+++ b/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
@@ -20,16 +20,20 @@
 #include "nsEscape.h"
 #include "nsAuthInformationHolder.h"
 #include "nsIStringBundle.h"
 #include "nsIPrompt.h"
 #include "netCore.h"
 #include "nsIHttpAuthenticableChannel.h"
 #include "nsIURI.h"
 #include "nsContentUtils.h"
+#include "nsHttpBasicAuth.h"
+#include "nsHttpDigestAuth.h"
+#include "nsHttpNegotiateAuth.h"
+#include "nsHttpNTLMAuth.h"
 #include "nsServiceManagerUtils.h"
 #include "nsILoadContext.h"
 #include "nsIURL.h"
 #include "mozilla/StaticPrefs.h"
 #include "mozilla/Telemetry.h"
 #include "nsIProxiedChannel.h"
 #include "nsIProxyInfo.h"
 
@@ -1090,21 +1094,33 @@ nsHttpChannelAuthProvider::GetAuthentica
     LOG(("nsHttpChannelAuthProvider::GetAuthenticator [this=%p channel=%p]\n",
         this, mAuthChannel));
 
     GetAuthType(challenge, authType);
 
     // normalize to lowercase
     ToLowerCase(authType);
 
-    nsAutoCString contractid;
-    contractid.AssignLiteral(NS_HTTP_AUTHENTICATOR_CONTRACTID_PREFIX);
-    contractid.Append(authType);
+    nsCOMPtr<nsIHttpAuthenticator> authenticator;
+    if (authType.EqualsLiteral("negotiate")) {
+      authenticator = nsHttpNegotiateAuth::GetOrCreate();
+    } else if (authType.EqualsLiteral("basic")) {
+      authenticator = nsHttpBasicAuth::GetOrCreate();
+    } else if (authType.EqualsLiteral("digest")) {
+      authenticator = nsHttpDigestAuth::GetOrCreate();
+    } else if (authType.EqualsLiteral("ntlm")) {
+      authenticator = nsHttpNTLMAuth::GetOrCreate();
+    } else {
+      return NS_ERROR_SERVICE_NOT_FOUND;
+    }
 
-    return CallGetService(contractid.get(), auth);
+    MOZ_ASSERT(authenticator);
+    authenticator.forget(auth);
+
+    return NS_OK;
 }
 
 void
 nsHttpChannelAuthProvider::GetIdentityFromURI(uint32_t            authFlags,
                                               nsHttpAuthIdentity &ident)
 {
     LOG(("nsHttpChannelAuthProvider::GetIdentityFromURI [this=%p channel=%p]\n",
         this, mAuthChannel));
--- a/netwerk/protocol/http/nsHttpDigestAuth.cpp
+++ b/netwerk/protocol/http/nsHttpDigestAuth.cpp
@@ -2,16 +2,17 @@
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
 // HttpLog.h should generally be included first
 #include "HttpLog.h"
 
+#include "mozilla/ClearOnShutdown.h"
 #include "mozilla/Sprintf.h"
 #include "mozilla/Unused.h"
 
 #include "nsHttp.h"
 #include "nsHttpDigestAuth.h"
 #include "nsIHttpAuthenticableChannel.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIURI.h"
@@ -20,16 +21,33 @@
 #include "nsNetCID.h"
 #include "nsCRT.h"
 #include "nsICryptoHash.h"
 #include "nsComponentManagerUtils.h"
 
 namespace mozilla {
 namespace net {
 
+StaticRefPtr<nsHttpDigestAuth> nsHttpDigestAuth::gSingleton;
+
+already_AddRefed<nsIHttpAuthenticator>
+nsHttpDigestAuth::GetOrCreate()
+{
+    nsCOMPtr<nsIHttpAuthenticator> authenticator;
+    if (gSingleton) {
+      authenticator = gSingleton;
+    } else {
+      gSingleton = new nsHttpDigestAuth();
+      ClearOnShutdown(&gSingleton);
+      authenticator = gSingleton;
+    }
+
+    return authenticator.forget();
+}
+
 //-----------------------------------------------------------------------------
 // nsHttpDigestAuth::nsISupports
 //-----------------------------------------------------------------------------
 
 NS_IMPL_ISUPPORTS(nsHttpDigestAuth, nsIHttpAuthenticator)
 
 //-----------------------------------------------------------------------------
 // nsHttpDigestAuth <protected>
--- a/netwerk/protocol/http/nsHttpDigestAuth.h
+++ b/netwerk/protocol/http/nsHttpDigestAuth.h
@@ -6,16 +6,17 @@
 
 #ifndef nsDigestAuth_h__
 #define nsDigestAuth_h__
 
 #include "nsIHttpAuthenticator.h"
 #include "nsStringFwd.h"
 #include "nsCOMPtr.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/StaticPtr.h"
 
 class nsICryptoHash;
 
 namespace mozilla { namespace net {
 
 #define ALGO_SPECIFIED 0x01
 #define ALGO_MD5 0x02
 #define ALGO_MD5_SESS 0x04
@@ -33,16 +34,18 @@ namespace mozilla { namespace net {
 class nsHttpDigestAuth final : public nsIHttpAuthenticator
 {
   public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIHTTPAUTHENTICATOR
 
     nsHttpDigestAuth() = default;
 
+    static already_AddRefed<nsIHttpAuthenticator> GetOrCreate();
+
   protected:
     ~nsHttpDigestAuth() = default;
 
     MOZ_MUST_USE nsresult ExpandToHex(const char * digest, char * result);
 
     MOZ_MUST_USE nsresult CalculateResponse(const char * ha1_digest,
                                             const char * ha2_digest,
                                             const nsCString&  nonce,
@@ -82,14 +85,16 @@ class nsHttpDigestAuth final : public ns
 
     // append the quoted version of value to aHeaderLine
     MOZ_MUST_USE nsresult AppendQuotedString(const nsACString & value,
                                              nsACString & aHeaderLine);
 
   protected:
     nsCOMPtr<nsICryptoHash>        mVerifier;
     char                           mHashBuf[DIGEST_LENGTH];
+
+    static StaticRefPtr<nsHttpDigestAuth> gSingleton;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif // nsHttpDigestAuth_h__
--- a/netwerk/protocol/http/nsHttpNTLMAuth.cpp
+++ b/netwerk/protocol/http/nsHttpNTLMAuth.cpp
@@ -30,26 +30,29 @@
 #include "mozilla/CheckedInt.h"
 #include "mozilla/Tokenizer.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/Unused.h"
 #include "nsNetUtil.h"
 #include "nsIChannel.h"
 #include "nsUnicharUtils.h"
 #include "mozilla/net/HttpAuthUtils.h"
+#include "mozilla/ClearOnShutdown.h"
 
 namespace mozilla {
 namespace net {
 
 static const char kAllowProxies[] = "network.automatic-ntlm-auth.allow-proxies";
 static const char kAllowNonFqdn[] = "network.automatic-ntlm-auth.allow-non-fqdn";
 static const char kTrustedURIs[]  = "network.automatic-ntlm-auth.trusted-uris";
 static const char kForceGeneric[] = "network.auth.force-generic-ntlm";
 static const char kSSOinPBmode[] = "network.auth.private-browsing-sso";
 
+StaticRefPtr<nsHttpNTLMAuth> nsHttpNTLMAuth::gSingleton;
+
 static bool
 IsNonFqdn(nsIURI *uri)
 {
     nsAutoCString host;
     PRNetAddr addr;
 
     if (NS_FAILED(uri->GetAsciiHost(host)))
         return false;
@@ -139,16 +142,31 @@ class nsNTLMSessionState final : public 
     ~nsNTLMSessionState() = default;
 public:
     NS_DECL_ISUPPORTS
 };
 NS_IMPL_ISUPPORTS0(nsNTLMSessionState)
 
 //-----------------------------------------------------------------------------
 
+already_AddRefed<nsIHttpAuthenticator>
+nsHttpNTLMAuth::GetOrCreate()
+{
+    nsCOMPtr<nsIHttpAuthenticator> authenticator;
+    if (gSingleton) {
+      authenticator = gSingleton;
+    } else {
+      gSingleton = new nsHttpNTLMAuth();
+      ClearOnShutdown(&gSingleton);
+      authenticator = gSingleton;
+    }
+
+    return authenticator.forget();
+}
+
 NS_IMPL_ISUPPORTS(nsHttpNTLMAuth, nsIHttpAuthenticator)
 
 NS_IMETHODIMP
 nsHttpNTLMAuth::ChallengeReceived(nsIHttpAuthenticableChannel *channel,
                                   const char     *challenge,
                                   bool            isProxyAuth,
                                   nsISupports   **sessionState,
                                   nsISupports   **continuationState,
--- a/netwerk/protocol/http/nsHttpNTLMAuth.h
+++ b/netwerk/protocol/http/nsHttpNTLMAuth.h
@@ -1,31 +1,36 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
 #ifndef nsHttpNTLMAuth_h__
 #define nsHttpNTLMAuth_h__
 
 #include "nsIHttpAuthenticator.h"
+#include "mozilla/StaticPtr.h"
 
 namespace mozilla { namespace net {
 
 class nsHttpNTLMAuth : public nsIHttpAuthenticator
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIHTTPAUTHENTICATOR
 
     nsHttpNTLMAuth() : mUseNative(false) {}
 
+    static already_AddRefed<nsIHttpAuthenticator> GetOrCreate();
+
 private:
     virtual ~nsHttpNTLMAuth() = default;
 
     // This flag indicates whether we are using the native NTLM implementation
     // or the internal one.
     bool  mUseNative;
+
+    static StaticRefPtr<nsHttpNTLMAuth> gSingleton;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif // !nsHttpNTLMAuth_h__
--- a/netwerk/protocol/http/nsHttpTransaction.cpp
+++ b/netwerk/protocol/http/nsHttpTransaction.cpp
@@ -4,21 +4,25 @@
  * 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/. */
 
 // HttpLog.h should generally be included first
 #include "HttpLog.h"
 
 #include "base/basictypes.h"
 
+#include "nsHttpBasicAuth.h"
+#include "nsHttpChunkedDecoder.h"
+#include "nsHttpDigestAuth.h"
 #include "nsHttpHandler.h"
-#include "nsHttpTransaction.h"
+#include "nsHttpNegotiateAuth.h"
+#include "nsHttpNTLMAuth.h"
 #include "nsHttpRequestHead.h"
 #include "nsHttpResponseHead.h"
-#include "nsHttpChunkedDecoder.h"
+#include "nsHttpTransaction.h"
 #include "nsTransportUtils.h"
 #include "nsNetCID.h"
 #include "nsNetUtil.h"
 #include "nsIChannel.h"
 #include "nsIPipe.h"
 #include "nsCRT.h"
 #include "mozilla/Tokenizer.h"
 #include "TCPFastOpenLayer.h"
@@ -2017,22 +2021,27 @@ nsHttpTransaction::CheckForStickyAuthSch
       return;
   }
 
   Tokenizer p(auth);
   nsAutoCString schema;
   while (p.ReadWord(schema)) {
       ToLowerCase(schema);
 
-      nsAutoCString contractid;
-      contractid.AssignLiteral(NS_HTTP_AUTHENTICATOR_CONTRACTID_PREFIX);
-      contractid.Append(schema);
-
       // using a new instance because of thread safety of auth modules refcnt
-      nsCOMPtr<nsIHttpAuthenticator> authenticator(do_CreateInstance(contractid.get()));
+      nsCOMPtr<nsIHttpAuthenticator> authenticator;
+      if (schema.EqualsLiteral("negotiate")) {
+        authenticator = new nsHttpNegotiateAuth();
+      } else if (schema.EqualsLiteral("basic")) {
+        authenticator = new nsHttpBasicAuth();
+      } else if (schema.EqualsLiteral("digest")) {
+        authenticator = new nsHttpDigestAuth();
+      } else if (schema.EqualsLiteral("ntlm")) {
+        authenticator = new nsHttpNTLMAuth();
+      }
       if (authenticator) {
           uint32_t flags;
           nsresult rv = authenticator->GetAuthFlags(&flags);
           if (NS_SUCCEEDED(rv) && (flags & nsIHttpAuthenticator::CONNECTION_BASED)) {
               LOG(("  connection made sticky, found %s auth shema", schema.get()));
               // This is enough to make this transaction keep it's current connection,
               // prevents the connection from being released back to the pool.
               mCaps |= NS_HTTP_STICKY_CONNECTION;
--- a/netwerk/protocol/http/nsIHttpAuthenticator.idl
+++ b/netwerk/protocol/http/nsIHttpAuthenticator.idl
@@ -214,13 +214,8 @@ interface nsIHttpAuthenticator : nsISupp
     const unsigned long IDENTITY_INCLUDES_DOMAIN = (1<<11);
 
     /**
      * This flag indicates that the identity will be sent encrypted. It does
      * not make sense to combine this flag with IDENTITY_IGNORED.
      */
     const unsigned long IDENTITY_ENCRYPTED = (1<<12);
 };
-
-%{C++
-#define NS_HTTP_AUTHENTICATOR_CONTRACTID_PREFIX \
-    "@mozilla.org/network/http-authenticator;1?scheme="
-%}