moebius#158: The Performance Resource Timing (added support for "workerStart")

https://github.com/MoonchildProductions/moebius/pull/158
This commit is contained in:
janekptacijarabaci 2018-04-29 11:49:50 +02:00 • committed by Roy Tam
commit 6885700c5b
26 changed files with 746 additions and 70 deletions

View file

@ -105,6 +105,7 @@ HttpBaseChannel::HttpBaseChannel()
, mHttpHandler(gHttpHandler)
, mReferrerPolicy(REFERRER_POLICY_NO_REFERRER_WHEN_DOWNGRADE)
, mRedirectCount(0)
, mInternalRedirectCount(0)
, mForcePending(false)
, mCorsIncludeCredentials(false)
, mCorsMode(nsIHttpChannelInternal::CORS_MODE_NO_CORS)
@ -3128,12 +3129,6 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI,
// convey the mAllowPipelining and mAllowSTS flags
httpChannel->SetAllowPipelining(mAllowPipelining);
httpChannel->SetAllowSTS(mAllowSTS);
// convey the new redirection limit
// make sure we don't underflow
uint32_t redirectionLimit = mRedirectionLimit
? mRedirectionLimit - 1
: 0;
httpChannel->SetRedirectionLimit(redirectionLimit);
// convey the Accept header value
{
@ -3215,23 +3210,40 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI,
do_QueryInterface(static_cast<nsIHttpChannel*>(this)));
if (oldTimedChannel && newTimedChannel) {
newTimedChannel->SetTimingEnabled(mTimingEnabled);
newTimedChannel->SetRedirectCount(mRedirectCount + 1);
if (redirectFlags & nsIChannelEventSink::REDIRECT_INTERNAL) {
int8_t newCount = mInternalRedirectCount + 1;
newTimedChannel->SetInternalRedirectCount(
std::max(newCount, mInternalRedirectCount));
} else {
int8_t newCount = mRedirectCount + 1;
newTimedChannel->SetRedirectCount(
std::max(newCount, mRedirectCount));
}
// If the RedirectStart is null, we will use the AsyncOpen value of the
// previous channel (this is the first redirect in the redirects chain).
if (mRedirectStartTimeStamp.IsNull()) {
TimeStamp asyncOpen;
oldTimedChannel->GetAsyncOpen(&asyncOpen);
newTimedChannel->SetRedirectStart(asyncOpen);
}
else {
// Only do this for real redirects. Internal redirects should be hidden.
if (!(redirectFlags & nsIChannelEventSink::REDIRECT_INTERNAL)) {
TimeStamp asyncOpen;
oldTimedChannel->GetAsyncOpen(&asyncOpen);
newTimedChannel->SetRedirectStart(asyncOpen);
}
} else {
newTimedChannel->SetRedirectStart(mRedirectStartTimeStamp);
}
// The RedirectEnd timestamp is equal to the previous channel response end.
TimeStamp prevResponseEnd;
oldTimedChannel->GetResponseEnd(&prevResponseEnd);
newTimedChannel->SetRedirectEnd(prevResponseEnd);
// For internal redirects just propagate the last redirect end time
// forward. Otherwise the new redirect end time is the last response
// end time.
TimeStamp newRedirectEnd;
if (redirectFlags & nsIChannelEventSink::REDIRECT_INTERNAL) {
oldTimedChannel->GetRedirectEnd(&newRedirectEnd);
} else {
oldTimedChannel->GetResponseEnd(&newRedirectEnd);
}
newTimedChannel->SetRedirectEnd(newRedirectEnd);
nsAutoString initiatorType;
oldTimedChannel->GetInitiatorType(initiatorType);
@ -3253,6 +3265,16 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI,
mAllRedirectsPassTimingAllowCheck &&
oldTimedChannel->TimingAllowCheck(principal));
}
// Propagate service worker measurements across redirects. The
// PeformanceResourceTiming.workerStart API expects to see the
// worker start time after a redirect.
newTimedChannel->SetLaunchServiceWorkerStart(mLaunchServiceWorkerStart);
newTimedChannel->SetLaunchServiceWorkerEnd(mLaunchServiceWorkerEnd);
newTimedChannel->SetDispatchFetchEventStart(mDispatchFetchEventStart);
newTimedChannel->SetDispatchFetchEventEnd(mDispatchFetchEventEnd);
newTimedChannel->SetHandleFetchEventStart(mHandleFetchEventStart);
newTimedChannel->SetHandleFetchEventEnd(mHandleFetchEventEnd);
}
// Pass the preferred alt-data type on to the new channel.
@ -3318,19 +3340,33 @@ HttpBaseChannel::GetAsyncOpen(TimeStamp* _retval) {
* redirects. This check must be done by the consumers.
*/
NS_IMETHODIMP
HttpBaseChannel::GetRedirectCount(uint16_t *aRedirectCount)
HttpBaseChannel::GetRedirectCount(uint8_t *aRedirectCount)
{
*aRedirectCount = mRedirectCount;
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::SetRedirectCount(uint16_t aRedirectCount)
HttpBaseChannel::SetRedirectCount(uint8_t aRedirectCount)
{
mRedirectCount = aRedirectCount;
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::GetInternalRedirectCount(uint8_t *aRedirectCount)
{
*aRedirectCount = mInternalRedirectCount;
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::SetInternalRedirectCount(uint8_t aRedirectCount)
{
mInternalRedirectCount = aRedirectCount;
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::GetRedirectStart(TimeStamp* _retval)
{
@ -3430,6 +3466,84 @@ HttpBaseChannel::TimingAllowCheck(nsIPrincipal *aOrigin, bool *_retval)
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::GetLaunchServiceWorkerStart(TimeStamp* _retval) {
MOZ_ASSERT(_retval);
*_retval = mLaunchServiceWorkerStart;
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::SetLaunchServiceWorkerStart(TimeStamp aTimeStamp) {
mLaunchServiceWorkerStart = aTimeStamp;
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::GetLaunchServiceWorkerEnd(TimeStamp* _retval) {
MOZ_ASSERT(_retval);
*_retval = mLaunchServiceWorkerEnd;
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::SetLaunchServiceWorkerEnd(TimeStamp aTimeStamp) {
mLaunchServiceWorkerEnd = aTimeStamp;
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::GetDispatchFetchEventStart(TimeStamp* _retval) {
MOZ_ASSERT(_retval);
*_retval = mDispatchFetchEventStart;
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::SetDispatchFetchEventStart(TimeStamp aTimeStamp) {
mDispatchFetchEventStart = aTimeStamp;
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::GetDispatchFetchEventEnd(TimeStamp* _retval) {
MOZ_ASSERT(_retval);
*_retval = mDispatchFetchEventEnd;
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::SetDispatchFetchEventEnd(TimeStamp aTimeStamp) {
mDispatchFetchEventEnd = aTimeStamp;
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::GetHandleFetchEventStart(TimeStamp* _retval) {
MOZ_ASSERT(_retval);
*_retval = mHandleFetchEventStart;
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::SetHandleFetchEventStart(TimeStamp aTimeStamp) {
mHandleFetchEventStart = aTimeStamp;
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::GetHandleFetchEventEnd(TimeStamp* _retval) {
MOZ_ASSERT(_retval);
*_retval = mHandleFetchEventEnd;
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::SetHandleFetchEventEnd(TimeStamp aTimeStamp) {
mHandleFetchEventEnd = aTimeStamp;
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::GetDomainLookupStart(TimeStamp* _retval) {
*_retval = mTransactionTimings.domainLookupStart;
@ -3520,6 +3634,12 @@ HttpBaseChannel::Get##name##Time(PRTime* _retval) { \
IMPL_TIMING_ATTR(ChannelCreation)
IMPL_TIMING_ATTR(AsyncOpen)
IMPL_TIMING_ATTR(LaunchServiceWorkerStart)
IMPL_TIMING_ATTR(LaunchServiceWorkerEnd)
IMPL_TIMING_ATTR(DispatchFetchEventStart)
IMPL_TIMING_ATTR(DispatchFetchEventEnd)
IMPL_TIMING_ATTR(HandleFetchEventStart)
IMPL_TIMING_ATTR(HandleFetchEventEnd)
IMPL_TIMING_ATTR(DomainLookupStart)
IMPL_TIMING_ATTR(DomainLookupEnd)
IMPL_TIMING_ATTR(ConnectStart)

View file

@ -506,7 +506,9 @@ protected:
// the HTML file.
nsString mInitiatorType;
// Number of redirects that has occurred.
int16_t mRedirectCount;
int8_t mRedirectCount;
// Number of internal redirects that has occurred.
int8_t mInternalRedirectCount;
// A time value equal to the starting time of the fetch that initiates the
// redirect.
mozilla::TimeStamp mRedirectStartTimeStamp;
@ -519,6 +521,12 @@ protected:
TimeStamp mAsyncOpenTime;
TimeStamp mCacheReadStart;
TimeStamp mCacheReadEnd;
TimeStamp mLaunchServiceWorkerStart;
TimeStamp mLaunchServiceWorkerEnd;
TimeStamp mDispatchFetchEventStart;
TimeStamp mDispatchFetchEventEnd;
TimeStamp mHandleFetchEventStart;
TimeStamp mHandleFetchEventEnd;
// copied from the transaction before we null out mTransaction
// so that the timing can still be queried from OnStopRequest
TimingStruct mTransactionTimings;

View file

@ -2132,6 +2132,13 @@ HttpChannelChild::ContinueAsyncOpen()
return NS_ERROR_FAILURE;
}
openArgs.launchServiceWorkerStart() = mLaunchServiceWorkerStart;
openArgs.launchServiceWorkerEnd() = mLaunchServiceWorkerEnd;
openArgs.dispatchFetchEventStart() = mDispatchFetchEventStart;
openArgs.dispatchFetchEventEnd() = mDispatchFetchEventEnd;
openArgs.handleFetchEventStart() = mHandleFetchEventStart;
openArgs.handleFetchEventEnd() = mHandleFetchEventEnd;
// The socket transport in the chrome process now holds a logical ref to us
// until OnStopRequest, or we do a redirect, or we hit an IPDL error.
AddIPDLReference();

View file

@ -130,7 +130,13 @@ HttpChannelParent::Init(const HttpChannelCreationArgs& aArgs)
a.initialRwin(), a.blockAuthPrompt(),
a.suspendAfterSynthesizeResponse(),
a.allowStaleCacheContent(), a.contentTypeHint(),
a.channelId(), a.contentWindowId(), a.preferredAlternativeType());
a.channelId(), a.contentWindowId(), a.preferredAlternativeType(),
a.launchServiceWorkerStart(),
a.launchServiceWorkerEnd(),
a.dispatchFetchEventStart(),
a.dispatchFetchEventEnd(),
a.handleFetchEventStart(),
a.handleFetchEventEnd());
}
case HttpChannelCreationArgs::THttpChannelConnectArgs:
{
@ -329,7 +335,13 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
const nsCString& aContentTypeHint,
const nsCString& aChannelId,
const uint64_t& aContentWindowId,
const nsCString& aPreferredAlternativeType)
const nsCString& aPreferredAlternativeType,
const TimeStamp& aLaunchServiceWorkerStart,
const TimeStamp& aLaunchServiceWorkerEnd,
const TimeStamp& aDispatchFetchEventStart,
const TimeStamp& aDispatchFetchEventEnd,
const TimeStamp& aHandleFetchEventStart,
const TimeStamp& aHandleFetchEventEnd)
{
nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
if (!uri) {
@ -534,6 +546,13 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
mChannel->SetInitialRwin(aInitialRwin);
mChannel->SetBlockAuthPrompt(aBlockAuthPrompt);
mChannel->SetLaunchServiceWorkerStart(aLaunchServiceWorkerStart);
mChannel->SetLaunchServiceWorkerEnd(aLaunchServiceWorkerEnd);
mChannel->SetDispatchFetchEventStart(aDispatchFetchEventStart);
mChannel->SetDispatchFetchEventEnd(aDispatchFetchEventEnd);
mChannel->SetHandleFetchEventStart(aHandleFetchEventStart);
mChannel->SetHandleFetchEventEnd(aHandleFetchEventEnd);
nsCOMPtr<nsIApplicationCacheChannel> appCacheChan =
do_QueryObject(mChannel);
nsCOMPtr<nsIApplicationCacheService> appCacheService =
@ -1159,7 +1178,7 @@ HttpChannelParent::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
nsCString secInfoSerialization;
UpdateAndSerializeSecurityInfo(secInfoSerialization);
uint16_t redirectCount = 0;
uint8_t redirectCount = 0;
chan->GetRedirectCount(&redirectCount);
nsCOMPtr<nsISupports> cacheKey;

View file

@ -143,7 +143,13 @@ protected:
const nsCString& aContentTypeHint,
const nsCString& aChannelId,
const uint64_t& aContentWindowId,
const nsCString& aPreferredAlternativeType);
const nsCString& aPreferredAlternativeType,
const TimeStamp& aLaunchServiceWorkerStart,
const TimeStamp& aLaunchServiceWorkerEnd,
const TimeStamp& aDispatchFetchEventStart,
const TimeStamp& aDispatchFetchEventEnd,
const TimeStamp& aHandleFetchEventStart,
const TimeStamp& aHandleFetchEventEnd);
virtual bool RecvSetPriority(const uint16_t& priority) override;
virtual bool RecvSetClassOfService(const uint32_t& cos) override;

View file

@ -10,6 +10,7 @@
#include "nsInputStreamPump.h"
#include "nsIPipe.h"
#include "nsIStreamListener.h"
#include "nsITimedChannel.h"
#include "nsHttpChannel.h"
#include "HttpChannelChild.h"
#include "nsHttpResponseHead.h"
@ -134,6 +135,40 @@ InterceptedChannelBase::SetReleaseHandle(nsISupports* aHandle)
return NS_OK;
}
NS_IMETHODIMP
InterceptedChannelBase::SaveTimeStampsToUnderlyingChannel()
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIChannel> underlyingChannel;
nsresult rv = GetChannel(getter_AddRefs(underlyingChannel));
MOZ_ASSERT(NS_SUCCEEDED(rv));
nsCOMPtr<nsITimedChannel> timedChannel =
do_QueryInterface(underlyingChannel);
MOZ_ASSERT(timedChannel);
rv = timedChannel->SetLaunchServiceWorkerStart(mLaunchServiceWorkerStart);
MOZ_ASSERT(NS_SUCCEEDED(rv));
rv = timedChannel->SetLaunchServiceWorkerEnd(mLaunchServiceWorkerEnd);
MOZ_ASSERT(NS_SUCCEEDED(rv));
rv = timedChannel->SetDispatchFetchEventStart(mDispatchFetchEventStart);
MOZ_ASSERT(NS_SUCCEEDED(rv));
rv = timedChannel->SetDispatchFetchEventEnd(mDispatchFetchEventEnd);
MOZ_ASSERT(NS_SUCCEEDED(rv));
rv = timedChannel->SetHandleFetchEventStart(mHandleFetchEventStart);
MOZ_ASSERT(NS_SUCCEEDED(rv));
rv = timedChannel->SetHandleFetchEventEnd(mHandleFetchEventEnd);
MOZ_ASSERT(NS_SUCCEEDED(rv));
return rv;
}
/* static */
already_AddRefed<nsIURI>
InterceptedChannelBase::SecureUpgradeChannelURI(nsIChannel* aChannel)

View file

@ -46,6 +46,13 @@ protected:
nsresult DoSynthesizeStatus(uint16_t aStatus, const nsACString& aReason);
nsresult DoSynthesizeHeader(const nsACString& aName, const nsACString& aValue);
TimeStamp mLaunchServiceWorkerStart;
TimeStamp mLaunchServiceWorkerEnd;
TimeStamp mDispatchFetchEventStart;
TimeStamp mDispatchFetchEventEnd;
TimeStamp mHandleFetchEventStart;
TimeStamp mHandleFetchEventEnd;
virtual ~InterceptedChannelBase();
public:
explicit InterceptedChannelBase(nsINetworkInterceptController* aController);
@ -60,6 +67,50 @@ public:
NS_IMETHOD GetConsoleReportCollector(nsIConsoleReportCollector** aCollectorOut) override;
NS_IMETHOD SetReleaseHandle(nsISupports* aHandle) override;
NS_IMETHODIMP
SetLaunchServiceWorkerStart(TimeStamp aTimeStamp) override
{
mLaunchServiceWorkerStart = aTimeStamp;
return NS_OK;
}
NS_IMETHODIMP
SetLaunchServiceWorkerEnd(TimeStamp aTimeStamp) override
{
mLaunchServiceWorkerEnd = aTimeStamp;
return NS_OK;
}
NS_IMETHODIMP
SetDispatchFetchEventStart(TimeStamp aTimeStamp) override
{
mDispatchFetchEventStart = aTimeStamp;
return NS_OK;
}
NS_IMETHODIMP
SetDispatchFetchEventEnd(TimeStamp aTimeStamp) override
{
mDispatchFetchEventEnd = aTimeStamp;
return NS_OK;
}
NS_IMETHODIMP
SetHandleFetchEventStart(TimeStamp aTimeStamp) override
{
mHandleFetchEventStart = aTimeStamp;
return NS_OK;
}
NS_IMETHODIMP
SetHandleFetchEventEnd(TimeStamp aTimeStamp) override
{
mHandleFetchEventEnd = aTimeStamp;
return NS_OK;
}
NS_IMETHODIMP SaveTimeStampsToUnderlyingChannel() override;
static already_AddRefed<nsIURI>
SecureUpgradeChannelURI(nsIChannel* aChannel);
};

View file

@ -539,13 +539,25 @@ NullHttpChannel::SetTimingEnabled(bool aTimingEnabled)
}
NS_IMETHODIMP
NullHttpChannel::GetRedirectCount(uint16_t *aRedirectCount)
NullHttpChannel::GetRedirectCount(uint8_t *aRedirectCount)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
NullHttpChannel::SetRedirectCount(uint16_t aRedirectCount)
NullHttpChannel::SetRedirectCount(uint8_t aRedirectCount)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
NullHttpChannel::GetInternalRedirectCount(uint8_t *aRedirectCount)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
NullHttpChannel::SetInternalRedirectCount(uint8_t aRedirectCount)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
@ -564,6 +576,90 @@ NullHttpChannel::GetAsyncOpen(mozilla::TimeStamp *aAsyncOpen)
return NS_OK;
}
NS_IMETHODIMP
NullHttpChannel::GetLaunchServiceWorkerStart(mozilla::TimeStamp *_retval)
{
MOZ_ASSERT(_retval);
*_retval = mAsyncOpenTime;
return NS_OK;
}
NS_IMETHODIMP
NullHttpChannel::SetLaunchServiceWorkerStart(mozilla::TimeStamp aTimeStamp)
{
return NS_OK;
}
NS_IMETHODIMP
NullHttpChannel::GetLaunchServiceWorkerEnd(mozilla::TimeStamp *_retval)
{
MOZ_ASSERT(_retval);
*_retval = mAsyncOpenTime;
return NS_OK;
}
NS_IMETHODIMP
NullHttpChannel::SetLaunchServiceWorkerEnd(mozilla::TimeStamp aTimeStamp)
{
return NS_OK;
}
NS_IMETHODIMP
NullHttpChannel::GetDispatchFetchEventStart(mozilla::TimeStamp *_retval)
{
MOZ_ASSERT(_retval);
*_retval = mAsyncOpenTime;
return NS_OK;
}
NS_IMETHODIMP
NullHttpChannel::SetDispatchFetchEventStart(mozilla::TimeStamp aTimeStamp)
{
return NS_OK;
}
NS_IMETHODIMP
NullHttpChannel::GetDispatchFetchEventEnd(mozilla::TimeStamp *_retval)
{
MOZ_ASSERT(_retval);
*_retval = mAsyncOpenTime;
return NS_OK;
}
NS_IMETHODIMP
NullHttpChannel::SetDispatchFetchEventEnd(mozilla::TimeStamp aTimeStamp)
{
return NS_OK;
}
NS_IMETHODIMP
NullHttpChannel::GetHandleFetchEventStart(mozilla::TimeStamp *_retval)
{
MOZ_ASSERT(_retval);
*_retval = mAsyncOpenTime;
return NS_OK;
}
NS_IMETHODIMP
NullHttpChannel::SetHandleFetchEventStart(mozilla::TimeStamp aTimeStamp)
{
return NS_OK;
}
NS_IMETHODIMP
NullHttpChannel::GetHandleFetchEventEnd(mozilla::TimeStamp *_retval)
{
MOZ_ASSERT(_retval);
*_retval = mAsyncOpenTime;
return NS_OK;
}
NS_IMETHODIMP
NullHttpChannel::SetHandleFetchEventEnd(mozilla::TimeStamp aTimeStamp)
{
return NS_OK;
}
NS_IMETHODIMP
NullHttpChannel::GetDomainLookupStart(mozilla::TimeStamp *aDomainLookupStart)
{
@ -761,6 +857,12 @@ NullHttpChannel::Get##name##Time(PRTime* _retval) { \
IMPL_TIMING_ATTR(ChannelCreation)
IMPL_TIMING_ATTR(AsyncOpen)
IMPL_TIMING_ATTR(LaunchServiceWorkerStart)
IMPL_TIMING_ATTR(LaunchServiceWorkerEnd)
IMPL_TIMING_ATTR(DispatchFetchEventStart)
IMPL_TIMING_ATTR(DispatchFetchEventEnd)
IMPL_TIMING_ATTR(HandleFetchEventStart)
IMPL_TIMING_ATTR(HandleFetchEventEnd)
IMPL_TIMING_ATTR(DomainLookupStart)
IMPL_TIMING_ATTR(DomainLookupEnd)
IMPL_TIMING_ATTR(ConnectStart)

View file

@ -5402,7 +5402,7 @@ nsHttpChannel::AsyncProcessRedirection(uint32_t redirectType)
if (NS_EscapeURL(location.get(), -1, esc_OnlyNonASCII, locationBuf))
location = locationBuf;
if (mRedirectionLimit == 0) {
if (mRedirectCount >= mRedirectionLimit || mInternalRedirectCount >= mRedirectionLimit) {
LOG(("redirection limit reached!\n"));
return NS_ERROR_REDIRECT_LOOP;
}