Bug 1391693 P12 Propagate creation and start times to InterceptedHttpChannel from original channel. r=valentin
authorBen Kelly <ben@wanderview.com>
Mon, 09 Oct 2017 10:03:42 -0700
changeset 427729 cdf9bc83b20d877a7a594763f752876e4c4a7e4b
parent 427728 8d6980bc060117d9b6f363f66657db1ff1aedf17
child 427730 bb1c5e40c33aa16f7a9443d81ab551376ad9a50e
push id97
push userfmarier@mozilla.com
push dateSat, 14 Oct 2017 01:12:59 +0000
reviewersvalentin
bugs1391693
milestone58.0a1
Bug 1391693 P12 Propagate creation and start times to InterceptedHttpChannel from original channel. r=valentin
netwerk/protocol/http/InterceptedHttpChannel.cpp
netwerk/protocol/http/InterceptedHttpChannel.h
netwerk/protocol/http/nsHttpChannel.cpp
--- a/netwerk/protocol/http/InterceptedHttpChannel.cpp
+++ b/netwerk/protocol/http/InterceptedHttpChannel.cpp
@@ -16,27 +16,33 @@ NS_IMPL_ISUPPORTS_INHERITED(InterceptedH
                             nsIInterceptedChannel,
                             nsIAsyncVerifyRedirectCallback,
                             nsIRequestObserver,
                             nsIStreamListener,
                             nsIChannelWithDivertableParentListener,
                             nsIThreadRetargetableRequest,
                             nsIThreadRetargetableStreamListener)
 
-InterceptedHttpChannel::InterceptedHttpChannel()
+InterceptedHttpChannel::InterceptedHttpChannel(PRTime aCreationTime,
+                                               const TimeStamp& aCreationTimestamp,
+                                               const TimeStamp& aAsyncOpenTimestamp)
   : HttpAsyncAborter<InterceptedHttpChannel>(this)
   , mProgress(0)
   , mProgressReported(0)
   , mSynthesizedStreamLength(-1)
   , mResumeStartPos(0)
   , mSynthesizedOrReset(Invalid)
   , mCallingStatusAndProgress(false)
 {
-  mChannelCreationTime = PR_Now();
-  mChannelCreationTimestamp = TimeStamp::Now();
+  // Pre-set the creation and AsyncOpen times based on the original channel
+  // we are intercepting.  We don't want our extra internal redirect to mask
+  // any time spent processing the channel.
+  mChannelCreationTime = aCreationTime;
+  mChannelCreationTimestamp = aCreationTimestamp;
+  mAsyncOpenTime = aAsyncOpenTimestamp;
 }
 
 void
 InterceptedHttpChannel::ReleaseListeners()
 {
   if (mLoadGroup) {
     mLoadGroup->RemoveRequest(this, nullptr, mStatus);
   }
@@ -160,17 +166,19 @@ InterceptedHttpChannel::RedirectForOpaqu
   // the given cross-origin response URL.  The resulting channel will then
   // process the synthetic response as normal.  This extra redirect is
   // performed so that listeners treat the result as unsafe cross-origin
   // data.
 
   nsresult rv = NS_OK;
 
   RefPtr<InterceptedHttpChannel> newChannel =
-    CreateForSynthesis(mResponseHead, mBodyReader);
+    CreateForSynthesis(mResponseHead, mBodyReader,
+                       mChannelCreationTime, mChannelCreationTimestamp,
+                       mAsyncOpenTime);
 
   rv = newChannel->Init(aResponseURI, mCaps,
                         static_cast<nsProxyInfo*>(mProxyInfo.get()),
                         mProxyResolveFlags, mProxyURI, mChannelId);
 
   uint32_t flags = nsIChannelEventSink::REDIRECT_INTERNAL;
 
   nsCOMPtr<nsILoadInfo> redirectLoadInfo =
@@ -324,36 +332,47 @@ InterceptedHttpChannel::MaybeCallStatusA
   mProgressSink->OnProgress(this, mListenerContext, progress,
                             mSynthesizedStreamLength);
 
   mProgressReported = progress;
 }
 
 // static
 already_AddRefed<InterceptedHttpChannel>
-InterceptedHttpChannel::CreateForInterception()
+InterceptedHttpChannel::CreateForInterception(PRTime aCreationTime,
+                                              const TimeStamp& aCreationTimestamp,
+                                              const TimeStamp& aAsyncOpenTimestamp)
 {
   // Create an InterceptedHttpChannel that will trigger a FetchEvent
   // in a ServiceWorker when opened.
-  RefPtr<InterceptedHttpChannel> ref = new InterceptedHttpChannel();
+  RefPtr<InterceptedHttpChannel> ref =
+    new InterceptedHttpChannel(aCreationTime, aCreationTimestamp,
+                               aAsyncOpenTimestamp);
+
   return ref.forget();
 }
 
 // static
 already_AddRefed<InterceptedHttpChannel>
 InterceptedHttpChannel::CreateForSynthesis(const nsHttpResponseHead* aHead,
-                                           nsIInputStream* aBody)
+                                           nsIInputStream* aBody,
+                                           PRTime aCreationTime,
+                                           const TimeStamp& aCreationTimestamp,
+                                           const TimeStamp& aAsyncOpenTimestamp)
 {
   MOZ_DIAGNOSTIC_ASSERT(aHead);
   MOZ_DIAGNOSTIC_ASSERT(aBody);
 
   // Create an InterceptedHttpChannel that already has a synthesized response.
   // The synthetic response will be processed when opened.  A FetchEvent
   // will not be triggered.
-  RefPtr<InterceptedHttpChannel> ref = new InterceptedHttpChannel();
+  RefPtr<InterceptedHttpChannel> ref =
+    new InterceptedHttpChannel(aCreationTime, aCreationTimestamp,
+                               aAsyncOpenTimestamp);
+
   ref->mBodyReader = aBody;
   ref->mResponseHead = new nsHttpResponseHead(*aHead);
 
   return ref.forget();
 }
 
 NS_IMETHODIMP
 InterceptedHttpChannel::Cancel(nsresult aStatus)
@@ -397,17 +416,22 @@ InterceptedHttpChannel::GetSecurityInfo(
 
 NS_IMETHODIMP
 InterceptedHttpChannel::AsyncOpen(nsIStreamListener* aListener, nsISupports* aContext)
 {
   if (mCanceled) {
     return mStatus;
   }
 
-  mAsyncOpenTime = TimeStamp::Now();
+  // We should have pre-set the AsyncOpen time based on the original channel if
+  // timings are enabled.
+  if (mTimingEnabled) {
+    MOZ_DIAGNOSTIC_ASSERT(!mAsyncOpenTime.IsNull());
+  }
+
   mIsPending = true;
   mListener = aListener;
 
   mResponseCouldBeSynthesized = true;
 
   if (mLoadGroup) {
     mLoadGroup->AddRequest(this, nullptr);
   }
--- a/netwerk/protocol/http/InterceptedHttpChannel.h
+++ b/netwerk/protocol/http/InterceptedHttpChannel.h
@@ -86,17 +86,19 @@ private:
   nsString mStatusHost;
   enum {
     Invalid = 0,
     Synthesized,
     Reset
   } mSynthesizedOrReset;
   Atomic<bool> mCallingStatusAndProgress;
 
-  InterceptedHttpChannel();
+  InterceptedHttpChannel(PRTime aCreationTime,
+                         const TimeStamp& aCreationTimestamp,
+                         const TimeStamp& aAsyncOpenTimestamp);
   ~InterceptedHttpChannel() = default;
 
   virtual void
   ReleaseListeners() override;
 
   virtual MOZ_MUST_USE nsresult
   SetupReplacementChannel(nsIURI *aURI, nsIChannel *aChannel,
                           bool aPreserveMethod,
@@ -117,20 +119,24 @@ private:
   nsresult
   OpenRedirectChannel();
 
   void
   MaybeCallStatusAndProgress();
 
 public:
   static already_AddRefed<InterceptedHttpChannel>
-  CreateForInterception();
+  CreateForInterception(PRTime aCreationTime, const TimeStamp& aCreationTimestamp,
+                        const TimeStamp& aAsyncOpenTimestamp);
 
   static already_AddRefed<InterceptedHttpChannel>
-  CreateForSynthesis(const nsHttpResponseHead* aHead, nsIInputStream* aBody);
+  CreateForSynthesis(const nsHttpResponseHead* aHead, nsIInputStream* aBody,
+                     PRTime aCreationTime,
+                     const TimeStamp& aCreationTimestamp,
+                     const TimeStamp& aAsyncOpenTimestamp);
 
   NS_IMETHOD
   Cancel(nsresult aStatus) override;
 
   NS_IMETHOD
   Suspend(void) override;
 
   NS_IMETHOD
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -9474,17 +9474,19 @@ nsHttpChannel::GetWarningReporter()
 
 nsresult
 nsHttpChannel::RedirectToInterceptedChannel()
 {
     nsCOMPtr<nsINetworkInterceptController> controller;
     GetCallback(controller);
 
     RefPtr<InterceptedHttpChannel> intercepted =
-      InterceptedHttpChannel::CreateForInterception();
+      InterceptedHttpChannel::CreateForInterception(mChannelCreationTime,
+                                                    mChannelCreationTimestamp,
+                                                    mAsyncOpenTime);
 
     nsresult rv =
       intercepted->Init(mURI, mCaps, static_cast<nsProxyInfo*>(mProxyInfo.get()),
                         mProxyResolveFlags, mProxyURI, mChannelId);
 
     nsCOMPtr<nsILoadInfo> redirectLoadInfo =
       CloneLoadInfoForRedirect(mURI, nsIChannelEventSink::REDIRECT_INTERNAL);
     intercepted->SetLoadInfo(redirectLoadInfo);