Bug 1612992 - Don't replace the nsIRequest passed to OnStart/StopRequest with nsViewSourceChannel if we don't need it. r=mayhemer
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 26 Feb 2020 22:59:34 +0000
changeset 515799 07bf7a599bcee97a1f0ba3b95a6286ec07a409a5
parent 515798 e385c9242708eb4cae1fd0dfe200874c71b20423
child 515800 465806a90c068e3d37cf7e564c0eb8027b0641b7
push id108455
push usermwoodrow@mozilla.com
push dateThu, 27 Feb 2020 01:00:58 +0000
treeherderautoland@07bf7a599bce [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmayhemer
bugs1612992
milestone75.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 1612992 - Don't replace the nsIRequest passed to OnStart/StopRequest with nsViewSourceChannel if we don't need it. r=mayhemer Differential Revision: https://phabricator.services.mozilla.com/D63285
netwerk/base/moz.build
netwerk/base/nsIWrapperChannel.idl
netwerk/ipc/DocumentLoadListener.cpp
netwerk/protocol/http/HttpChannelParent.cpp
netwerk/protocol/viewsource/nsIViewSourceChannel.idl
netwerk/protocol/viewsource/nsViewSourceChannel.cpp
netwerk/protocol/viewsource/nsViewSourceChannel.h
--- a/netwerk/base/moz.build
+++ b/netwerk/base/moz.build
@@ -122,17 +122,16 @@ XPIDL_SOURCES += [
     'nsIUDPSocket.idl',
     'nsIUploadChannel.idl',
     'nsIUploadChannel2.idl',
     'nsIURI.idl',
     'nsIURIMutator.idl',
     'nsIURIWithSpecialOrigin.idl',
     'nsIURL.idl',
     'nsIURLParser.idl',
-    'nsIWrapperChannel.idl',
     'nsPISocketTransportService.idl',
 ]
 
 XPIDL_MODULE = 'necko'
 
 EXPORTS += [
     'netCore.h',
     'nsASocketHandler.h',
deleted file mode 100644
--- a/netwerk/base/nsIWrapperChannel.idl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* 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 "nsIChannel.idl"
-
-/**
- * A channel that exists as a wrapper around another channel,
- * like view-source.
- *
- * Exposes the inner channel for callers that need it. 
- */
-
-[uuid(2dfce356-b3e0-4f5e-bb55-e91cf9b49acc)]
-interface nsIWrapperChannel : nsISupports
-{
-  readonly attribute nsIChannel innerChannel;
-};
--- a/netwerk/ipc/DocumentLoadListener.cpp
+++ b/netwerk/ipc/DocumentLoadListener.cpp
@@ -27,17 +27,17 @@
 #include "nsIWindowWatcher.h"
 #include "nsIURIContentListener.h"
 #include "nsWebNavigationInfo.h"
 #include "nsURILoader.h"
 #include "nsIStreamConverterService.h"
 #include "nsExternalHelperAppService.h"
 #include "nsCExternalHandlerService.h"
 #include "nsMimeTypes.h"
-#include "nsIWrapperChannel.h"
+#include "nsIViewSourceChannel.h"
 
 mozilla::LazyLogModule gDocumentChannelLog("DocumentChannel");
 #define LOG(fmt) MOZ_LOG(gDocumentChannelLog, mozilla::LogLevel::Verbose, fmt)
 
 using namespace mozilla::dom;
 
 namespace mozilla {
 namespace net {
@@ -302,16 +302,25 @@ bool DocumentLoadListener::Open(
     httpChannelImpl->SetWarningReporter(this);
   }
 
   nsCOMPtr<nsITimedChannel> timedChannel = do_QueryInterface(mChannel);
   if (timedChannel) {
     timedChannel->SetAsyncOpen(aAsyncOpenTime);
   }
 
+  // nsViewSourceChannel normally replaces the nsIRequest passed to
+  // OnStart/StopRequest with itself. We don't need this, and instead
+  // we want the original request so that we get different ones for
+  // each part of a multipart channel.
+  if (nsCOMPtr<nsIViewSourceChannel> viewSourceChannel =
+          do_QueryInterface(mChannel)) {
+    viewSourceChannel->SetReplaceRequest(false);
+  }
+
   // Setup a ClientChannelHelper to watch for redirects, and copy
   // across any serviceworker related data between channels as needed.
   AddClientChannelHelperInParent(mChannel, GetMainThreadSerialEventTarget());
 
   if (aDocumentOpenFlags) {
     RefPtr<ParentProcessDocumentOpenInfo> openInfo =
         new ParentProcessDocumentOpenInfo(mParentChannelListener,
                                           aPluginsAllowed, *aDocumentOpenFlags,
@@ -645,21 +654,17 @@ void DocumentLoadListener::SerializeRedi
       redirectLoadInfo->SetReservedClientInfo(*reservedClientInfo);
     }
   }
 
   // Register the new channel and obtain id for it
   nsCOMPtr<nsIRedirectChannelRegistrar> registrar =
       RedirectChannelRegistrar::GetOrCreate();
   MOZ_ASSERT(registrar);
-  nsCOMPtr<nsIChannel> chan = mChannel;
-  if (nsCOMPtr<nsIWrapperChannel> wrapper = do_QueryInterface(chan)) {
-    wrapper->GetInnerChannel(getter_AddRefs(chan));
-  }
-  nsresult rv = registrar->RegisterChannel(chan, &mRedirectChannelId);
+  nsresult rv = registrar->RegisterChannel(mChannel, &mRedirectChannelId);
   NS_ENSURE_SUCCESS_VOID(rv);
   aArgs.registrarId() = mRedirectChannelId;
 
   MOZ_ALWAYS_SUCCEEDS(
       ipc::LoadInfoToLoadInfoArgs(redirectLoadInfo, &aArgs.loadInfo()));
 
   mChannel->GetOriginalURI(getter_AddRefs(aArgs.originalURI()));
 
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -48,17 +48,16 @@
 #include "nsIWindowWatcher.h"
 #include "mozilla/dom/Document.h"
 #include "nsISecureBrowserUI.h"
 #include "nsStreamUtils.h"
 #include "nsStringStream.h"
 #include "nsThreadUtils.h"
 #include "nsQueryObject.h"
 #include "nsIMultiPartChannel.h"
-#include "nsIWrapperChannel.h"
 
 using mozilla::BasePrincipal;
 using namespace mozilla::dom;
 using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace net {
 
@@ -1378,21 +1377,16 @@ HttpChannelParent::OnStartRequest(nsIReq
       nsCOMPtr<nsIChannel> baseChannel;
       multiPartChannel->GetBaseChannel(getter_AddRefs(baseChannel));
       chan = do_QueryObject(baseChannel);
 
       uint32_t partID = 0;
       multiPartChannel->GetPartID(&partID);
       multiPartID = Some(partID);
       multiPartChannel->GetIsLastPart(&isLastPartOfMultiPart);
-    } else if (nsCOMPtr<nsIWrapperChannel> wrapperChannel =
-                   do_QueryInterface(aRequest)) {
-      nsCOMPtr<nsIChannel> inner;
-      wrapperChannel->GetInnerChannel(getter_AddRefs(inner));
-      chan = do_QueryObject(inner);
     }
   }
   MOZ_ASSERT(multiPartID || !mIsMultiPart, "Changed multi-part state?");
 
   if (!chan) {
     LOG(("  aRequest is not HttpBaseChannel"));
     NS_ERROR(
         "Expecting only HttpBaseChannel as aRequest in "
--- a/netwerk/protocol/viewsource/nsIViewSourceChannel.idl
+++ b/netwerk/protocol/viewsource/nsIViewSourceChannel.idl
@@ -28,11 +28,19 @@ interface nsIViewSourceChannel : nsIChan
     /**
      * Set to indicate the base URI.  If this channel is a srcdoc channel, it
      * returns the base URI provided by the embedded channel.  It is used to
      * provide an indication of the base URI in circumstances where it isn't
      * otherwise recoverable.  Returns null when it isn't set and isn't a
      * srcdoc channel.
      */
     [must_use] attribute nsIURI baseURI;
+
+    /**
+     * If true (default), then replaces the nsIRequest* passed to
+     * nsIStreamListener callback functions with itself, so that
+     * nsIViewSourceChannel is available.
+     * Otherwise passes through the the nsIRequest* from the inner channel.
+     */
+    attribute boolean replaceRequest;
 };
 
 
--- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
+++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
@@ -23,17 +23,16 @@ NS_IMPL_RELEASE(nsViewSourceChannel)
 /*
   This QI uses NS_INTERFACE_MAP_ENTRY_CONDITIONAL to check for
   non-nullness of mHttpChannel, mCachingChannel, and mUploadChannel.
 */
 NS_INTERFACE_MAP_BEGIN(nsViewSourceChannel)
   NS_INTERFACE_MAP_ENTRY(nsIViewSourceChannel)
   NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
   NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
-  NS_INTERFACE_MAP_ENTRY(nsIWrapperChannel)
   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
   NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink)
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannel, mHttpChannel)
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIIdentChannel, mHttpChannel)
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannelInternal,
                                      mHttpChannelInternal)
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsICachingChannel, mCachingChannel)
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsICacheInfoChannel, mCacheInfoChannel)
@@ -642,58 +641,80 @@ nsViewSourceChannel::SetBaseURI(nsIURI* 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsViewSourceChannel::GetProtocolVersion(nsACString& aProtocolVersion) {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
+NS_IMETHODIMP
+nsViewSourceChannel::GetReplaceRequest(bool* aReplaceRequest) {
+  *aReplaceRequest = mReplaceRequest;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsViewSourceChannel::SetReplaceRequest(bool aReplaceRequest) {
+  mReplaceRequest = aReplaceRequest;
+  return NS_OK;
+}
+
 // nsIRequestObserver methods
 NS_IMETHODIMP
 nsViewSourceChannel::OnStartRequest(nsIRequest* aRequest) {
   NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
   // The channel may have gotten redirected... Time to update our info
   mChannel = do_QueryInterface(aRequest);
   mHttpChannel = do_QueryInterface(aRequest);
   mCachingChannel = do_QueryInterface(aRequest);
   mCacheInfoChannel = do_QueryInterface(mChannel);
   mUploadChannel = do_QueryInterface(aRequest);
 
   nsresult rv = UpdateLoadInfoResultPrincipalURI();
   if (NS_FAILED(rv)) {
     Cancel(rv);
   }
 
-  return mListener->OnStartRequest(static_cast<nsIViewSourceChannel*>(this));
+  if (mReplaceRequest) {
+    return mListener->OnStartRequest(static_cast<nsIViewSourceChannel*>(this));
+  }
+  return mListener->OnStartRequest(aRequest);
 }
 
 NS_IMETHODIMP
 nsViewSourceChannel::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
   NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
   if (mChannel) {
     nsCOMPtr<nsILoadGroup> loadGroup;
     mChannel->GetLoadGroup(getter_AddRefs(loadGroup));
     if (loadGroup) {
       loadGroup->RemoveRequest(static_cast<nsIViewSourceChannel*>(this),
                                nullptr, aStatus);
     }
   }
-  return mListener->OnStopRequest(static_cast<nsIViewSourceChannel*>(this),
-                                  aStatus);
+  if (mReplaceRequest) {
+    return mListener->OnStopRequest(static_cast<nsIViewSourceChannel*>(this),
+                                    aStatus);
+  }
+  return mListener->OnStopRequest(aRequest, aStatus);
 }
 
 // nsIStreamListener methods
 NS_IMETHODIMP
 nsViewSourceChannel::OnDataAvailable(nsIRequest* aRequest,
                                      nsIInputStream* aInputStream,
                                      uint64_t aSourceOffset, uint32_t aLength) {
   NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
-  return mListener->OnDataAvailable(static_cast<nsIViewSourceChannel*>(this),
-                                    aInputStream, aSourceOffset, aLength);
+  if (mReplaceRequest) {
+    return mListener->OnDataAvailable(static_cast<nsIViewSourceChannel*>(this),
+                                      aInputStream, aSourceOffset, aLength);
+  }
+  return mListener->OnDataAvailable(aRequest, aInputStream, aSourceOffset,
+                                    aLength);
 }
 
 // nsIHttpChannel methods
 
 // We want to forward most of nsIHttpChannel over to mHttpChannel, but we want
 // to override GetRequestHeader and VisitHeaders. The reason is that we don't
 // want various headers like Link: and Refresh: applying to view-source.
 NS_IMETHODIMP
@@ -1083,27 +1104,16 @@ nsViewSourceChannel::CompleteRedirectSet
 
   if (NS_SUCCEEDED(rv)) {
     mOpened = true;
   }
 
   return rv;
 }
 
-// nsIWrapperChannel
-
-NS_IMETHODIMP
-nsViewSourceChannel::GetInnerChannel(nsIChannel** aChannel) {
-  NS_ENSURE_TRUE(mChannel, NS_ERROR_NOT_INITIALIZED);
-
-  nsCOMPtr<nsIChannel> chan = mChannel;
-  chan.forget(aChannel);
-  return NS_OK;
-}
-
 // nsIChannelEventSink
 
 NS_IMETHODIMP
 nsViewSourceChannel::AsyncOnChannelRedirect(
     nsIChannel* oldChannel, nsIChannel* newChannel, uint32_t flags,
     nsIAsyncVerifyRedirectCallback* callback) {
   nsresult rv;
 
--- a/netwerk/protocol/viewsource/nsViewSourceChannel.h
+++ b/netwerk/protocol/viewsource/nsViewSourceChannel.h
@@ -12,55 +12,55 @@
 #include "nsIApplicationCacheChannel.h"
 #include "nsICachingChannel.h"
 #include "nsIFormPOSTActionChannel.h"
 #include "nsIHttpChannel.h"
 #include "nsIHttpChannelInternal.h"
 #include "nsIStreamListener.h"
 #include "nsIURI.h"
 #include "nsIViewSourceChannel.h"
-#include "nsIWrapperChannel.h"
 #include "nsIChildChannel.h"
 #include "nsString.h"
 
 class nsViewSourceChannel final : public nsIViewSourceChannel,
                                   public nsIStreamListener,
                                   public nsIHttpChannel,
                                   public nsIHttpChannelInternal,
                                   public nsICachingChannel,
                                   public nsIApplicationCacheChannel,
                                   public nsIFormPOSTActionChannel,
                                   public nsIChildChannel,
-                                  public nsIWrapperChannel,
                                   public nsIInterfaceRequestor,
                                   public nsIChannelEventSink {
  public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIREQUEST
   NS_DECL_NSICHANNEL
   NS_DECL_NSIIDENTCHANNEL
   NS_DECL_NSIVIEWSOURCECHANNEL
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSIHTTPCHANNEL
   NS_DECL_NSICHILDCHANNEL
-  NS_DECL_NSIWRAPPERCHANNEL
   NS_DECL_NSIINTERFACEREQUESTOR
   NS_DECL_NSICHANNELEVENTSINK
   NS_FORWARD_SAFE_NSICACHEINFOCHANNEL(mCacheInfoChannel)
   NS_FORWARD_SAFE_NSICACHINGCHANNEL(mCachingChannel)
   NS_FORWARD_SAFE_NSIAPPLICATIONCACHECHANNEL(mApplicationCacheChannel)
   NS_FORWARD_SAFE_NSIAPPLICATIONCACHECONTAINER(mApplicationCacheChannel)
   NS_FORWARD_SAFE_NSIUPLOADCHANNEL(mUploadChannel)
   NS_FORWARD_SAFE_NSIFORMPOSTACTIONCHANNEL(mPostChannel)
   NS_FORWARD_SAFE_NSIHTTPCHANNELINTERNAL(mHttpChannelInternal)
 
   // nsViewSourceChannel methods:
   nsViewSourceChannel()
-      : mIsDocument(false), mOpened(false), mIsSrcdocChannel(false) {}
+      : mIsDocument(false),
+        mOpened(false),
+        mIsSrcdocChannel(false),
+        mReplaceRequest(true) {}
 
   MOZ_MUST_USE nsresult Init(nsIURI* uri, nsILoadInfo* aLoadInfo);
 
   MOZ_MUST_USE nsresult InitSrcdoc(nsIURI* aURI, nsIURI* aBaseURI,
                                    const nsAString& aSrcdoc,
                                    nsILoadInfo* aLoadInfo);
 
   // Updates or sets the result principal URI of the underlying channel's
@@ -89,11 +89,12 @@ class nsViewSourceChannel final : public
   nsCOMPtr<nsIChildChannel> mChildChannel;
   nsCOMPtr<nsIStreamListener> mListener;
   nsCOMPtr<nsIURI> mOriginalURI;
   nsCOMPtr<nsIURI> mBaseURI;
   nsCString mContentType;
   bool mIsDocument;  // keeps track of the LOAD_DOCUMENT_URI flag
   bool mOpened;
   bool mIsSrcdocChannel;
+  bool mReplaceRequest;
 };
 
 #endif /* nsViewSourceChannel_h___ */