Bug 772589 - Implement the secureConnectionStart property for the PerformanceTiming interface r=bkelly,dragana,francois,Honza

Implements PerformanceTiming, nsITimedChannel, and devtools 'tls setup'

Also captures telemetry on this as we do for all other attributes of timedChannel

Also propogates some null transaction timings onto first real
transaction of a connection

MozReview-Commit-ID: 47TQJYVHnKC

--HG--
extra : rebase_source : a7723962986de0c2ab00d479a22c3f5fd185c8b2
This commit is contained in:
Patrick McManus 2017-07-10 15:01:35 -04:00
Родитель 93add5506b
Коммит 850582d8f3
35 изменённых файлов: 280 добавлений и 43 удалений

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

@ -237,6 +237,10 @@ netmonitor.waterfall.tooltip.blocked=Blocked %S ms
# displayed in the requests waterfall for dns time (in milliseconds).
netmonitor.waterfall.tooltip.dns=DNS %S ms
# LOCALIZATION NOTE (netmonitor.waterfall.tooltip.ssl): This is part of the tooltip
# displayed in the requests waterfall for tls setup time (in milliseconds).
netmonitor.waterfall.tooltip.ssl=TLS %S ms
# LOCALIZATION NOTE (netmonitor.waterfall.tooltip.connect): This is part of the tooltip
# displayed in the requests waterfall for connect time (in milliseconds).
netmonitor.waterfall.tooltip.connect=Connect %S ms
@ -709,6 +713,11 @@ netmonitor.timings.blocked=Blocked:
# in a "dns" state.
netmonitor.timings.dns=DNS resolution:
# LOCALIZATION NOTE (netmonitor.timings.ssl): This is the label displayed
# in the network details timings tab identifying the amount of time spent
# in a "tls" handshake state.
netmonitor.timings.ssl=TLS setup:
# LOCALIZATION NOTE (netmonitor.timings.connect): This is the label displayed
# in the network details timings tab identifying the amount of time spent
# in a "connect" state.

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

@ -19,6 +19,7 @@
--timing-blocked-color: rgba(235, 83, 104, 0.8);
--timing-dns-color: rgba(223, 128, 255, 0.8); /* pink */
--timing-ssl-color: rgba(217, 102, 41, 0.8); /* orange */
--timing-connect-color: rgba(217, 102, 41, 0.8); /* orange */
--timing-send-color: rgba(70, 175, 227, 0.8); /* light blue */
--timing-wait-color: rgba(94, 136, 176, 0.8); /* blue grey */
@ -34,6 +35,7 @@
--timing-blocked-color: rgba(235, 83, 104, 0.8);
--timing-dns-color: rgba(223, 128, 255, 0.8); /* pink */
--timing-ssl-color: rgba(217, 102, 41, 0.8); /* orange */
--timing-connect-color: rgba(217, 102, 41, 0.8); /* orange */
--timing-send-color: rgba(0, 136, 204, 0.8); /* blue */
--timing-wait-color: rgba(95, 136, 176, 0.8); /* blue grey */
@ -683,6 +685,10 @@ body,
background-color: var(--timing-connect-color);
}
.requests-list-timings-box.ssl {
background-color: var(--timing-ssl-color);
}
.requests-list-timings-box.send {
background-color: var(--timing-send-color);
}

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

@ -21,7 +21,7 @@ const UPDATED_WATERFALL_PROPS = [
"totalTime",
];
// List of properties of the timing info we want to create boxes for
const TIMING_KEYS = ["blocked", "dns", "connect", "send", "wait", "receive"];
const TIMING_KEYS = ["blocked", "dns", "connect", "ssl", "send", "wait", "receive"];
const RequestListColumnWaterfall = createClass({
displayName: "RequestListColumnWaterfall",

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

@ -12,7 +12,7 @@ const { getNetMonitorTimingsURL } = require("../utils/mdn-utils");
const MDNLink = require("./mdn-link");
const { div, span } = DOM;
const types = ["blocked", "dns", "connect", "send", "wait", "receive"];
const types = ["blocked", "dns", "connect", "ssl", "send", "wait", "receive"];
const TIMINGS_END_PADDING = "80px";
/*

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

@ -327,6 +327,8 @@ function test() {
"The eventTimings data has an incorrect |timings.blocked| property.");
is(typeof requestItem.eventTimings.timings.dns, "number",
"The eventTimings data has an incorrect |timings.dns| property.");
is(typeof requestItem.eventTimings.timings.ssl, "number",
"The eventTimings data has an incorrect |timings.ssl| property.");
is(typeof requestItem.eventTimings.timings.connect, "number",
"The eventTimings data has an incorrect |timings.connect| property.");
is(typeof requestItem.eventTimings.timings.send, "number",

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

@ -731,7 +731,9 @@ NetworkMonitor.prototype = {
0x804b0004: "STATUS_CONNECTED_TO",
0x804b0005: "STATUS_SENDING_TO",
0x804b000a: "STATUS_WAITING_FOR",
0x804b0006: "STATUS_RECEIVING_FROM"
0x804b0006: "STATUS_RECEIVING_FROM",
0x804b000c: "STATUS_TLS_STARTING",
0x804b000d: "STATUS_TLS_ENDING"
},
httpDownloadActivities: [
@ -1391,6 +1393,7 @@ NetworkMonitor.prototype = {
timings: {
blocked: 0,
dns: 0,
ssl: 0,
connect: 0,
send: 0,
wait: 0,
@ -1425,6 +1428,36 @@ NetworkMonitor.prototype = {
harTimings.connect = -1;
}
if (timings.STATUS_TLS_STARTING && timings.STATUS_TLS_ENDING) {
harTimings.ssl = timings.STATUS_TLS_ENDING.last -
timings.STATUS_TLS_STARTING.first;
} else {
harTimings.ssl = -1;
}
// sometimes the connection information events are attached to a speculative
// channel instead of this one, but necko might glue them back together in the
// nsITimedChannel interface used by Resource and Navigation Timing
let timedChannel = httpActivity.channel.QueryInterface(Ci.nsITimedChannel);
if ((harTimings.connect <= 0) && timedChannel) {
if (timedChannel.secureConnectionStartTime > timedChannel.connectStartTime) {
harTimings.connect =
timedChannel.secureConnectionStartTime - timedChannel.connectStartTime;
harTimings.ssl =
timedChannel.connectEndTime - timedChannel.secureConnectionStartTime;
} else {
harTimings.connect =
timedChannel.connectEndTime - timedChannel.connectStartTime;
harTimings.ssl = -1;
}
}
if ((harTimings.dns <= 0) && timedChannel) {
harTimings.dns =
timedChannel.domainLookupEndTime - timedChannel.domainLookupStartTime;
}
if (timings.STATUS_SENDING_TO) {
harTimings.send = timings.STATUS_SENDING_TO.last - timings.STATUS_SENDING_TO.first;
} else if (timings.REQUEST_HEADER && timings.REQUEST_BODY_SENT) {

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

@ -202,7 +202,7 @@ PerformanceMainThread::IsPerformanceTimingAttribute(const nsAString& aName)
static const char* attributes[] =
{"navigationStart", "unloadEventStart", "unloadEventEnd", "redirectStart",
"redirectEnd", "fetchStart", "domainLookupStart", "domainLookupEnd",
"connectStart", "connectEnd", "requestStart", "responseStart",
"connectStart", "secureConnectionStart", "connectEnd", "requestStart", "responseStart",
"responseEnd", "domLoading", "domInteractive",
"domContentLoadedEventStart", "domContentLoadedEventEnd", "domComplete",
"loadEventStart", "loadEventEnd", nullptr};
@ -251,6 +251,9 @@ PerformanceMainThread::GetPerformanceTimingFromString(const nsAString& aProperty
if (aProperty.EqualsLiteral("connectStart")) {
return Timing()->ConnectStart();
}
if (aProperty.EqualsLiteral("secureConnectionStart")) {
return Timing()->SecureConnectionStart();
}
if (aProperty.EqualsLiteral("connectEnd")) {
return Timing()->ConnectEnd();
}

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

@ -128,9 +128,9 @@ public:
DOMHighResTimeStamp SecureConnectionStart() const
{
// This measurement is not available for Navigation Timing either.
// There is a different bug submitted for it.
return 0;
return mTiming && mTiming->TimingAllowed()
? mTiming->SecureConnectionStartHighRes()
: 0;
}
virtual const PerformanceResourceTiming* ToResourceTiming() const override

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

@ -78,12 +78,40 @@ PerformanceTiming::InitializeTimingInfo(nsITimedChannel* aChannel)
aChannel->GetDomainLookupStart(&mDomainLookupStart);
aChannel->GetDomainLookupEnd(&mDomainLookupEnd);
aChannel->GetConnectStart(&mConnectStart);
aChannel->GetSecureConnectionStart(&mSecureConnectionStart);
aChannel->GetConnectEnd(&mConnectEnd);
aChannel->GetRequestStart(&mRequestStart);
aChannel->GetResponseStart(&mResponseStart);
aChannel->GetCacheReadStart(&mCacheReadStart);
aChannel->GetResponseEnd(&mResponseEnd);
aChannel->GetCacheReadEnd(&mCacheReadEnd);
// the performance timing api essentially requires that the event timestamps
// are >= asyncOpen().. but in truth the browser engages in a number of
// speculative activities that sometimes mean connections and lookups begin
// earlier. Workaround that here by just using asyncOpen as the minimum
// timestamp for dns and connection info.
if (!mAsyncOpen.IsNull()) {
if (!mDomainLookupStart.IsNull() && mDomainLookupStart < mAsyncOpen) {
mDomainLookupStart = mAsyncOpen;
}
if (!mDomainLookupEnd.IsNull() && mDomainLookupEnd < mAsyncOpen) {
mDomainLookupEnd = mAsyncOpen;
}
if (!mConnectStart.IsNull() && mConnectStart < mAsyncOpen) {
mConnectStart = mAsyncOpen;
}
if (!mSecureConnectionStart.IsNull() && mSecureConnectionStart < mAsyncOpen) {
mSecureConnectionStart = mAsyncOpen;
}
if (!mConnectEnd.IsNull() && mConnectEnd < mAsyncOpen) {
mConnectEnd = mAsyncOpen;
}
}
}
}
@ -296,6 +324,23 @@ PerformanceTiming::ConnectStart()
return static_cast<int64_t>(ConnectStartHighRes());
}
DOMHighResTimeStamp
PerformanceTiming::SecureConnectionStartHighRes()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
nsContentUtils::ShouldResistFingerprinting()) {
return mZeroTime;
}
return mSecureConnectionStart.IsNull() ? mZeroTime
: TimeStampToDOMHighRes(mSecureConnectionStart);
}
DOMTimeMilliSec
PerformanceTiming::SecureConnectionStart()
{
return static_cast<int64_t>(SecureConnectionStartHighRes());
}
DOMHighResTimeStamp
PerformanceTiming::ConnectEndHighRes()
{

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

@ -164,6 +164,7 @@ public:
DOMHighResTimeStamp DomainLookupStartHighRes();
DOMHighResTimeStamp DomainLookupEndHighRes();
DOMHighResTimeStamp ConnectStartHighRes();
DOMHighResTimeStamp SecureConnectionStartHighRes();
DOMHighResTimeStamp ConnectEndHighRes();
DOMHighResTimeStamp RequestStartHighRes();
DOMHighResTimeStamp ResponseStartHighRes();
@ -176,6 +177,7 @@ public:
DOMTimeMilliSec DomainLookupStart();
DOMTimeMilliSec DomainLookupEnd();
DOMTimeMilliSec ConnectStart();
DOMTimeMilliSec SecureConnectionStart();
DOMTimeMilliSec ConnectEnd();
DOMTimeMilliSec RequestStart();
DOMTimeMilliSec ResponseStart();
@ -276,6 +278,7 @@ private:
TimeStamp mDomainLookupStart;
TimeStamp mDomainLookupEnd;
TimeStamp mConnectStart;
TimeStamp mSecureConnectionStart;
TimeStamp mConnectEnd;
TimeStamp mRequestStart;
TimeStamp mResponseStart;

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

@ -21,8 +21,7 @@ interface PerformanceTiming {
readonly attribute unsigned long long domainLookupEnd;
readonly attribute unsigned long long connectStart;
readonly attribute unsigned long long connectEnd;
// secureConnectionStart will be implemneted in bug 772589
// readonly attribute unsigned long long secureConnectionStart;
readonly attribute unsigned long long secureConnectionStart;
readonly attribute unsigned long long requestStart;
readonly attribute unsigned long long responseStart;
readonly attribute unsigned long long responseEnd;

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

@ -169,6 +169,8 @@ interface nsISocketTransport : nsITransport
const unsigned long STATUS_SENDING_TO = 0x804b0005;
const unsigned long STATUS_WAITING_FOR = 0x804b000a;
const unsigned long STATUS_RECEIVING_FROM = 0x804b0006;
const unsigned long STATUS_TLS_HANDSHAKE_STARTING = 0x804b000c;
const unsigned long STATUS_TLS_HANDSHAKE_ENDED = 0x804b000d;
/**
* connectionFlags is a bitmask that can be used to modify underlying

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

@ -40,6 +40,7 @@ interface nsITimedChannel : nsISupports {
[noscript] readonly attribute TimeStamp domainLookupStart;
[noscript] readonly attribute TimeStamp domainLookupEnd;
[noscript] readonly attribute TimeStamp connectStart;
[noscript] readonly attribute TimeStamp secureConnectionStart;
[noscript] readonly attribute TimeStamp connectEnd;
[noscript] readonly attribute TimeStamp requestStart;
[noscript] readonly attribute TimeStamp responseStart;
@ -84,6 +85,7 @@ interface nsITimedChannel : nsISupports {
readonly attribute PRTime domainLookupStartTime;
readonly attribute PRTime domainLookupEndTime;
readonly attribute PRTime connectStartTime;
readonly attribute PRTime secureConnectionStartTime;
readonly attribute PRTime connectEndTime;
readonly attribute PRTime requestStartTime;
readonly attribute PRTime responseStartTime;

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

@ -890,6 +890,11 @@ nsLoadGroup::TelemetryReportChannel(nsITimedChannel *aTimedChannel,
if (NS_FAILED(rv))
return;
TimeStamp secureConnectionStart;
rv = aTimedChannel->GetSecureConnectionStart(&secureConnectionStart);
if (NS_FAILED(rv))
return;
TimeStamp connectEnd;
rv = aTimedChannel->GetConnectEnd(&connectEnd);
if (NS_FAILED(rv))
@ -923,12 +928,17 @@ nsLoadGroup::TelemetryReportChannel(nsITimedChannel *aTimedChannel,
domainLookupStart, domainLookupEnd); \
} \
\
if (!connectStart.IsNull() && !connectEnd.IsNull()) { \
if (!secureConnectionStart.IsNull() && !connectEnd.IsNull()) { \
Telemetry::AccumulateTimeDelta( \
Telemetry::HTTP_##prefix##_TCP_CONNECTION, \
connectStart, connectEnd); \
Telemetry::HTTP_##prefix##_TLS_HANDSHAKE, \
secureConnectionStart, connectEnd); \
} \
\
if (!connectStart.IsNull() && !connectEnd.IsNull()) { \
Telemetry::AccumulateTimeDelta( \
Telemetry::HTTP_##prefix##_TCP_CONNECTION_2, \
connectStart, connectEnd); \
} \
\
if (!requestStart.IsNull() && !responseEnd.IsNull()) { \
Telemetry::AccumulateTimeDelta( \

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

@ -147,6 +147,7 @@ struct ParamTraits<mozilla::net::ResourceTimingStruct>
WriteParam(aMsg, aParam.domainLookupStart);
WriteParam(aMsg, aParam.domainLookupEnd);
WriteParam(aMsg, aParam.connectStart);
WriteParam(aMsg, aParam.secureConnectionStart);
WriteParam(aMsg, aParam.connectEnd);
WriteParam(aMsg, aParam.requestStart);
WriteParam(aMsg, aParam.responseStart);
@ -169,6 +170,7 @@ struct ParamTraits<mozilla::net::ResourceTimingStruct>
return ReadParam(aMsg, aIter, &aResult->domainLookupStart) &&
ReadParam(aMsg, aIter, &aResult->domainLookupEnd) &&
ReadParam(aMsg, aIter, &aResult->connectStart) &&
ReadParam(aMsg, aIter, &aResult->secureConnectionStart) &&
ReadParam(aMsg, aIter, &aResult->connectEnd) &&
ReadParam(aMsg, aIter, &aResult->requestStart) &&
ReadParam(aMsg, aIter, &aResult->responseStart) &&

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

@ -2434,6 +2434,15 @@ Http2Session::OnTransportStatus(nsITransport* aTransport,
case NS_NET_STATUS_TLS_HANDSHAKE_ENDED:
{
Http2Stream *target = mStreamIDHash.Get(mUseH2Deps ? 0xF : 0x3);
if (!target) {
// any transaction will do if we can't find the low numbered one
// generally this happens when the initial transaction hasn't been
// assigned a stream id yet.
auto iter = mStreamTransactionHash.Iter();
if (!iter.Done()) {
target = iter.Data();
}
}
nsAHttpTransaction *transaction = target ? target->Transaction() : nullptr;
if (transaction)
transaction->OnTransportStatus(aTransport, aStatus, aProgress);

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

@ -3839,6 +3839,12 @@ HttpBaseChannel::GetConnectStart(TimeStamp* _retval) {
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::GetSecureConnectionStart(TimeStamp* _retval) {
*_retval = mTransactionTimings.secureConnectionStart;
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::GetConnectEnd(TimeStamp* _retval) {
*_retval = mTransactionTimings.connectEnd;
@ -3914,6 +3920,7 @@ IMPL_TIMING_ATTR(HandleFetchEventEnd)
IMPL_TIMING_ATTR(DomainLookupStart)
IMPL_TIMING_ATTR(DomainLookupEnd)
IMPL_TIMING_ATTR(ConnectStart)
IMPL_TIMING_ATTR(SecureConnectionStart)
IMPL_TIMING_ATTR(ConnectEnd)
IMPL_TIMING_ATTR(RequestStart)
IMPL_TIMING_ATTR(ResponseStart)

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

@ -1043,6 +1043,7 @@ HttpChannelChild::OnStopRequest(const nsresult& channelStatus,
mTransactionTimings.domainLookupStart = timing.domainLookupStart;
mTransactionTimings.domainLookupEnd = timing.domainLookupEnd;
mTransactionTimings.connectStart = timing.connectStart;
mTransactionTimings.secureConnectionStart = timing.secureConnectionStart;
mTransactionTimings.connectEnd = timing.connectEnd;
mTransactionTimings.requestStart = timing.requestStart;
mTransactionTimings.responseStart = timing.responseStart;

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

@ -1530,6 +1530,7 @@ HttpChannelParent::OnStopRequest(nsIRequest *aRequest,
mChannel->GetDomainLookupStart(&timing.domainLookupStart);
mChannel->GetDomainLookupEnd(&timing.domainLookupEnd);
mChannel->GetConnectStart(&timing.connectStart);
mChannel->GetSecureConnectionStart(&timing.secureConnectionStart);
mChannel->GetConnectEnd(&timing.connectEnd);
mChannel->GetRequestStart(&timing.requestStart);
mChannel->GetResponseStart(&timing.responseStart);

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

@ -694,6 +694,13 @@ NullHttpChannel::GetConnectStart(mozilla::TimeStamp *aConnectStart)
return NS_OK;
}
NS_IMETHODIMP
NullHttpChannel::GetSecureConnectionStart(mozilla::TimeStamp *aSecureConnectionStart)
{
*aSecureConnectionStart = mAsyncOpenTime;
return NS_OK;
}
NS_IMETHODIMP
NullHttpChannel::GetConnectEnd(mozilla::TimeStamp *aConnectEnd)
{
@ -872,6 +879,7 @@ IMPL_TIMING_ATTR(HandleFetchEventEnd)
IMPL_TIMING_ATTR(DomainLookupStart)
IMPL_TIMING_ATTR(DomainLookupEnd)
IMPL_TIMING_ATTR(ConnectStart)
IMPL_TIMING_ATTR(SecureConnectionStart)
IMPL_TIMING_ATTR(ConnectEnd)
IMPL_TIMING_ATTR(RequestStart)
IMPL_TIMING_ATTR(ResponseStart)

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

@ -170,6 +170,30 @@ void
NullHttpTransaction::OnTransportStatus(nsITransport* transport,
nsresult status, int64_t progress)
{
if (status == NS_NET_STATUS_RESOLVING_HOST) {
if (mTimings.domainLookupStart.IsNull()) {
mTimings.domainLookupStart = TimeStamp::Now();
}
} else if (status == NS_NET_STATUS_RESOLVED_HOST) {
if (mTimings.domainLookupEnd.IsNull()) {
mTimings.domainLookupEnd = TimeStamp::Now();
}
} else if (status == NS_NET_STATUS_CONNECTING_TO) {
if (mTimings.connectStart.IsNull()) {
mTimings.connectStart = TimeStamp::Now();
}
} else if (status == NS_NET_STATUS_CONNECTED_TO) {
if (mTimings.connectEnd.IsNull()) {
mTimings.connectEnd = TimeStamp::Now();
}
} else if (status == NS_NET_STATUS_TLS_HANDSHAKE_ENDED) {
if (mTimings.secureConnectionStart.IsNull() &&
!mTimings.connectEnd.IsNull()) {
mTimings.secureConnectionStart = mTimings.connectEnd;
}
mTimings.connectEnd = TimeStamp::Now();;
}
if (mActivityDistributor) {
NS_DispatchToMainThread(new CallObserveActivity(mActivityDistributor,
mConnectionInfo->GetOrigin(),

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

@ -9,6 +9,7 @@
#include "nsAHttpTransaction.h"
#include "mozilla/Attributes.h"
#include "TimingStruct.h"
// This is the minimal nsAHttpTransaction implementation. A NullHttpTransaction
// can be used to drive connection level semantics (such as SSL handshakes
@ -56,6 +57,8 @@ public:
// creation and be never put in a pending queue, so it's OK to just return 0.
uint64_t TopLevelOuterContentWindowId() override { return 0; }
TimingStruct Timings() { return mTimings; }
protected:
virtual ~NullHttpTransaction();
@ -75,6 +78,7 @@ private:
Atomic<uint32_t> mCapsToClear;
bool mIsDone;
bool mClaimed;
TimingStruct mTimings;
protected:
RefPtr<nsAHttpConnection> mConnection;

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

@ -14,6 +14,7 @@ struct TimingStruct {
TimeStamp domainLookupStart;
TimeStamp domainLookupEnd;
TimeStamp connectStart;
TimeStamp secureConnectionStart;
TimeStamp connectEnd;
TimeStamp requestStart;
TimeStamp responseStart;

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

@ -6914,6 +6914,15 @@ nsHttpChannel::GetConnectStart(TimeStamp* _retval) {
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::GetSecureConnectionStart(TimeStamp* _retval) {
if (mTransaction)
*_retval = mTransaction->GetSecureConnectionStart();
else
*_retval = mTransactionTimings.secureConnectionStart;
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::GetConnectEnd(TimeStamp* _retval) {
if (mTransaction)

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

@ -178,6 +178,7 @@ public:
NS_IMETHOD GetDomainLookupStart(mozilla::TimeStamp *aDomainLookupStart) override;
NS_IMETHOD GetDomainLookupEnd(mozilla::TimeStamp *aDomainLookupEnd) override;
NS_IMETHOD GetConnectStart(mozilla::TimeStamp *aConnectStart) override;
NS_IMETHOD GetSecureConnectionStart(mozilla::TimeStamp *aSecureConnectionStart) override;
NS_IMETHOD GetConnectEnd(mozilla::TimeStamp *aConnectEnd) override;
NS_IMETHOD GetRequestStart(mozilla::TimeStamp *aRequestStart) override;
NS_IMETHOD GetResponseStart(mozilla::TimeStamp *aResponseStart) override;

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

@ -539,8 +539,15 @@ npnComplete:
mNPNComplete = true;
mTransaction->OnTransportStatus(mSocketTransport,
NS_NET_STATUS_TLS_HANDSHAKE_ENDED,
0);
NS_NET_STATUS_TLS_HANDSHAKE_ENDED, 0);
// this is happening after the bootstrap was originally written to. so update it.
if (mBootstrappedTimings.secureConnectionStart.IsNull() &&
!mBootstrappedTimings.connectEnd.IsNull()) {
mBootstrappedTimings.secureConnectionStart = mBootstrappedTimings.connectEnd;
mBootstrappedTimings.connectEnd = TimeStamp::Now();
}
if (mWaitingFor0RTTResponse) {
// Didn't get 0RTT OK, back out of the "attempting 0RTT" state
mWaitingFor0RTTResponse = false;
@ -584,8 +591,14 @@ nsHttpConnection::Activate(nsAHttpTransaction *trans, uint32_t caps, int32_t pri
LOG(("nsHttpConnection::Activate [this=%p trans=%p caps=%x]\n",
this, trans, caps));
if (!trans->IsNullTransaction() && !mFastOpen)
if (!mExperienced && !trans->IsNullTransaction() && !mFastOpen) {
mExperienced = true;
nsHttpTransaction *hTrans = trans->QueryHttpTransaction();
if (hTrans) {
hTrans->BootstrapTimings(mBootstrappedTimings);
}
mBootstrappedTimings = TimingStruct();
}
mTransactionCaps = caps;
mPriority = pri;
@ -2379,5 +2392,11 @@ nsHttpConnection::SetFastOpen(bool aFastOpen)
}
}
void
nsHttpConnection::BootstrapTimings(TimingStruct times)
{
mBootstrappedTimings = times;
}
} // namespace net
} // namespace mozilla

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

@ -16,6 +16,7 @@
#include "TunnelUtils.h"
#include "mozilla/Mutex.h"
#include "ARefBase.h"
#include "TimingStruct.h"
#include "nsIAsyncInputStream.h"
#include "nsIAsyncOutputStream.h"
@ -400,6 +401,11 @@ private:
bool mForceSendDuringFastOpenPending;
bool mReceivedSocketWouldBlockDuringFastOpen;
public:
void BootstrapTimings(TimingStruct times);
private:
TimingStruct mBootstrappedTimings;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsHttpConnection, NS_HTTPCONNECTION_IID)

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

@ -4415,6 +4415,11 @@ nsHalfOpenSocket::SetupConn(nsIAsyncOutputStream *out,
LOG(("nsHalfOpenSocket::SetupConn "
"Created new nshttpconnection %p\n", conn.get()));
NullHttpTransaction *nullTrans = mTransaction->QueryNullTransaction();
if (nullTrans) {
conn->BootstrapTimings(nullTrans->Timings());
}
// Some capabilities are needed before a transaciton actually gets
// scheduled (e.g. how to negotiate false start)
conn->SetTransactionCaps(mTransaction->Caps());
@ -4634,7 +4639,7 @@ nsHttpConnectionMgr::nsHalfOpenSocket::OnTransportStatus(nsITransport *trans,
if ((trans == mSocketTransport) ||
((trans == mBackupTransport) && (status == NS_NET_STATUS_CONNECTED_TO) &&
info)) {
// Send this status event only if the transaction is still panding,
// Send this status event only if the transaction is still pending,
// i.e. it has not found a free already connected socket.
// Sockets in halfOpen state can only get following events:
// NS_NET_STATUS_RESOLVING_HOST, NS_NET_STATUS_RESOLVED_HOST,

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

@ -578,6 +578,14 @@ nsHttpTransaction::OnTransportStatus(nsITransport* transport,
} else if (status == NS_NET_STATUS_CONNECTED_TO) {
SetConnectEnd(TimeStamp::Now(), true);
} else if (status == NS_NET_STATUS_TLS_HANDSHAKE_ENDED) {
{
// before overwriting connectEnd, copy it to secureConnectionStart
MutexAutoLock lock(mLock);
if (mTimings.secureConnectionStart.IsNull() &&
!mTimings.connectEnd.IsNull()) {
mTimings.secureConnectionStart = mTimings.connectEnd;
}
}
SetConnectEnd(TimeStamp::Now(), false);
} else if (status == NS_NET_STATUS_SENDING_TO) {
// Set the timestamp to Now(), only if it null
@ -1947,6 +1955,13 @@ nsHttpTransaction::Timings()
return timings;
}
void
nsHttpTransaction::BootstrapTimings(TimingStruct times)
{
mozilla::MutexAutoLock lock(mLock);
mTimings = times;
}
void
nsHttpTransaction::SetDomainLookupStart(mozilla::TimeStamp timeStamp, bool onlyIfNull)
{
@ -2038,6 +2053,13 @@ nsHttpTransaction::GetConnectStart()
return mTimings.connectStart;
}
mozilla::TimeStamp
nsHttpTransaction::GetSecureConnectionStart()
{
mozilla::MutexAutoLock lock(mLock);
return mTimings.secureConnectionStart;
}
mozilla::TimeStamp
nsHttpTransaction::GetConnectEnd()
{

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

@ -148,6 +148,7 @@ public:
// Locked methods to get and set timing info
const TimingStruct Timings();
void BootstrapTimings(TimingStruct times);
void SetDomainLookupStart(mozilla::TimeStamp timeStamp, bool onlyIfNull = false);
void SetDomainLookupEnd(mozilla::TimeStamp timeStamp, bool onlyIfNull = false);
void SetConnectStart(mozilla::TimeStamp timeStamp, bool onlyIfNull = false);
@ -159,6 +160,8 @@ public:
mozilla::TimeStamp GetDomainLookupStart();
mozilla::TimeStamp GetDomainLookupEnd();
mozilla::TimeStamp GetConnectStart();
mozilla::TimeStamp GetSecureConnectionStart();
mozilla::TimeStamp GetConnectEnd();
mozilla::TimeStamp GetRequestStart();
mozilla::TimeStamp GetResponseStart();

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

@ -1,11 +1,5 @@
[idlharness.html]
type: testharness
[PerformanceTiming interface: attribute secureConnectionStart]
expected: FAIL
[PerformanceTiming interface: window.performance.timing must inherit property "secureConnectionStart" with the proper type (10)]
expected: FAIL
[Performance interface: existence and properties of interface object]
expected: FAIL

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

@ -1,8 +0,0 @@
[invoke_with_timing_attributes.html]
type: testharness
[performance.mark should throw if used with timing attribute secureConnectionStart]
expected: FAIL
[performance.measure should throw if used with timing attribute secureConnectionStart]
expected: FAIL

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

@ -1,5 +0,0 @@
[mark_exceptions.html]
type: testharness
[window.performance.mark("secureConnectionStart") throws a SyntaxError exception.]
expected: FAIL

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

@ -1900,13 +1900,25 @@
"n_buckets": 50,
"description": "HTTP page channel: DNS lookup time (ms)"
},
"HTTP_PAGE_TCP_CONNECTION": {
"HTTP_PAGE_TLS_HANDSHAKE": {
"record_in_processes": ["main", "content"],
"expires_in_version": "never",
"alert_emails": ["necko@mozilla.com", "pmcmanus@mozilla.com"],
"bug_numbers": [772589],
"kind": "exponential",
"high": 30000,
"n_buckets": 50,
"description": "HTTP page channel: TCP connection setup (ms)"
"description": "HTTP page channel: After TCP SYN to Ready for HTTP (ms)"
},
"HTTP_PAGE_TCP_CONNECTION_2": {
"record_in_processes": ["main", "content"],
"expires_in_version": "never",
"alert_emails": ["necko@mozilla.com", "pmcmanus@mozilla.com"],
"bug_numbers": [772589],
"kind": "exponential",
"high": 30000,
"n_buckets": 50,
"description": "HTTP page channel: TCP SYN to Ready for HTTP (ms)"
},
"HTTP_PAGE_OPEN_TO_FIRST_SENT": {
"record_in_processes": ["main", "content"],
@ -2036,13 +2048,25 @@
"n_buckets": 50,
"description": "HTTP subitem channel: DNS lookup time (ms)"
},
"HTTP_SUB_TCP_CONNECTION": {
"HTTP_SUB_TLS_HANDSHAKE": {
"record_in_processes": ["main", "content"],
"expires_in_version": "never",
"alert_emails": ["necko@mozilla.com", "pmcmanus@mozilla.com"],
"bug_numbers": [772589],
"kind": "exponential",
"high": 30000,
"n_buckets": 50,
"description": "HTTP subitem channel: After TCP SYN to Ready for HTTP (ms)"
},
"HTTP_SUB_TCP_CONNECTION_2": {
"record_in_processes": ["main", "content"],
"alert_emails": ["necko@mozilla.com", "pmcmanus@mozilla.com"],
"bug_numbers": [772589],
"expires_in_version": "never",
"kind": "exponential",
"high": 30000,
"n_buckets": 50,
"description": "HTTP subitem channel: TCP connection setup (ms)"
"description": "HTTP subitem channel: TCP SYN to Ready for HTTP (ms)"
},
"HTTP_SUB_OPEN_TO_FIRST_SENT": {
"record_in_processes": ["main", "content"],

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

@ -303,7 +303,6 @@
"HTTP_PAGE_OPEN_TO_FIRST_RECEIVED",
"HTTP_PAGE_OPEN_TO_FIRST_SENT",
"HTTP_PAGE_REVALIDATION",
"HTTP_PAGE_TCP_CONNECTION",
"HTTP_PROXY_TYPE",
"HTTP_REQUEST_PER_CONN",
"HTTP_REQUEST_PER_PAGE",
@ -326,7 +325,6 @@
"HTTP_SUB_OPEN_TO_FIRST_RECEIVED",
"HTTP_SUB_OPEN_TO_FIRST_SENT",
"HTTP_SUB_REVALIDATION",
"HTTP_SUB_TCP_CONNECTION",
"HTTP_TRANSACTION_USE_ALTSVC",
"HTTP_TRANSACTION_USE_ALTSVC_OE",
"INNERWINDOWS_WITH_MUTATION_LISTENERS",
@ -1011,7 +1009,6 @@
"HTTP_PAGE_OPEN_TO_FIRST_RECEIVED",
"HTTP_PAGE_OPEN_TO_FIRST_SENT",
"HTTP_PAGE_REVALIDATION",
"HTTP_PAGE_TCP_CONNECTION",
"HTTP_PROXY_TYPE",
"HTTP_REQUEST_PER_CONN",
"HTTP_REQUEST_PER_PAGE",
@ -1036,7 +1033,6 @@
"HTTP_SUB_OPEN_TO_FIRST_RECEIVED",
"HTTP_SUB_OPEN_TO_FIRST_SENT",
"HTTP_SUB_REVALIDATION",
"HTTP_SUB_TCP_CONNECTION",
"HTTP_TRANSACTION_USE_ALTSVC",
"HTTP_TRANSACTION_USE_ALTSVC_OE",
"IMAGE_DECODE_CHUNKS",