Bug 1064706 - Save timing info in nsPerformanceTiming to avoid keeping a ref to the channel r=bz

This commit is contained in:
Valentin Gosu 2014-10-21 15:49:40 +03:00
Родитель 6e415f1825
Коммит 79c0bcd432
2 изменённых файлов: 75 добавлений и 63 удалений

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

@ -33,10 +33,12 @@ nsPerformanceTiming::nsPerformanceTiming(nsPerformance* aPerformance,
nsIHttpChannel* aHttpChannel,
DOMHighResTimeStamp aZeroTime)
: mPerformance(aPerformance),
mChannel(aChannel),
mFetchStart(0.0),
mZeroTime(aZeroTime),
mRedirectCount(0),
mTimingAllowed(true),
mAllRedirectsSameOrigin(true),
mInitialized(!!aChannel),
mReportCrossOriginRedirect(true)
{
MOZ_ASSERT(aPerformance, "Parent performance object should be provided");
@ -49,11 +51,36 @@ nsPerformanceTiming::nsPerformanceTiming(nsPerformance* aPerformance,
// is being used for the navigation timing (document) and has a non-null
// value for the resource timing (any resources within the page).
if (aHttpChannel) {
mTimingAllowed = CheckAllowedOrigin(aHttpChannel);
mTimingAllowed = CheckAllowedOrigin(aHttpChannel, aChannel);
bool redirectsPassCheck = false;
mChannel->GetAllRedirectsPassTimingAllowCheck(&redirectsPassCheck);
aChannel->GetAllRedirectsPassTimingAllowCheck(&redirectsPassCheck);
mReportCrossOriginRedirect = mTimingAllowed && redirectsPassCheck;
}
InitializeTimingInfo(aChannel);
}
// Copy the timing info from the channel so we don't need to keep the channel
// alive just to get the timestamps.
void
nsPerformanceTiming::InitializeTimingInfo(nsITimedChannel* aChannel)
{
if (aChannel) {
aChannel->GetAsyncOpen(&mAsyncOpen);
aChannel->GetAllRedirectsSameOrigin(&mAllRedirectsSameOrigin);
aChannel->GetRedirectCount(&mRedirectCount);
aChannel->GetRedirectStart(&mRedirectStart);
aChannel->GetRedirectEnd(&mRedirectEnd);
aChannel->GetDomainLookupStart(&mDomainLookupStart);
aChannel->GetDomainLookupEnd(&mDomainLookupEnd);
aChannel->GetConnectStart(&mConnectStart);
aChannel->GetConnectEnd(&mConnectEnd);
aChannel->GetRequestStart(&mRequestStart);
aChannel->GetResponseStart(&mResponseStart);
aChannel->GetCacheReadStart(&mCacheReadStart);
aChannel->GetResponseEnd(&mResponseEnd);
aChannel->GetCacheReadEnd(&mCacheReadEnd);
}
}
nsPerformanceTiming::~nsPerformanceTiming()
@ -67,12 +94,10 @@ nsPerformanceTiming::FetchStartHighRes()
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
return mZeroTime;
}
TimeStamp stamp;
mChannel->GetAsyncOpen(&stamp);
MOZ_ASSERT(!stamp.IsNull(), "The fetch start time stamp should always be "
MOZ_ASSERT(!mAsyncOpen.IsNull(), "The fetch start time stamp should always be "
"valid if the performance timing is enabled");
mFetchStart = (!stamp.IsNull())
? TimeStampToDOMHighRes(stamp)
mFetchStart = (!mAsyncOpen.IsNull())
? TimeStampToDOMHighRes(mAsyncOpen)
: 0.0;
}
return mFetchStart;
@ -85,7 +110,8 @@ nsPerformanceTiming::FetchStart()
}
bool
nsPerformanceTiming::CheckAllowedOrigin(nsIHttpChannel* aResourceChannel)
nsPerformanceTiming::CheckAllowedOrigin(nsIHttpChannel* aResourceChannel,
nsITimedChannel* aChannel)
{
if (!IsInitialized()) {
return false;
@ -102,7 +128,7 @@ nsPerformanceTiming::CheckAllowedOrigin(nsIHttpChannel* aResourceChannel)
// Check if the resource is either same origin as the page that started
// the load, or if the response contains the proper Timing-Allow-Origin
// header with the domain of the page that started the load.
return mChannel->TimingAllowCheck(principal);
return aChannel->TimingAllowCheck(principal);
}
bool
@ -117,14 +143,10 @@ nsPerformanceTiming::GetRedirectCount() const
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
return 0;
}
bool sameOrigin;
mChannel->GetAllRedirectsSameOrigin(&sameOrigin);
if (!sameOrigin) {
if (!mAllRedirectsSameOrigin) {
return 0;
}
uint16_t redirectCount;
mChannel->GetRedirectCount(&redirectCount);
return redirectCount;
return mRedirectCount;
}
bool
@ -137,9 +159,7 @@ nsPerformanceTiming::ShouldReportCrossOriginRedirect() const
// If the redirect count is 0, or if one of the cross-origin
// redirects doesn't have the proper Timing-Allow-Origin header,
// then RedirectStart and RedirectEnd will be set to zero
uint16_t redirectCount;
mChannel->GetRedirectCount(&redirectCount);
return (redirectCount != 0) && mReportCrossOriginRedirect;
return (mRedirectCount != 0) && mReportCrossOriginRedirect;
}
/**
@ -158,9 +178,7 @@ nsPerformanceTiming::RedirectStartHighRes()
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
return mZeroTime;
}
mozilla::TimeStamp stamp;
mChannel->GetRedirectStart(&stamp);
return TimeStampToDOMHighResOrFetchStart(stamp);
return TimeStampToDOMHighResOrFetchStart(mRedirectStart);
}
DOMTimeMilliSec
@ -171,9 +189,7 @@ nsPerformanceTiming::RedirectStart()
}
// We have to check if all the redirect URIs had the same origin (since there
// is no check in RedirectStartHighRes())
bool sameOrigin;
mChannel->GetAllRedirectsSameOrigin(&sameOrigin);
if (sameOrigin) {
if (mAllRedirectsSameOrigin) {
return static_cast<int64_t>(RedirectStartHighRes());
}
return 0;
@ -195,9 +211,7 @@ nsPerformanceTiming::RedirectEndHighRes()
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
return mZeroTime;
}
mozilla::TimeStamp stamp;
mChannel->GetRedirectEnd(&stamp);
return TimeStampToDOMHighResOrFetchStart(stamp);
return TimeStampToDOMHighResOrFetchStart(mRedirectEnd);
}
DOMTimeMilliSec
@ -208,9 +222,7 @@ nsPerformanceTiming::RedirectEnd()
}
// We have to check if all the redirect URIs had the same origin (since there
// is no check in RedirectEndHighRes())
bool sameOrigin;
mChannel->GetAllRedirectsSameOrigin(&sameOrigin);
if (sameOrigin) {
if (mAllRedirectsSameOrigin) {
return static_cast<int64_t>(RedirectEndHighRes());
}
return 0;
@ -222,9 +234,7 @@ nsPerformanceTiming::DomainLookupStartHighRes()
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
return mZeroTime;
}
mozilla::TimeStamp stamp;
mChannel->GetDomainLookupStart(&stamp);
return TimeStampToDOMHighResOrFetchStart(stamp);
return TimeStampToDOMHighResOrFetchStart(mDomainLookupStart);
}
DOMTimeMilliSec
@ -239,9 +249,7 @@ nsPerformanceTiming::DomainLookupEndHighRes()
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
return mZeroTime;
}
mozilla::TimeStamp stamp;
mChannel->GetDomainLookupEnd(&stamp);
return TimeStampToDOMHighResOrFetchStart(stamp);
return TimeStampToDOMHighResOrFetchStart(mDomainLookupEnd);
}
DOMTimeMilliSec
@ -256,9 +264,7 @@ nsPerformanceTiming::ConnectStartHighRes()
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
return mZeroTime;
}
mozilla::TimeStamp stamp;
mChannel->GetConnectStart(&stamp);
return TimeStampToDOMHighResOrFetchStart(stamp);
return TimeStampToDOMHighResOrFetchStart(mConnectStart);
}
DOMTimeMilliSec
@ -273,9 +279,7 @@ nsPerformanceTiming::ConnectEndHighRes()
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
return mZeroTime;
}
mozilla::TimeStamp stamp;
mChannel->GetConnectEnd(&stamp);
return TimeStampToDOMHighResOrFetchStart(stamp);
return TimeStampToDOMHighResOrFetchStart(mConnectEnd);
}
DOMTimeMilliSec
@ -290,9 +294,7 @@ nsPerformanceTiming::RequestStartHighRes()
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
return mZeroTime;
}
mozilla::TimeStamp stamp;
mChannel->GetRequestStart(&stamp);
return TimeStampToDOMHighResOrFetchStart(stamp);
return TimeStampToDOMHighResOrFetchStart(mRequestStart);
}
DOMTimeMilliSec
@ -307,14 +309,11 @@ nsPerformanceTiming::ResponseStartHighRes()
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
return mZeroTime;
}
mozilla::TimeStamp stamp;
mChannel->GetResponseStart(&stamp);
mozilla::TimeStamp cacheStamp;
mChannel->GetCacheReadStart(&cacheStamp);
if (stamp.IsNull() || (!cacheStamp.IsNull() && cacheStamp < stamp)) {
stamp = cacheStamp;
if (mResponseStart.IsNull() ||
(!mCacheReadStart.IsNull() && mCacheReadStart < mResponseStart)) {
mResponseStart = mCacheReadStart;
}
return TimeStampToDOMHighResOrFetchStart(stamp);
return TimeStampToDOMHighResOrFetchStart(mResponseStart);
}
DOMTimeMilliSec
@ -329,14 +328,11 @@ nsPerformanceTiming::ResponseEndHighRes()
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
return mZeroTime;
}
mozilla::TimeStamp stamp;
mChannel->GetResponseEnd(&stamp);
mozilla::TimeStamp cacheStamp;
mChannel->GetCacheReadEnd(&cacheStamp);
if (stamp.IsNull() || (!cacheStamp.IsNull() && cacheStamp < stamp)) {
stamp = cacheStamp;
if (mResponseEnd.IsNull() ||
(!mCacheReadEnd.IsNull() && mCacheReadEnd < mResponseEnd)) {
mResponseEnd = mCacheReadEnd;
}
return TimeStampToDOMHighResOrFetchStart(stamp);
return TimeStampToDOMHighResOrFetchStart(mResponseEnd);
}
DOMTimeMilliSec
@ -348,7 +344,7 @@ nsPerformanceTiming::ResponseEnd()
bool
nsPerformanceTiming::IsInitialized() const
{
return !!mChannel;
return mInitialized;
}
JSObject*

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

@ -142,7 +142,7 @@ public:
// Checks if the resource is either same origin as the page that started
// the load, or if the response contains the Timing-Allow-Origin header
// with a value of * or matching the domain of the loading Principal
bool CheckAllowedOrigin(nsIHttpChannel* aResourceChannel);
bool CheckAllowedOrigin(nsIHttpChannel* aResourceChannel, nsITimedChannel* aChannel);
// Cached result of CheckAllowedOrigin. If false, security sensitive
// attributes of the resourceTiming object will be set to 0
bool TimingAllowed() const;
@ -222,15 +222,31 @@ public:
private:
~nsPerformanceTiming();
bool IsInitialized() const;
void InitializeTimingInfo(nsITimedChannel* aChannel);
nsRefPtr<nsPerformance> mPerformance;
nsCOMPtr<nsITimedChannel> mChannel;
DOMHighResTimeStamp mFetchStart;
// This is an offset that will be added to each timing ([ms] resolution).
// There are only 2 possible values: (1) logicaly equal to navigationStart
// TimeStamp (results are absolute timstamps - wallclock); (2) "0" (results
// are relative to the navigation start).
DOMHighResTimeStamp mZeroTime;
TimeStamp mAsyncOpen;
TimeStamp mRedirectStart;
TimeStamp mRedirectEnd;
TimeStamp mDomainLookupStart;
TimeStamp mDomainLookupEnd;
TimeStamp mConnectStart;
TimeStamp mConnectEnd;
TimeStamp mRequestStart;
TimeStamp mResponseStart;
TimeStamp mCacheReadStart;
TimeStamp mResponseEnd;
TimeStamp mCacheReadEnd;
uint16_t mRedirectCount;
bool mTimingAllowed;
bool mAllRedirectsSameOrigin;
bool mInitialized;
// If the resourceTiming object should have non-zero redirectStart and
// redirectEnd attributes. It is false if there were no redirects, or if