Bug 1423495 - Part4: Create doc entry form http channel if server timing headers are found for a document load r=baku

Currently, the document entry is created at the first time when some JS code tries to access it. But for the case when server timing headers exist for a document loading channel, we need to create the document entry and save the server timing data in the document entry.
If we don’t do this, the server timing data would be lost since the http channel will be deleted.

MozReview-Commit-ID: B5ksAZvZACq

--HG--
extra : rebase_source : 27bc6284ec417b2ff430a59cd9eeddc56b7a77ac
This commit is contained in:
Kershaw Chang ext:(%2C%20Valentin%20Gosu%20%3Cvalentin.gosu%40gmail.com%3E) 2018-01-12 03:13:00 +01:00
parent 0aa410f629
commit 042ac19155
9 changed files with 52 additions and 17 deletions

View File

@ -297,6 +297,20 @@ PerformanceMainThread::EnsureDocEntry()
}
}
void
PerformanceMainThread::CreateDocumentEntry(nsITimedChannel* aChannel)
{
MOZ_ASSERT(aChannel);
MOZ_ASSERT(!mDocEntry, "mDocEntry should be null.");
if (!nsContentUtils::IsPerformanceNavigationTimingEnabled()) {
return;
}
UniquePtr<PerformanceTimingData> timing(
new PerformanceTimingData(aChannel, nullptr, 0));
mDocEntry = new PerformanceNavigationTiming(Move(timing), this);
}
void
PerformanceMainThread::GetEntries(nsTArray<RefPtr<PerformanceEntry>>& aRetval)

View File

@ -37,6 +37,8 @@ public:
virtual void AddEntry(nsIHttpChannel* channel,
nsITimedChannel* timedChannel) override;
void CreateDocumentEntry(nsITimedChannel* aChannel) override;
TimeStamp CreationTimeStamp() const override;
DOMHighResTimeStamp CreationTime() const override;

View File

@ -25,6 +25,8 @@ public:
virtual void AddEntry(nsIHttpChannel* aChannel,
nsITimedChannel* aTimedChannel) = 0;
virtual void CreateDocumentEntry(nsITimedChannel* aChannel) = 0;
protected:
virtual ~PerformanceStorage() {}
};

View File

@ -30,6 +30,11 @@ public:
void AddEntry(nsIHttpChannel* aChannel,
nsITimedChannel* aTimedChannel) override;
void CreateDocumentEntry(nsITimedChannel* aChannel) override
{
MOZ_CRASH("This should not be called on workers.");
}
void AddEntryOnWorker(UniquePtr<PerformanceProxyData>&& aData);
private:

View File

@ -4250,11 +4250,6 @@ HttpBaseChannel::GetPerformanceStorage()
return performanceStorage;
}
// We don't need to report the resource timing entry for a TYPE_DOCUMENT load.
if (mLoadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_DOCUMENT) {
return nullptr;
}
nsCOMPtr<nsIDOMDocument> domDocument;
mLoadInfo->GetLoadingDocument(getter_AddRefs(domDocument));
if (!domDocument) {
@ -4287,6 +4282,31 @@ HttpBaseChannel::GetPerformanceStorage()
return performance->AsPerformanceStorage();
}
void
HttpBaseChannel::MaybeReportTimingData()
{
// We don't need to report the resource timing entry for a TYPE_DOCUMENT load.
// But for the case that Server-Timing headers are existed for
// a document load, we have to create the document entry early
// with the timed channel. This is the only way to make
// server timing data availeble in the document entry.
if (mLoadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_DOCUMENT) {
if ((mResponseHead && mResponseHead->HasHeader(nsHttp::Server_Timing)) ||
(mResponseTrailers && mResponseTrailers->HasHeader(nsHttp::Server_Timing))) {
mozilla::dom::PerformanceStorage* documentPerformance = GetPerformanceStorage();
if (documentPerformance) {
documentPerformance->CreateDocumentEntry(this);
}
}
return;
}
mozilla::dom::PerformanceStorage* documentPerformance = GetPerformanceStorage();
if (documentPerformance) {
documentPerformance->AddEntry(this, this);
}
}
NS_IMETHODIMP
HttpBaseChannel::SetReportResourceTiming(bool enabled) {
mReportTiming = enabled;

View File

@ -429,6 +429,7 @@ protected:
void NotifySetCookie(char const *aCookie);
mozilla::dom::PerformanceStorage* GetPerformanceStorage();
void MaybeReportTimingData();
nsIURI* GetReferringPage();
nsPIDOMWindowInner* GetInnerDOMWindow();

View File

@ -1213,10 +1213,7 @@ HttpChannelChild::DoPreOnStopRequest(nsresult aStatus)
MaybeCallSynthesizedCallback();
PerformanceStorage* performanceStorage = GetPerformanceStorage();
if (performanceStorage) {
performanceStorage->AddEntry(this, this);
}
MaybeReportTimingData();
if (!mCanceled && NS_SUCCEEDED(mStatus)) {
mStatus = aStatus;

View File

@ -1084,10 +1084,7 @@ InterceptedHttpChannel::OnStopRequest(nsIRequest* aRequest,
mIsPending = false;
// Register entry to the PerformanceStorage resource timing
mozilla::dom::PerformanceStorage* performanceStorage = GetPerformanceStorage();
if (performanceStorage) {
performanceStorage->AddEntry(this, this);
}
MaybeReportTimingData();
if (mListener) {
mListener->OnStopRequest(this, mListenerContext, mStatus);

View File

@ -7431,10 +7431,7 @@ nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult st
ReportRcwnStats(isFromNet);
// Register entry to the PerformanceStorage resource timing
mozilla::dom::PerformanceStorage* performanceStorage = GetPerformanceStorage();
if (performanceStorage) {
performanceStorage->AddEntry(this, this);
}
MaybeReportTimingData();
if (mListener) {
LOG(("nsHttpChannel %p calling OnStopRequest\n", this));