DevTools - network - implement the secureConnectionStart property for the PerformanceTiming

https://github.com/MoonchildProductions/moebius/pull/116
("/testing" and "/toolkit" in in the previous commit)
This commit is contained in:
janekptacijarabaci 2018-03-01 11:52:50 +01:00 • committed by Roy Tam
commit 54f2e6eafd
32 changed files with 263 additions and 13 deletions

View file

@ -581,6 +581,11 @@ netmonitor.timings.blocked=Blocked:
# in a "dns" state. # in a "dns" state.
netmonitor.timings.dns=DNS resolution: 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 # LOCALIZATION NOTE (netmonitor.timings.connect): This is the label displayed
# in the network details timings tab identifying the amount of time spent # in the network details timings tab identifying the amount of time spent
# in a "connect" state. # in a "connect" state.

View file

@ -963,7 +963,7 @@ NetworkDetailsView.prototype = {
if (!response) { if (!response) {
return; return;
} }
let { blocked, dns, connect, send, wait, receive } = response.timings; let { blocked, dns, connect, ssl, send, wait, receive } = response.timings;
let tabboxWidth = $("#details-pane").getAttribute("width"); let tabboxWidth = $("#details-pane").getAttribute("width");
@ -988,6 +988,11 @@ NetworkDetailsView.prototype = {
$("#timings-summary-connect .requests-menu-timings-total") $("#timings-summary-connect .requests-menu-timings-total")
.setAttribute("value", L10N.getFormatStr("networkMenu.totalMS", connect)); .setAttribute("value", L10N.getFormatStr("networkMenu.totalMS", connect));
$("#timings-summary-ssl .requests-menu-timings-box")
.setAttribute("width", ssl * scale);
$("#timings-summary-ssl .requests-menu-timings-total")
.setAttribute("value", L10N.getFormatStr("networkMenu.totalMS", ssl));
$("#timings-summary-send .requests-menu-timings-box") $("#timings-summary-send .requests-menu-timings-box")
.setAttribute("width", send * scale); .setAttribute("width", send * scale);
$("#timings-summary-send .requests-menu-timings-total") $("#timings-summary-send .requests-menu-timings-total")
@ -1007,6 +1012,8 @@ NetworkDetailsView.prototype = {
.style.transform = "translateX(" + (scale * blocked) + "px)"; .style.transform = "translateX(" + (scale * blocked) + "px)";
$("#timings-summary-connect .requests-menu-timings-box") $("#timings-summary-connect .requests-menu-timings-box")
.style.transform = "translateX(" + (scale * (blocked + dns)) + "px)"; .style.transform = "translateX(" + (scale * (blocked + dns)) + "px)";
$("#timings-summary-ssl .requests-menu-timings-box")
.style.transform = "translateX(" + (scale * blocked) + "px)";
$("#timings-summary-send .requests-menu-timings-box") $("#timings-summary-send .requests-menu-timings-box")
.style.transform = .style.transform =
"translateX(" + (scale * (blocked + dns + connect)) + "px)"; "translateX(" + (scale * (blocked + dns + connect)) + "px)";
@ -1022,6 +1029,8 @@ NetworkDetailsView.prototype = {
.style.transform = "translateX(" + (scale * blocked) + "px)"; .style.transform = "translateX(" + (scale * blocked) + "px)";
$("#timings-summary-connect .requests-menu-timings-total") $("#timings-summary-connect .requests-menu-timings-total")
.style.transform = "translateX(" + (scale * (blocked + dns)) + "px)"; .style.transform = "translateX(" + (scale * (blocked + dns)) + "px)";
$("#timings-summary-ssl .requests-menu-timings-total")
.style.transform = "translateX(" + (scale * blocked) + "px)";
$("#timings-summary-send .requests-menu-timings-total") $("#timings-summary-send .requests-menu-timings-total")
.style.transform = .style.transform =
"translateX(" + (scale * (blocked + dns + connect)) + "px)"; "translateX(" + (scale * (blocked + dns + connect)) + "px)";

View file

@ -478,6 +478,14 @@
<hbox class="requests-menu-timings-box connect"/> <hbox class="requests-menu-timings-box connect"/>
<label class="plain requests-menu-timings-total"/> <label class="plain requests-menu-timings-total"/>
</hbox> </hbox>
<hbox id="timings-summary-ssl"
class="tabpanel-summary-container"
align="center">
<label class="plain tabpanel-summary-label"
data-localization="content=netmonitor.timings.ssl"/>
<hbox class="requests-menu-timings-box ssl"/>
<label class="plain requests-menu-timings-total"/>
</hbox>
<hbox id="timings-summary-send" <hbox id="timings-summary-send"
class="tabpanel-summary-container" class="tabpanel-summary-container"
align="center"> align="center">

View file

@ -1099,7 +1099,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
*/ */
_createWaterfallView: function (item, timings, fromCache) { _createWaterfallView: function (item, timings, fromCache) {
let { target } = item; let { target } = item;
let sections = ["blocked", "dns", "connect", "send", "wait", "receive"]; let sections = ["blocked", "dns", "connect", "ssl", "send", "wait", "receive"];
// Skipping "blocked" because it doesn't work yet. // Skipping "blocked" because it doesn't work yet.
let timingsNode = $(".requests-menu-timings", target); let timingsNode = $(".requests-menu-timings", target);

View file

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

View file

@ -59,6 +59,7 @@
--timing-blocked-color: rgba(235, 83, 104, 0.8); --timing-blocked-color: rgba(235, 83, 104, 0.8);
--timing-dns-color: rgba(223, 128, 255, 0.8); /* pink */ --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-connect-color: rgba(217, 102, 41, 0.8); /* orange */
--timing-send-color: rgba(70, 175, 227, 0.8); /* light blue */ --timing-send-color: rgba(70, 175, 227, 0.8); /* light blue */
--timing-wait-color: rgba(94, 136, 176, 0.8); /* blue grey */ --timing-wait-color: rgba(94, 136, 176, 0.8); /* blue grey */
@ -74,6 +75,7 @@
--timing-blocked-color: rgba(235, 83, 104, 0.8); --timing-blocked-color: rgba(235, 83, 104, 0.8);
--timing-dns-color: rgba(223, 128, 255, 0.8); /* pink */ --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-connect-color: rgba(217, 102, 41, 0.8); /* orange */
--timing-send-color: rgba(0, 136, 204, 0.8); /* blue */ --timing-send-color: rgba(0, 136, 204, 0.8); /* blue */
--timing-wait-color: rgba(95, 136, 176, 0.8); /* blue grey */ --timing-wait-color: rgba(95, 136, 176, 0.8); /* blue grey */
@ -505,6 +507,10 @@
background-color: var(--timing-connect-color); background-color: var(--timing-connect-color);
} }
.requests-menu-timings-box.ssl {
background-color: var(--timing-ssl-color);
}
.requests-menu-timings-box.send { .requests-menu-timings-box.send {
background-color: var(--timing-send-color); background-color: var(--timing-send-color);
} }

View file

@ -732,7 +732,9 @@ NetworkMonitor.prototype = {
0x804b0004: "STATUS_CONNECTED_TO", 0x804b0004: "STATUS_CONNECTED_TO",
0x804b0005: "STATUS_SENDING_TO", 0x804b0005: "STATUS_SENDING_TO",
0x804b000a: "STATUS_WAITING_FOR", 0x804b000a: "STATUS_WAITING_FOR",
0x804b0006: "STATUS_RECEIVING_FROM" 0x804b0006: "STATUS_RECEIVING_FROM",
0x804b000c: "STATUS_TLS_STARTING",
0x804b000d: "STATUS_TLS_ENDING"
}, },
httpDownloadActivities: [ httpDownloadActivities: [
@ -1406,6 +1408,7 @@ NetworkMonitor.prototype = {
timings: { timings: {
blocked: 0, blocked: 0,
dns: 0, dns: 0,
ssl: 0,
connect: 0, connect: 0,
send: 0, send: 0,
wait: 0, wait: 0,
@ -1440,6 +1443,36 @@ NetworkMonitor.prototype = {
harTimings.connect = -1; 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) { if (timings.STATUS_SENDING_TO) {
harTimings.send = timings.STATUS_SENDING_TO.last - timings.STATUS_SENDING_TO.first; harTimings.send = timings.STATUS_SENDING_TO.last - timings.STATUS_SENDING_TO.first;
} else if (timings.REQUEST_HEADER && timings.REQUEST_BODY_SENT) { } else if (timings.REQUEST_HEADER && timings.REQUEST_BODY_SENT) {

View file

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

View file

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

View file

@ -63,12 +63,40 @@ PerformanceTiming::InitializeTimingInfo(nsITimedChannel* aChannel)
aChannel->GetDomainLookupStart(&mDomainLookupStart); aChannel->GetDomainLookupStart(&mDomainLookupStart);
aChannel->GetDomainLookupEnd(&mDomainLookupEnd); aChannel->GetDomainLookupEnd(&mDomainLookupEnd);
aChannel->GetConnectStart(&mConnectStart); aChannel->GetConnectStart(&mConnectStart);
aChannel->GetSecureConnectionStart(&mSecureConnectionStart);
aChannel->GetConnectEnd(&mConnectEnd); aChannel->GetConnectEnd(&mConnectEnd);
aChannel->GetRequestStart(&mRequestStart); aChannel->GetRequestStart(&mRequestStart);
aChannel->GetResponseStart(&mResponseStart); aChannel->GetResponseStart(&mResponseStart);
aChannel->GetCacheReadStart(&mCacheReadStart); aChannel->GetCacheReadStart(&mCacheReadStart);
aChannel->GetResponseEnd(&mResponseEnd); aChannel->GetResponseEnd(&mResponseEnd);
aChannel->GetCacheReadEnd(&mCacheReadEnd); 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;
}
}
} }
} }
@ -273,6 +301,22 @@ PerformanceTiming::ConnectStart()
return static_cast<int64_t>(ConnectStartHighRes()); return static_cast<int64_t>(ConnectStartHighRes());
} }
DOMHighResTimeStamp
PerformanceTiming::SecureConnectionStartHighRes()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
return mZeroTime;
}
return mSecureConnectionStart.IsNull() ? mZeroTime
: TimeStampToDOMHighRes(mSecureConnectionStart);
}
DOMTimeMilliSec
PerformanceTiming::SecureConnectionStart()
{
return static_cast<int64_t>(SecureConnectionStartHighRes());
}
DOMHighResTimeStamp DOMHighResTimeStamp
PerformanceTiming::ConnectEndHighRes() PerformanceTiming::ConnectEndHighRes()
{ {

View file

@ -161,6 +161,7 @@ public:
DOMHighResTimeStamp DomainLookupStartHighRes(); DOMHighResTimeStamp DomainLookupStartHighRes();
DOMHighResTimeStamp DomainLookupEndHighRes(); DOMHighResTimeStamp DomainLookupEndHighRes();
DOMHighResTimeStamp ConnectStartHighRes(); DOMHighResTimeStamp ConnectStartHighRes();
DOMHighResTimeStamp SecureConnectionStartHighRes();
DOMHighResTimeStamp ConnectEndHighRes(); DOMHighResTimeStamp ConnectEndHighRes();
DOMHighResTimeStamp RequestStartHighRes(); DOMHighResTimeStamp RequestStartHighRes();
DOMHighResTimeStamp ResponseStartHighRes(); DOMHighResTimeStamp ResponseStartHighRes();
@ -173,6 +174,7 @@ public:
DOMTimeMilliSec DomainLookupStart(); DOMTimeMilliSec DomainLookupStart();
DOMTimeMilliSec DomainLookupEnd(); DOMTimeMilliSec DomainLookupEnd();
DOMTimeMilliSec ConnectStart(); DOMTimeMilliSec ConnectStart();
DOMTimeMilliSec SecureConnectionStart();
DOMTimeMilliSec ConnectEnd(); DOMTimeMilliSec ConnectEnd();
DOMTimeMilliSec RequestStart(); DOMTimeMilliSec RequestStart();
DOMTimeMilliSec ResponseStart(); DOMTimeMilliSec ResponseStart();
@ -255,6 +257,7 @@ private:
TimeStamp mDomainLookupStart; TimeStamp mDomainLookupStart;
TimeStamp mDomainLookupEnd; TimeStamp mDomainLookupEnd;
TimeStamp mConnectStart; TimeStamp mConnectStart;
TimeStamp mSecureConnectionStart;
TimeStamp mConnectEnd; TimeStamp mConnectEnd;
TimeStamp mRequestStart; TimeStamp mRequestStart;
TimeStamp mResponseStart; TimeStamp mResponseStart;

View file

@ -21,8 +21,7 @@ interface PerformanceTiming {
readonly attribute unsigned long long domainLookupEnd; readonly attribute unsigned long long domainLookupEnd;
readonly attribute unsigned long long connectStart; readonly attribute unsigned long long connectStart;
readonly attribute unsigned long long connectEnd; 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 requestStart;
readonly attribute unsigned long long responseStart; readonly attribute unsigned long long responseStart;
readonly attribute unsigned long long responseEnd; readonly attribute unsigned long long responseEnd;

View file

@ -162,6 +162,8 @@ interface nsISocketTransport : nsITransport
const unsigned long STATUS_SENDING_TO = 0x804b0005; const unsigned long STATUS_SENDING_TO = 0x804b0005;
const unsigned long STATUS_WAITING_FOR = 0x804b000a; const unsigned long STATUS_WAITING_FOR = 0x804b000a;
const unsigned long STATUS_RECEIVING_FROM = 0x804b0006; 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 * connectionFlags is a bitmask that can be used to modify underlying

View file

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

View file

@ -888,6 +888,11 @@ nsLoadGroup::TelemetryReportChannel(nsITimedChannel *aTimedChannel,
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return; return;
TimeStamp secureConnectionStart;
rv = aTimedChannel->GetSecureConnectionStart(&secureConnectionStart);
if (NS_FAILED(rv))
return;
TimeStamp connectEnd; TimeStamp connectEnd;
rv = aTimedChannel->GetConnectEnd(&connectEnd); rv = aTimedChannel->GetConnectEnd(&connectEnd);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
@ -921,9 +926,15 @@ nsLoadGroup::TelemetryReportChannel(nsITimedChannel *aTimedChannel,
domainLookupStart, domainLookupEnd); \ domainLookupStart, domainLookupEnd); \
} \ } \
\ \
if (!secureConnectionStart.IsNull() && !connectEnd.IsNull()) { \
Telemetry::AccumulateTimeDelta( \
Telemetry::HTTP_##prefix##_TLS_HANDSHAKE, \
secureConnectionStart, connectEnd); \
} \
\
if (!connectStart.IsNull() && !connectEnd.IsNull()) { \ if (!connectStart.IsNull() && !connectEnd.IsNull()) { \
Telemetry::AccumulateTimeDelta( \ Telemetry::AccumulateTimeDelta( \
Telemetry::HTTP_##prefix##_TCP_CONNECTION, \ Telemetry::HTTP_##prefix##_TCP_CONNECTION_2, \
connectStart, connectEnd); \ connectStart, connectEnd); \
} \ } \
\ \

View file

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

View file

@ -2277,6 +2277,15 @@ Http2Session::OnTransportStatus(nsITransport* aTransport,
case NS_NET_STATUS_TLS_HANDSHAKE_ENDED: case NS_NET_STATUS_TLS_HANDSHAKE_ENDED:
{ {
Http2Stream *target = mStreamIDHash.Get(1); Http2Stream *target = mStreamIDHash.Get(1);
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; nsAHttpTransaction *transaction = target ? target->Transaction() : nullptr;
if (transaction) if (transaction)
transaction->OnTransportStatus(aTransport, aStatus, aProgress); transaction->OnTransportStatus(aTransport, aStatus, aProgress);

View file

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

View file

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

View file

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

View file

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

View file

@ -162,6 +162,30 @@ void
NullHttpTransaction::OnTransportStatus(nsITransport* transport, NullHttpTransaction::OnTransportStatus(nsITransport* transport,
nsresult status, int64_t progress) 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) { if (mActivityDistributor) {
NS_DispatchToMainThread(new CallObserveActivity(mActivityDistributor, NS_DispatchToMainThread(new CallObserveActivity(mActivityDistributor,
mConnectionInfo->GetOrigin(), mConnectionInfo->GetOrigin(),

View file

@ -9,6 +9,7 @@
#include "nsAHttpTransaction.h" #include "nsAHttpTransaction.h"
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "TimingStruct.h"
// This is the minimal nsAHttpTransaction implementation. A NullHttpTransaction // This is the minimal nsAHttpTransaction implementation. A NullHttpTransaction
// can be used to drive connection level semantics (such as SSL handshakes // can be used to drive connection level semantics (such as SSL handshakes
@ -49,6 +50,8 @@ public:
return PR_SecondsToInterval(15); return PR_SecondsToInterval(15);
} }
TimingStruct Timings() { return mTimings; }
protected: protected:
virtual ~NullHttpTransaction(); virtual ~NullHttpTransaction();
@ -68,6 +71,7 @@ private:
Atomic<uint32_t> mCapsToClear; Atomic<uint32_t> mCapsToClear;
bool mIsDone; bool mIsDone;
bool mClaimed; bool mClaimed;
TimingStruct mTimings;
protected: protected:
RefPtr<nsAHttpConnection> mConnection; RefPtr<nsAHttpConnection> mConnection;

View file

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

View file

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

View file

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

View file

@ -527,8 +527,15 @@ npnComplete:
mNPNComplete = true; mNPNComplete = true;
mTransaction->OnTransportStatus(mSocketTransport, mTransaction->OnTransportStatus(mSocketTransport,
NS_NET_STATUS_TLS_HANDSHAKE_ENDED, NS_NET_STATUS_TLS_HANDSHAKE_ENDED, 0);
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) { if (mWaitingFor0RTTResponse) {
// Didn't get 0RTT OK, back out of the "attempting 0RTT" state // Didn't get 0RTT OK, back out of the "attempting 0RTT" state
mWaitingFor0RTTResponse = false; mWaitingFor0RTTResponse = false;
@ -572,8 +579,14 @@ nsHttpConnection::Activate(nsAHttpTransaction *trans, uint32_t caps, int32_t pri
LOG(("nsHttpConnection::Activate [this=%p trans=%p caps=%x]\n", LOG(("nsHttpConnection::Activate [this=%p trans=%p caps=%x]\n",
this, trans, caps)); this, trans, caps));
if (!trans->IsNullTransaction()) if (!mExperienced && !trans->IsNullTransaction()) {
mExperienced = true; mExperienced = true;
nsHttpTransaction *hTrans = trans->QueryHttpTransaction();
if (hTrans) {
hTrans->BootstrapTimings(mBootstrappedTimings);
}
mBootstrappedTimings = TimingStruct();
}
mTransactionCaps = caps; mTransactionCaps = caps;
mPriority = pri; mPriority = pri;
@ -2414,5 +2427,11 @@ nsHttpConnection::CheckForTraffic(bool check)
} }
} }
void
nsHttpConnection::BootstrapTimings(TimingStruct times)
{
mBootstrappedTimings = times;
}
} // namespace net } // namespace net
} // namespace mozilla } // namespace mozilla

View file

@ -16,6 +16,7 @@
#include "TunnelUtils.h" #include "TunnelUtils.h"
#include "mozilla/Mutex.h" #include "mozilla/Mutex.h"
#include "ARefBase.h" #include "ARefBase.h"
#include "TimingStruct.h"
#include "nsIAsyncInputStream.h" #include "nsIAsyncInputStream.h"
#include "nsIAsyncOutputStream.h" #include "nsIAsyncOutputStream.h"
@ -379,6 +380,11 @@ private:
bool mEarlyDataNegotiated; //Only used for telemetry bool mEarlyDataNegotiated; //Only used for telemetry
nsCString mEarlyNegotiatedALPN; nsCString mEarlyNegotiatedALPN;
bool mDid0RTTSpdy; bool mDid0RTTSpdy;
public:
void BootstrapTimings(TimingStruct times);
private:
TimingStruct mBootstrappedTimings;
}; };
} // namespace net } // namespace net

View file

@ -3314,6 +3314,11 @@ nsHalfOpenSocket::OnOutputStreamReady(nsIAsyncOutputStream *out)
LOG(("nsHalfOpenSocket::OnOutputStreamReady " LOG(("nsHalfOpenSocket::OnOutputStreamReady "
"Created new nshttpconnection %p\n", conn.get())); "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 // Some capabilities are needed before a transaciton actually gets
// scheduled (e.g. how to negotiate false start) // scheduled (e.g. how to negotiate false start)
conn->SetTransactionCaps(mTransaction->Caps()); conn->SetTransactionCaps(mTransaction->Caps());

View file

@ -623,6 +623,14 @@ nsHttpTransaction::OnTransportStatus(nsITransport* transport,
} else if (status == NS_NET_STATUS_CONNECTED_TO) { } else if (status == NS_NET_STATUS_CONNECTED_TO) {
SetConnectEnd(TimeStamp::Now(), true); SetConnectEnd(TimeStamp::Now(), true);
} else if (status == NS_NET_STATUS_TLS_HANDSHAKE_ENDED) { } 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); SetConnectEnd(TimeStamp::Now(), false);
} }
} }
@ -2135,6 +2143,13 @@ nsHttpTransaction::Timings()
return timings; return timings;
} }
void
nsHttpTransaction::BootstrapTimings(TimingStruct times)
{
mozilla::MutexAutoLock lock(mLock);
mTimings = times;
}
void void
nsHttpTransaction::SetDomainLookupStart(mozilla::TimeStamp timeStamp, bool onlyIfNull) nsHttpTransaction::SetDomainLookupStart(mozilla::TimeStamp timeStamp, bool onlyIfNull)
{ {
@ -2226,6 +2241,13 @@ nsHttpTransaction::GetConnectStart()
return mTimings.connectStart; return mTimings.connectStart;
} }
mozilla::TimeStamp
nsHttpTransaction::GetSecureConnectionStart()
{
mozilla::MutexAutoLock lock(mLock);
return mTimings.secureConnectionStart;
}
mozilla::TimeStamp mozilla::TimeStamp
nsHttpTransaction::GetConnectEnd() nsHttpTransaction::GetConnectEnd()
{ {

View file

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

View file

@ -50,6 +50,7 @@ netmonitor.properties:netmonitor.response.dimensions = netmonitor.dtd:netmonitor
netmonitor.properties:netmonitor.response.mime = netmonitor.dtd:netmonitorUI.response.mime netmonitor.properties:netmonitor.response.mime = netmonitor.dtd:netmonitorUI.response.mime
netmonitor.properties:netmonitor.timings.blocked = netmonitor.dtd:netmonitorUI.timings.blocked netmonitor.properties:netmonitor.timings.blocked = netmonitor.dtd:netmonitorUI.timings.blocked
netmonitor.properties:netmonitor.timings.dns = netmonitor.dtd:netmonitorUI.timings.dns netmonitor.properties:netmonitor.timings.dns = netmonitor.dtd:netmonitorUI.timings.dns
netmonitor.properties:netmonitor.timings.ssl = netmonitor.dtd:netmonitorUI.timings.ssl
netmonitor.properties:netmonitor.timings.connect = netmonitor.dtd:netmonitorUI.timings.connect netmonitor.properties:netmonitor.timings.connect = netmonitor.dtd:netmonitorUI.timings.connect
netmonitor.properties:netmonitor.timings.send = netmonitor.dtd:netmonitorUI.timings.send netmonitor.properties:netmonitor.timings.send = netmonitor.dtd:netmonitorUI.timings.send
netmonitor.properties:netmonitor.timings.wait = netmonitor.dtd:netmonitorUI.timings.wait netmonitor.properties:netmonitor.timings.wait = netmonitor.dtd:netmonitorUI.timings.wait