Bug 1539819 - P3: Some adjustments to make TRRServiceChannel work on socket process r=dragana,necko-reviewers
authorKershaw Chang <kershaw@mozilla.com>
Mon, 18 May 2020 20:18:08 +0000
changeset 530705 d332f00b2ada23ed72448219d551d37449723144
parent 530704 3c13d25cab1eff31c39c7fa3b121fe58d24f71ca
child 530706 a0f338331b410462ac54b92603232828cecc65f4
push id116316
push userkjang@mozilla.com
push dateMon, 18 May 2020 20:28:45 +0000
treeherderautoland@7c84257e93be [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdragana, necko-reviewers
bugs1539819
milestone78.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 1539819 - P3: Some adjustments to make TRRServiceChannel work on socket process r=dragana,necko-reviewers Differential Revision: https://phabricator.services.mozilla.com/D68399
netwerk/build/components.conf
netwerk/dns/TRR.cpp
netwerk/dns/TRR.h
netwerk/dns/TRRService.cpp
netwerk/protocol/http/HttpBaseChannel.h
netwerk/protocol/http/TRRServiceChannel.cpp
netwerk/protocol/http/TRRServiceChannel.h
xpcom/io/components.conf
--- a/netwerk/build/components.conf
+++ b/netwerk/build/components.conf
@@ -468,16 +468,17 @@ Classes = [
         'type': 'nsAuthURLParser',
         'headers': ['nsURLParsers.h'],
         'processes': ProcessSelector.ALLOW_IN_SOCKET_PROCESS,
     },
     {
         'cid': '{892ffeb0-3f80-11d3-a16c-0050041caf44}',
         'contract_ids': ['@mozilla.org/streamConverters;1'],
         'legacy_constructor': 'CreateNewStreamConvServiceFactory',
+        'processes': ProcessSelector.ALLOW_IN_SOCKET_PROCESS,
     },
     {
         'cid': '{cf0f71fd-fafd-4e2b-9fdc-134d972e16e2}',
         'contract_ids': ['@mozilla.org/streamconv;1?from=application/http-index-format&to=text/html'],
         'legacy_constructor': 'nsIndexedToHTML::Create',
         'headers': ['/netwerk/streamconv/converters/nsIndexedToHTML.h'],
     },
     {
@@ -491,16 +492,17 @@ Classes = [
             '@mozilla.org/streamconv;1?from=br&to=uncompressed',
             '@mozilla.org/streamconv;1?from=compress&to=uncompressed',
             '@mozilla.org/streamconv;1?from=deflate&to=uncompressed',
             '@mozilla.org/streamconv;1?from=gzip&to=uncompressed',
             '@mozilla.org/streamconv;1?from=x-compress&to=uncompressed',
             '@mozilla.org/streamconv;1?from=x-gzip&to=uncompressed',
         ],
         'legacy_constructor': 'CreateNewHTTPCompressConvFactory',
+        'processes': ProcessSelector.ALLOW_IN_SOCKET_PROCESS,
     },
     {
         'cid': '{7584ce90-5b25-11d3-a175-0050041caf44}',
         'contract_ids': [
             '@mozilla.org/streamconv;1?from=multipart/byteranges&to=*/*',
             '@mozilla.org/streamconv;1?from=multipart/mixed&to=*/*',
             '@mozilla.org/streamconv;1?from=multipart/x-mixed-replace&to=*/*',
         ],
--- a/netwerk/dns/TRR.cpp
+++ b/netwerk/dns/TRR.cpp
@@ -156,21 +156,23 @@ nsresult TRR::DohEncode(nsCString& aBody
 
     // ADDRESS, minimum number of octets == nothing because zero bits
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TRR::Run() {
-  MOZ_ASSERT_IF(gTRRService && StaticPrefs::network_trr_fetch_off_main_thread(),
+  MOZ_ASSERT_IF(gTRRService &&
+                    StaticPrefs::network_trr_fetch_off_main_thread() &&
+                    !XRE_IsSocketProcess(),
                 gTRRService->IsOnTRRThread());
-  MOZ_ASSERT_IF(
-      gTRRService && !StaticPrefs::network_trr_fetch_off_main_thread(),
-      NS_IsMainThread());
+  MOZ_ASSERT_IF(!StaticPrefs::network_trr_fetch_off_main_thread() ||
+                    XRE_IsSocketProcess(),
+                NS_IsMainThread());
 
   if ((gTRRService == nullptr) || NS_FAILED(SendHTTPRequest())) {
     FailData(NS_ERROR_FAILURE);
     // The dtor will now be run
   }
   return NS_OK;
 }
 
@@ -186,17 +188,17 @@ static void InitHttpHandler() {
   if (NS_FAILED(rv)) {
     return;
   }
 }
 
 nsresult TRR::CreateChannelHelper(nsIURI* aUri, nsIChannel** aResult) {
   *aResult = nullptr;
 
-  if (NS_IsMainThread()) {
+  if (NS_IsMainThread() && !XRE_IsSocketProcess()) {
     nsresult rv;
     nsCOMPtr<nsIIOService> ios(do_GetIOService(&rv));
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_NewChannel(aResult, aUri, nsContentUtils::GetSystemPrincipal(),
                          nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
                          nsIContentPolicy::TYPE_OTHER,
                          nullptr,  // nsICookieJarSettings
@@ -1469,17 +1471,18 @@ class ProxyCancel : public Runnable {
     return NS_OK;
   }
 
  private:
   RefPtr<TRR> mTRR;
 };
 
 void TRR::Cancel() {
-  if (StaticPrefs::network_trr_fetch_off_main_thread()) {
+  if (StaticPrefs::network_trr_fetch_off_main_thread() &&
+      !XRE_IsSocketProcess()) {
     if (gTRRService) {
       nsCOMPtr<nsIThread> thread = gTRRService->TRRThread();
       if (thread && !thread->IsOnCurrentThread()) {
         nsCOMPtr<nsIRunnable> r = new ProxyCancel(this);
         thread->Dispatch(r.forget());
         return;
       }
     }
--- a/netwerk/dns/TRR.h
+++ b/netwerk/dns/TRR.h
@@ -81,64 +81,68 @@ class TRR : public Runnable,
         mType(aType),
         mBodySize(0),
         mFailed(false),
         mCnameLoop(kCnameChaseMax),
         mAllowRFC1918(false),
         mOriginSuffix(aRec->originSuffix) {
     mHost = aRec->host;
     mPB = aRec->pb;
-    MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess(), "TRR must be in parent");
+    MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess() || XRE_IsSocketProcess(),
+                          "TRR must be in parent or socket process");
   }
 
   // when following CNAMEs
   explicit TRR(AHostResolver* aResolver, nsHostRecord* aRec, nsCString& aHost,
                enum TrrType& aType, unsigned int aLoopCount, bool aPB)
       : mozilla::Runnable("TRR"),
         mHost(aHost),
         mRec(aRec),
         mHostResolver(aResolver),
         mType(aType),
         mBodySize(0),
         mFailed(false),
         mPB(aPB),
         mCnameLoop(aLoopCount),
         mAllowRFC1918(false),
         mOriginSuffix(aRec ? aRec->originSuffix : EmptyCString()) {
-    MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess(), "TRR must be in parent");
+    MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess() || XRE_IsSocketProcess(),
+                          "TRR must be in parent or socket process");
   }
 
   // used on push
   explicit TRR(AHostResolver* aResolver, bool aPB)
       : mozilla::Runnable("TRR"),
         mHostResolver(aResolver),
         mType(TRRTYPE_A),
         mBodySize(0),
         mFailed(false),
         mPB(aPB),
         mCnameLoop(kCnameChaseMax),
         mAllowRFC1918(false) {
-    MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess(), "TRR must be in parent");
+    MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess() || XRE_IsSocketProcess(),
+                          "TRR must be in parent or socket process");
   }
 
   // to verify a domain
   explicit TRR(AHostResolver* aResolver, nsACString& aHost, enum TrrType aType,
                const nsACString& aOriginSuffix, bool aPB)
       : mozilla::Runnable("TRR"),
         mHost(aHost),
         mRec(nullptr),
         mHostResolver(aResolver),
         mType(aType),
         mBodySize(0),
         mFailed(false),
         mPB(aPB),
         mCnameLoop(kCnameChaseMax),
         mAllowRFC1918(false),
         mOriginSuffix(aOriginSuffix) {
-    MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess(), "TRR must be in parent");
+    MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess() || XRE_IsSocketProcess(),
+                          "TRR must be in parent or socket process");
   }
 
   NS_IMETHOD Run() override;
   void Cancel();
   enum TrrType Type() { return mType; }
   nsCString mHost;
   RefPtr<nsHostRecord> mRec;
   RefPtr<AHostResolver> mHostResolver;
--- a/netwerk/dns/TRRService.cpp
+++ b/netwerk/dns/TRRService.cpp
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsCharSeparatedTokenizer.h"
 #include "nsComponentManagerUtils.h"
 #include "nsICaptivePortalService.h"
 #include "nsIParentalControlsService.h"
 #include "nsINetworkLinkService.h"
 #include "nsIObserverService.h"
+#include "nsIOService.h"
 #include "nsNetUtil.h"
 #include "nsStandardURL.h"
 #include "TRR.h"
 #include "TRRService.h"
 
 #include "mozilla/Preferences.h"
 #include "mozilla/StaticPrefs_network.h"
 #include "mozilla/Telemetry.h"
@@ -541,17 +542,18 @@ TRRService::~TRRService() {
 
 nsresult TRRService::DispatchTRRRequest(TRR* aTrrRequest) {
   return DispatchTRRRequestInternal(aTrrRequest, true);
 }
 
 nsresult TRRService::DispatchTRRRequestInternal(TRR* aTrrRequest,
                                                 bool aWithLock) {
   NS_ENSURE_ARG_POINTER(aTrrRequest);
-  if (!StaticPrefs::network_trr_fetch_off_main_thread()) {
+  if (!StaticPrefs::network_trr_fetch_off_main_thread() ||
+      XRE_IsSocketProcess()) {
     return NS_DispatchToMainThread(aTrrRequest);
   }
 
   RefPtr<TRR> trr = aTrrRequest;
   nsCOMPtr<nsIThread> thread = aWithLock ? TRRThread() : TRRThread_locked();
   if (!thread) {
     return NS_ERROR_FAILURE;
   }
@@ -992,19 +994,21 @@ TRRService::Notify(nsITimer* aTimer) {
   } else {
     MOZ_CRASH("Unknown timer");
   }
 
   return NS_OK;
 }
 
 void TRRService::TRRIsOkay(enum TrrOkay aReason) {
-  MOZ_ASSERT_IF(StaticPrefs::network_trr_fetch_off_main_thread(),
+  MOZ_ASSERT_IF(StaticPrefs::network_trr_fetch_off_main_thread() &&
+                    !XRE_IsSocketProcess(),
                 IsOnTRRThread());
-  MOZ_ASSERT_IF(!StaticPrefs::network_trr_fetch_off_main_thread(),
+  MOZ_ASSERT_IF(!StaticPrefs::network_trr_fetch_off_main_thread() ||
+                    XRE_IsSocketProcess(),
                 NS_IsMainThread());
 
   Telemetry::AccumulateCategorical(
       aReason == OKAY_NORMAL ? Telemetry::LABELS_DNS_TRR_SUCCESS::Fine
                              : (aReason == OKAY_TIMEOUT
                                     ? Telemetry::LABELS_DNS_TRR_SUCCESS::Timeout
                                     : Telemetry::LABELS_DNS_TRR_SUCCESS::Bad));
   if (aReason == OKAY_NORMAL) {
@@ -1023,19 +1027,21 @@ void TRRService::TRRIsOkay(enum TrrOkay 
   }
 }
 
 AHostResolver::LookupStatus TRRService::CompleteLookup(
     nsHostRecord* rec, nsresult status, AddrInfo* aNewRRSet, bool pb,
     const nsACString& aOriginSuffix) {
   // this is an NS check for the TRR blacklist or confirmationNS check
 
-  MOZ_ASSERT_IF(StaticPrefs::network_trr_fetch_off_main_thread(),
+  MOZ_ASSERT_IF(StaticPrefs::network_trr_fetch_off_main_thread() &&
+                    !XRE_IsSocketProcess(),
                 IsOnTRRThread());
-  MOZ_ASSERT_IF(!StaticPrefs::network_trr_fetch_off_main_thread(),
+  MOZ_ASSERT_IF(!StaticPrefs::network_trr_fetch_off_main_thread() ||
+                    XRE_IsSocketProcess(),
                 NS_IsMainThread());
   MOZ_ASSERT(!rec);
 
   RefPtr<AddrInfo> newRRSet(aNewRRSet);
   MOZ_ASSERT(newRRSet && newRRSet->IsTRR() == TRRTYPE_NS);
 
 #ifdef DEBUG
   {
--- a/netwerk/protocol/http/HttpBaseChannel.h
+++ b/netwerk/protocol/http/HttpBaseChannel.h
@@ -563,17 +563,17 @@ class HttpBaseChannel : public nsHashPro
   void GetCallback(nsCOMPtr<T>& aResult) {
     NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
                                   NS_GET_TEMPLATE_IID(T),
                                   getter_AddRefs(aResult));
   }
 
   // Redirect tracking
   // Checks whether or not aURI and mOriginalURI share the same domain.
-  bool SameOriginWithOriginalUri(nsIURI* aURI);
+  virtual bool SameOriginWithOriginalUri(nsIURI* aURI);
 
   // GetPrincipal Returns the channel's URI principal.
   nsIPrincipal* GetURIPrincipal();
 
   [[nodiscard]] bool BypassServiceWorker() const;
 
   // Returns true if this channel should intercept the network request and
   // prepare for a possible synthesized response instead.
--- a/netwerk/protocol/http/TRRServiceChannel.cpp
+++ b/netwerk/protocol/http/TRRServiceChannel.cpp
@@ -3,16 +3,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/. */
 
 #include "TRRServiceChannel.h"
 
 #include "HttpLog.h"
+#include "AltServiceChild.h"
 #include "mozilla/StaticPrefs_network.h"
 #include "nsDNSPrefetch.h"
 #include "nsEscape.h"
 #include "nsHttpTransaction.h"
 #include "nsICancelable.h"
 #include "nsIHttpPushListener.h"
 #include "nsIProtocolProxyService2.h"
 #include "nsIOService.h"
@@ -320,17 +321,19 @@ nsresult TRRServiceChannel::BeginConnect
   if (mProxyInfo) proxyInfo = do_QueryInterface(mProxyInfo);
 
   mRequestHead.SetHTTPS(isHttps);
   mRequestHead.SetOrigin(scheme, host, port);
 
   RefPtr<nsHttpConnectionInfo> connInfo = new nsHttpConnectionInfo(
       host, port, EmptyCString(), mUsername, GetTopWindowOrigin(), proxyInfo,
       OriginAttributes(), isHttps);
-  mAllowAltSvc = (mAllowAltSvc && !gHttpHandler->IsSpdyBlacklisted(connInfo));
+  // TODO: Bug 1622778 for using AltService in socket process.
+  mAllowAltSvc = XRE_IsParentProcess() &&
+                 (mAllowAltSvc && !gHttpHandler->IsSpdyBlacklisted(connInfo));
 
   RefPtr<AltSvcMapping> mapping;
   if (!mConnectionInfo && mAllowAltSvc &&  // per channel
       !(mLoadFlags & LOAD_FRESH_CONNECTION) &&
       AltSvcMapping::AcceptableProxy(proxyInfo) &&
       (scheme.EqualsLiteral("http") || scheme.EqualsLiteral("https")) &&
       (mapping = gHttpHandler->GetAltServiceMapping(
            scheme, host, port, mPrivateBrowsing, IsIsolated(),
@@ -769,16 +772,29 @@ nsresult TRRServiceChannel::CallOnStartR
   }
 
   nsAutoCString contentEncoding;
   rv = mResponseHead->GetHeader(nsHttp::Content_Encoding, contentEncoding);
   if (NS_FAILED(rv) || contentEncoding.IsEmpty()) {
     return NS_OK;
   }
 
+  // DoApplyContentConversions can only be called on the main thread.
+  if (NS_IsMainThread()) {
+    nsCOMPtr<nsIStreamListener> listener;
+    rv =
+        DoApplyContentConversions(mListener, getter_AddRefs(listener), nullptr);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    AfterApplyContentConversions(rv, listener);
+    return NS_OK;
+  }
+
   Suspend();
 
   RefPtr<TRRServiceChannel> self = this;
   rv = NS_DispatchToMainThread(
       NS_NewRunnableFunction("TRRServiceChannel::DoApplyContentConversions",
                              [self]() {
                                nsCOMPtr<nsIStreamListener> listener;
                                nsresult rv = self->DoApplyContentConversions(
@@ -800,24 +816,23 @@ void TRRServiceChannel::AfterApplyConten
   LOG(("TRRServiceChannel::AfterApplyContentConversions [this=%p]", this));
   if (!mCurrentEventTarget->IsOnCurrentThread()) {
     RefPtr<TRRServiceChannel> self = this;
     nsCOMPtr<nsIStreamListener> listener = aListener;
     self->mCurrentEventTarget->Dispatch(
         NS_NewRunnableFunction(
             "TRRServiceChannel::AfterApplyContentConversions",
             [self, aResult, listener]() {
+              self->Resume();
               self->AfterApplyContentConversions(aResult, listener);
             }),
         NS_DISPATCH_NORMAL);
     return;
   }
 
-  Resume();
-
   if (mCanceled) {
     return;
   }
 
   if (NS_FAILED(aResult)) {
     Unused << AsyncAbort(aResult);
     return;
   }
@@ -879,16 +894,24 @@ void TRRServiceChannel::ProcessAltServic
   }
 
   nsCString topWindowOrigin = GetTopWindowOrigin();
   bool isIsolated = IsIsolated();
   auto processHeaderTask = [altSvc, scheme, originHost, originPort,
                             userName(mUsername), topWindowOrigin,
                             privateBrowsing(mPrivateBrowsing), isIsolated,
                             callbacks, proxyInfo, caps(mCaps)]() {
+    if (XRE_IsSocketProcess()) {
+      AltServiceChild::ProcessHeader(
+          altSvc, scheme, originHost, originPort, userName, topWindowOrigin,
+          privateBrowsing, isIsolated, callbacks, proxyInfo,
+          caps & NS_HTTP_DISALLOW_SPDY, OriginAttributes());
+      return;
+    }
+
     AltSvcMapping::ProcessHeader(
         altSvc, scheme, originHost, originPort, userName, topWindowOrigin,
         privateBrowsing, isIsolated, callbacks, proxyInfo,
         caps & NS_HTTP_DISALLOW_SPDY, OriginAttributes());
   };
 
   if (NS_IsMainThread()) {
     processHeaderTask();
@@ -1428,10 +1451,12 @@ NS_IMETHODIMP TRRServiceChannel::SetLoad
 
 NS_IMETHODIMP
 TRRServiceChannel::TimingAllowCheck(nsIPrincipal* aOrigin, bool* aResult) {
   NS_ENSURE_ARG_POINTER(aResult);
   *aResult = true;
   return NS_OK;
 }
 
+bool TRRServiceChannel::SameOriginWithOriginalUri(nsIURI* aURI) { return true; }
+
 }  // namespace net
 }  // namespace mozilla
--- a/netwerk/protocol/http/TRRServiceChannel.h
+++ b/netwerk/protocol/http/TRRServiceChannel.h
@@ -128,16 +128,18 @@ class TRRServiceChannel : public HttpBas
   nsresult ResolveProxy();
   void AfterApplyContentConversions(nsresult aResult,
                                     nsIStreamListener* aListener);
   nsresult SyncProcessRedirection(uint32_t aHttpStatus);
   [[nodiscard]] virtual nsresult SetupReplacementChannel(
       nsIURI* aNewURI, nsIChannel* aNewChannel, bool aPreserveMethod,
       uint32_t aRedirectFlags) override;
 
+  virtual bool SameOriginWithOriginalUri(nsIURI* aURI) override;
+
   // True only when we have computed the value of the top window origin.
   bool mTopWindowOriginComputed;
 
   nsCString mUsername;
   // The origin of the top window, only valid when mTopWindowOriginComputed is
   // true.
   nsCString mTopWindowOrigin;
 
--- a/xpcom/io/components.conf
+++ b/xpcom/io/components.conf
@@ -29,10 +29,11 @@ Classes = [
         'legacy_constructor': 'nsScriptableInputStream::Create',
         'headers': ['nsScriptableInputStream.h'],
     },
     {
         'cid': '{0abb0835-5000-4790-af28-61b3ba17c295}',
         'contract_ids': ['@mozilla.org/io/string-input-stream;1'],
         'legacy_constructor': 'nsStringInputStreamConstructor',
         'headers': ['/xpcom/build/XPCOMModule.h'],
+        'processes': ProcessSelector.ALLOW_IN_SOCKET_PROCESS,
     },
 ]