Bug 1413999 - Part3: IPC part, send trailers to child process r=dragana
authorKershaw Chang <kechang@mozilla.com>
Wed, 03 Jan 2018 02:05:00 +0200
changeset 449529 c29cf020715fafc192c31713abc42db87f91dc13
parent 449528 c92b27c7f6bd143650616f438961c3bbe5c7f8dd
child 449530 d6ad893078b23c1a2c546ca7b1509013fa10e89e
push id8527
push userCallek@gmail.com
push dateThu, 11 Jan 2018 21:05:50 +0000
treeherdermozilla-beta@95342d212a7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdragana
bugs1413999
milestone59.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 1413999 - Part3: IPC part, send trailers to child process r=dragana The aim of this patch is to send trailers to child process via SendOnStopRequest.
netwerk/protocol/http/HttpBackgroundChannelChild.cpp
netwerk/protocol/http/HttpBackgroundChannelChild.h
netwerk/protocol/http/HttpBackgroundChannelParent.cpp
netwerk/protocol/http/HttpBackgroundChannelParent.h
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelChild.h
netwerk/protocol/http/HttpChannelParent.cpp
netwerk/protocol/http/PHttpBackgroundChannel.ipdl
--- a/netwerk/protocol/http/HttpBackgroundChannelChild.cpp
+++ b/netwerk/protocol/http/HttpBackgroundChannelChild.cpp
@@ -174,19 +174,20 @@ HttpBackgroundChannelChild::RecvOnTransp
                                            aCount,
                                            aData);
 
   return IPC_OK();
 }
 
 IPCResult
 HttpBackgroundChannelChild::RecvOnStopRequest(
-                                            const nsresult& aChannelStatus,
-                                            const ResourceTimingStruct& aTiming,
-                                            const TimeStamp& aLastActiveTabOptHit)
+                                    const nsresult& aChannelStatus,
+                                    const ResourceTimingStruct& aTiming,
+                                    const TimeStamp& aLastActiveTabOptHit,
+                                    const nsHttpHeaderArray& aResponseTrailers)
 {
   LOG(("HttpBackgroundChannelChild::RecvOnStopRequest [this=%p]\n", this));
   MOZ_ASSERT(OnSocketThread());
 
   // It's enough to set this from (just before) OnStopRequest notification, since
   // we don't need this value sooner than a channel was done loading - everything
   // this timestamp affects takes place only after a channel's OnStopRequest.
   nsHttp::SetLastActiveTabLoadOptimizationHit(aLastActiveTabOptHit);
@@ -195,28 +196,32 @@ HttpBackgroundChannelChild::RecvOnStopRe
     return IPC_OK();
   }
 
   if (IsWaitingOnStartRequest()) {
     LOG(("  > pending until OnStartRequest [status=%" PRIx32 "]\n",
          static_cast<uint32_t>(aChannelStatus)));
 
     mQueuedRunnables.AppendElement(
-      NewRunnableMethod<const nsresult, const ResourceTimingStruct, const TimeStamp>(
+      NewRunnableMethod<const nsresult,
+                        const ResourceTimingStruct,
+                        const TimeStamp,
+                        const nsHttpHeaderArray>(
         "HttpBackgroundChannelChild::RecvOnStopRequest",
         this,
         &HttpBackgroundChannelChild::RecvOnStopRequest,
         aChannelStatus,
         aTiming,
-        aLastActiveTabOptHit));
+        aLastActiveTabOptHit,
+        aResponseTrailers));
 
     return IPC_OK();
   }
 
-  mChannelChild->ProcessOnStopRequest(aChannelStatus, aTiming);
+  mChannelChild->ProcessOnStopRequest(aChannelStatus, aTiming, aResponseTrailers);
 
   return IPC_OK();
 }
 
 IPCResult
 HttpBackgroundChannelChild::RecvOnProgress(const int64_t& aProgress,
                                            const int64_t& aProgressMax)
 {
--- a/netwerk/protocol/http/HttpBackgroundChannelChild.h
+++ b/netwerk/protocol/http/HttpBackgroundChannelChild.h
@@ -44,17 +44,18 @@ protected:
   IPCResult RecvOnTransportAndData(const nsresult& aChannelStatus,
                                    const nsresult& aTransportStatus,
                                    const uint64_t& aOffset,
                                    const uint32_t& aCount,
                                    const nsCString& aData) override;
 
   IPCResult RecvOnStopRequest(const nsresult& aChannelStatus,
                               const ResourceTimingStruct& aTiming,
-                              const TimeStamp& aLastActiveTabOptHit) override;
+                              const TimeStamp& aLastActiveTabOptHit,
+                              const nsHttpHeaderArray& aResponseTrailers) override;
 
   IPCResult RecvOnProgress(const int64_t& aProgress,
                            const int64_t& aProgressMax) override;
 
   IPCResult RecvOnStatus(const nsresult& aStatus) override;
 
   IPCResult RecvFlushedForDiversion() override;
 
--- a/netwerk/protocol/http/HttpBackgroundChannelParent.cpp
+++ b/netwerk/protocol/http/HttpBackgroundChannelParent.cpp
@@ -215,46 +215,50 @@ HttpBackgroundChannelParent::OnTransport
   }
 
   return SendOnTransportAndData(aChannelStatus, aTransportStatus,
                                 aOffset, aCount, aData);
 }
 
 bool
 HttpBackgroundChannelParent::OnStopRequest(const nsresult& aChannelStatus,
-                                           const ResourceTimingStruct& aTiming)
+                                           const ResourceTimingStruct& aTiming,
+                                           const nsHttpHeaderArray& aResponseTrailers)
 {
   LOG(("HttpBackgroundChannelParent::OnStopRequest [this=%p "
         "status=%" PRIx32 "]\n", this, static_cast<uint32_t>(aChannelStatus)));
   AssertIsInMainProcess();
 
   if (NS_WARN_IF(!mIPCOpened)) {
     return false;
   }
 
   if (!IsOnBackgroundThread()) {
     MutexAutoLock lock(mBgThreadMutex);
     nsresult rv = mBackgroundThread->Dispatch(
-      NewRunnableMethod<const nsresult, const ResourceTimingStruct>(
+      NewRunnableMethod<const nsresult,
+                        const ResourceTimingStruct,
+                        const nsHttpHeaderArray>(
         "net::HttpBackgroundChannelParent::OnStopRequest",
         this,
         &HttpBackgroundChannelParent::OnStopRequest,
         aChannelStatus,
-        aTiming),
+        aTiming,
+        aResponseTrailers),
       NS_DISPATCH_NORMAL);
 
     MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
 
     return NS_SUCCEEDED(rv);
   }
 
   // See the child code for why we do this.
   TimeStamp lastActTabOpt = nsHttp::GetLastActiveTabLoadOptimizationHit();
 
-  return SendOnStopRequest(aChannelStatus, aTiming, lastActTabOpt);
+  return SendOnStopRequest(aChannelStatus, aTiming, lastActTabOpt, aResponseTrailers);
 }
 
 bool
 HttpBackgroundChannelParent::OnProgress(const int64_t& aProgress,
                                         const int64_t& aProgressMax)
 {
   LOG(("HttpBackgroundChannelParent::OnProgress [this=%p progress=%" PRId64
        " max=%" PRId64 "]\n", this, aProgress, aProgressMax));
--- a/netwerk/protocol/http/HttpBackgroundChannelParent.h
+++ b/netwerk/protocol/http/HttpBackgroundChannelParent.h
@@ -47,17 +47,18 @@ public:
   bool OnTransportAndData(const nsresult& aChannelStatus,
                           const nsresult& aTransportStatus,
                           const uint64_t& aOffset,
                           const uint32_t& aCount,
                           const nsCString& aData);
 
   // To send OnStopRequest message over background channel.
   bool OnStopRequest(const nsresult& aChannelStatus,
-                     const ResourceTimingStruct& aTiming);
+                     const ResourceTimingStruct& aTiming,
+                     const nsHttpHeaderArray& aResponseTrailers);
 
   // To send OnProgress message over background channel.
   bool OnProgress(const int64_t& aProgress,
                   const int64_t& aProgressMax);
 
   // To send OnStatus message over background channel.
   bool OnStatus(const nsresult& aStatus);
 
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -974,38 +974,43 @@ HttpChannelChild::DoOnDataAvailable(nsIR
   }
 }
 
 class StopRequestEvent : public NeckoTargetChannelEvent<HttpChannelChild>
 {
  public:
   StopRequestEvent(HttpChannelChild* child,
                    const nsresult& channelStatus,
-                   const ResourceTimingStruct& timing)
+                   const ResourceTimingStruct& timing,
+                   const nsHttpHeaderArray& aResponseTrailers)
   : NeckoTargetChannelEvent<HttpChannelChild>(child)
   , mChannelStatus(channelStatus)
-  , mTiming(timing) {}
-
-  void Run() { mChild->OnStopRequest(mChannelStatus, mTiming); }
+  , mTiming(timing)
+  , mResponseTrailers(aResponseTrailers) {}
+
+  void Run() { mChild->OnStopRequest(mChannelStatus, mTiming, mResponseTrailers); }
 
  private:
   nsresult mChannelStatus;
   ResourceTimingStruct mTiming;
+  nsHttpHeaderArray mResponseTrailers;
 };
 
 void
 HttpChannelChild::ProcessOnStopRequest(const nsresult& aChannelStatus,
-                                       const ResourceTimingStruct& aTiming)
+                                       const ResourceTimingStruct& aTiming,
+                                       const nsHttpHeaderArray& aResponseTrailers)
 {
   LOG(("HttpChannelChild::ProcessOnStopRequest [this=%p]\n", this));
   MOZ_ASSERT(OnSocketThread());
   MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
     "Should not be receiving any more callbacks from parent!");
 
-  mEventQ->RunOrEnqueue(new StopRequestEvent(this, aChannelStatus, aTiming),
+  mEventQ->RunOrEnqueue(new StopRequestEvent(this, aChannelStatus,
+                                             aTiming, aResponseTrailers),
                         mDivertingToParent);
 }
 
 class MaybeDivertOnStopHttpEvent : public NeckoTargetChannelEvent<HttpChannelChild>
 {
  public:
   MaybeDivertOnStopHttpEvent(HttpChannelChild* child,
                              const nsresult& channelStatus)
@@ -1031,17 +1036,18 @@ HttpChannelChild::MaybeDivertOnStop(cons
        static_cast<uint32_t>(aChannelStatus)));
   if (mDivertingToParent) {
     SendDivertOnStopRequest(aChannelStatus);
   }
 }
 
 void
 HttpChannelChild::OnStopRequest(const nsresult& channelStatus,
-                                const ResourceTimingStruct& timing)
+                                const ResourceTimingStruct& timing,
+                                const nsHttpHeaderArray& aResponseTrailers)
 {
   LOG(("HttpChannelChild::OnStopRequest [this=%p status=%" PRIx32 "]\n",
        this, static_cast<uint32_t>(channelStatus)));
   MOZ_ASSERT(NS_IsMainThread());
 
   if (mDivertingToParent) {
     MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
       "Should not be processing any more callbacks from parent!");
@@ -1084,16 +1090,18 @@ HttpChannelChild::OnStopRequest(const ns
   mRedirectEndTimeStamp = timing.redirectEnd;
   mTransferSize = timing.transferSize;
   mEncodedBodySize = timing.encodedBodySize;
   mProtocolVersion = timing.protocolVersion;
 
   mCacheReadStart = timing.cacheReadStart;
   mCacheReadEnd = timing.cacheReadEnd;
 
+  mResponseTrailers = new nsHttpHeaderArray(aResponseTrailers);
+
   DoPreOnStopRequest(channelStatus);
 
   { // We must flush the queue before we Send__delete__
     // (although we really shouldn't receive any msgs after OnStop),
     // so make sure this goes out of scope before then.
     AutoEventEnqueuer ensureSerialDispatch(mEventQ);
 
     DoOnStopRequest(this, channelStatus, mListenerContext);
--- a/netwerk/protocol/http/HttpChannelChild.h
+++ b/netwerk/protocol/http/HttpChannelChild.h
@@ -237,17 +237,18 @@ private:
   // Callbacks while receiving OnTransportAndData/OnStopRequest/OnProgress/
   // OnStatus/FlushedForDiversion/DivertMessages on background IPC channel.
   void ProcessOnTransportAndData(const nsresult& aChannelStatus,
                                  const nsresult& aStatus,
                                  const uint64_t& aOffset,
                                  const uint32_t& aCount,
                                  const nsCString& aData);
   void ProcessOnStopRequest(const nsresult& aStatusCode,
-                            const ResourceTimingStruct& aTiming);
+                            const ResourceTimingStruct& aTiming,
+                            const nsHttpHeaderArray& aResponseTrailers);
   void ProcessOnProgress(const int64_t& aProgress, const int64_t& aProgressMax);
   void ProcessOnStatus(const nsresult& aStatus);
   void ProcessFlushedForDiversion();
   void ProcessDivertMessages();
   void ProcessNotifyTrackingProtectionDisabled();
   void ProcessNotifyTrackingResource();
   void ProcessSetClassifierMatchedInfo(const nsCString& aList,
                                        const nsCString& aProvider,
@@ -410,17 +411,19 @@ private:
   void MaybeDivertOnData(const nsCString& data,
                          const uint64_t& offset,
                          const uint32_t& count);
   void OnTransportAndData(const nsresult& channelStatus,
                           const nsresult& status,
                           const uint64_t& offset,
                           const uint32_t& count,
                           const nsCString& data);
-  void OnStopRequest(const nsresult& channelStatus, const ResourceTimingStruct& timing);
+  void OnStopRequest(const nsresult& channelStatus,
+                     const ResourceTimingStruct& timing,
+                     const nsHttpHeaderArray& aResponseTrailers);
   void MaybeDivertOnStop(const nsresult& aChannelStatus);
   void OnProgress(const int64_t& progress, const int64_t& progressMax);
   void OnStatus(const nsresult& status);
   void FailedAsyncOpen(const nsresult& status);
   void HandleAsyncAbort();
   void Redirect1Begin(const uint32_t& registrarId,
                       const URIParams& newUri,
                       const uint32_t& redirectFlags,
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -1591,22 +1591,26 @@ HttpChannelParent::OnStopRequest(nsIRequ
   mChannel->GetCacheReadStart(&timing.cacheReadStart);
   mChannel->GetCacheReadEnd(&timing.cacheReadEnd);
 
   RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(mChannel);
   if (httpChannelImpl) {
     httpChannelImpl->SetWarningReporter(nullptr);
   }
 
+  nsHttpHeaderArray *responseTrailer = mChannel->GetResponseTrailers();
+
   // Either IPC channel is closed or background channel
   // is ready to send OnStopRequest.
   MOZ_ASSERT(mIPCClosed || mBgParent);
 
   if (mIPCClosed ||
-      !mBgParent || !mBgParent->OnStopRequest(aStatusCode, timing)) {
+      !mBgParent ||
+      !mBgParent->OnStopRequest(aStatusCode, timing,
+                                responseTrailer ? *responseTrailer : nsHttpHeaderArray())) {
     return NS_ERROR_UNEXPECTED;
   }
 
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // HttpChannelParent::nsIStreamListener
--- a/netwerk/protocol/http/PHttpBackgroundChannel.ipdl
+++ b/netwerk/protocol/http/PHttpBackgroundChannel.ipdl
@@ -6,16 +6,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include protocol PBackground;
 include NeckoChannelParams;
 include PURLClassifierInfo;
 
 include "mozilla/net/NeckoMessageUtils.h";
 
+using class nsHttpHeaderArray from "nsHttpHeaderArray.h";
 using struct mozilla::net::ResourceTimingStruct from "mozilla/net/TimingStruct.h";
 
 namespace mozilla {
 namespace net {
 
 //-------------------------------------------------------------------
 async protocol PHttpBackgroundChannel
 {
@@ -31,18 +32,20 @@ child:
   // Combines a single OnDataAvailable and its associated OnProgress &
   // OnStatus calls into one IPDL message
   async OnTransportAndData(nsresult  channelStatus,
                            nsresult  transportStatus,
                            uint64_t  offset,
                            uint32_t  count,
                            nsCString data);
 
-  async OnStopRequest(nsresult channelStatus, ResourceTimingStruct timing,
-                      TimeStamp lastActiveTabOptimization);
+  async OnStopRequest(nsresult channelStatus,
+                      ResourceTimingStruct timing,
+                      TimeStamp lastActiveTabOptimization,
+                      nsHttpHeaderArray responseTrailers);
 
   async OnProgress(int64_t progress, int64_t progressMax);
 
   async OnStatus(nsresult status);
 
   // Parent has been suspended for diversion; no more events to be enqueued.
   async FlushedForDiversion();