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
Родитель 0aa410f629
Коммит 042ac19155
9 изменённых файлов: 52 добавлений и 17 удалений

Просмотреть файл

@ -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)

Просмотреть файл

@ -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;

Просмотреть файл

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

Просмотреть файл

@ -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:

Просмотреть файл

@ -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;

Просмотреть файл

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

Просмотреть файл

@ -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;

Просмотреть файл

@ -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);

Просмотреть файл

@ -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));