Bug 1528188 - Get the HttpChannelParentListener via the parent r=mayhemer
authorValentin Gosu <valentin.gosu@gmail.com>
Mon, 18 Feb 2019 21:37:44 +0000
changeset 459812 bc1a5ca9464b2342b79ad1642b6fbe51139916e7
parent 459811 2299664d9a0b83229ed527ca3e5c43452e69ab2a
child 459813 56992c2597a4b318ce074061d916444029a8e4e8
push id35574
push usercbrindusan@mozilla.com
push dateTue, 19 Feb 2019 04:38:09 +0000
treeherdermozilla-central@8231f78228bc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmayhemer
bugs1528188
milestone67.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 1528188 - Get the HttpChannelParentListener via the parent r=mayhemer Differential Revision: https://phabricator.services.mozilla.com/D20184
netwerk/protocol/http/HttpChannelParent.cpp
netwerk/protocol/http/HttpChannelParent.h
netwerk/protocol/http/nsHttpChannel.cpp
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -2010,16 +2010,22 @@ void HttpChannelParent::CancelChildCross
   MOZ_ASSERT(NS_IsMainThread());
 
   mDoingCrossProcessRedirect = true;
   if (!mIPCClosed) {
     Unused << SendCancelRedirected();
   }
 }
 
+already_AddRefed<HttpChannelParentListener>
+HttpChannelParent::GetParentListener() {
+  RefPtr<HttpChannelParentListener> listener = mParentListener;
+  return listener.forget();
+}
+
 NS_IMETHODIMP
 HttpChannelParent::CompleteRedirect(bool succeeded) {
   LOG(("HttpChannelParent::CompleteRedirect [this=%p succeeded=%d]\n", this,
        succeeded));
 
   if (mDoingCrossProcessRedirect) {
     LOG(("Child was cancelled for cross-process redirect. Bail."));
     return NS_OK;
--- a/netwerk/protocol/http/HttpChannelParent.h
+++ b/netwerk/protocol/http/HttpChannelParent.h
@@ -124,16 +124,18 @@ class HttpChannelParent final : public n
   base::ProcessId OtherPid() const override;
 
   // Calling this method will cancel the HttpChannelChild because the consumer
   // needs to be relocated to another process.
   // Any OnStart/Stop/DataAvailable calls that follow will not be sent to the
   // child channel.
   void CancelChildCrossProcessRedirect();
 
+  already_AddRefed<HttpChannelParentListener> GetParentListener();
+
  protected:
   // used to connect redirected-to channel in parent with just created
   // ChildChannel.  Used during redirects.
   MOZ_MUST_USE bool ConnectChannel(const uint32_t& channelId,
                                    const bool& shouldIntercept);
 
   MOZ_MUST_USE bool DoAsyncOpen(
       const URIParams& uri, const OptionalURIParams& originalUri,
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -7126,18 +7126,30 @@ NS_IMETHODIMP nsHttpChannel::SwitchProce
 nsresult nsHttpChannel::StartCrossProcessRedirect() {
   nsresult rv;
 
   LOG(("nsHttpChannel::StartCrossProcessRedirect [this=%p]", this));
 
   rv = CheckRedirectLimit(nsIChannelEventSink::REDIRECT_INTERNAL);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  RefPtr<HttpChannelParentListener> listener = do_QueryObject(mCallbacks);
+  // We can't do QueryObject mCallbacks into HttpChannelParentListener, because
+  // the notification callbacks can be replaced with another object.
+  // Rather we do GetInterface for HttpChannelParent, which should always be
+  // there if the new callbacks properly forward to the original channel's
+  // callbacks, and get the listener from there using QueryObject.
+  nsCOMPtr<nsIParentChannel> parentChannel;
+  NS_QueryNotificationCallbacks(this, parentChannel);
+  RefPtr<HttpChannelParent> httpParent = do_QueryObject(parentChannel);
+  MOZ_ASSERT(httpParent);
+  NS_ENSURE_TRUE(httpParent, NS_ERROR_UNEXPECTED);
+
+  RefPtr<HttpChannelParentListener> listener = httpParent->GetParentListener();
   MOZ_ASSERT(listener);
+  NS_ENSURE_TRUE(listener, NS_ERROR_UNEXPECTED);
 
   nsCOMPtr<nsILoadInfo> redirectLoadInfo =
       CloneLoadInfoForRedirect(mURI, nsIChannelEventSink::REDIRECT_INTERNAL);
 
   listener->TriggerCrossProcessRedirect(this, redirectLoadInfo,
                                         mCrossProcessRedirectIdentifier);
 
   // This will suspend the channel