Modified: trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp (277224 => 277225)
--- trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp 2021-05-08 07:32:45 UTC (rev 277224)
+++ trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp 2021-05-08 10:43:06 UTC (rev 277225)
@@ -65,7 +65,9 @@
auto request = requestWithCredentials;
if (request.url().protocolIsInHTTPFamily()) {
+#if USE(SOUP2)
m_networkLoadMetrics.fetchStart = MonotonicTime::now().secondsSinceEpoch();
+#endif
auto url = ""
if (m_storedCredentialsPolicy == StoredCredentialsPolicy::Use) {
m_user = url.user();
@@ -139,6 +141,9 @@
}
unsigned messageFlags = SOUP_MESSAGE_NO_REDIRECT;
+#if !USE(SOUP2)
+ messageFlags |= SOUP_MESSAGE_COLLECT_METRICS;
+#endif
if (m_shouldContentSniff == ContentSniffingPolicy::DoNotSniffContent)
soup_message_disable_feature(m_soupMessage.get(), SOUP_TYPE_CONTENT_SNIFFER);
if (m_user.isEmpty() && m_password.isEmpty() && m_storedCredentialsPolicy == StoredCredentialsPolicy::DoNotUse) {
@@ -192,11 +197,16 @@
g_signal_connect(m_soupMessage.get(), "wrote-body-data", G_CALLBACK(wroteBodyDataCallback), this);
#if USE(SOUP2)
g_signal_connect(static_cast<NetworkSessionSoup&>(*m_session).soupSession(), "authenticate", G_CALLBACK(authenticateCallback), this);
+ g_signal_connect(m_soupMessage.get(), "network-event", G_CALLBACK(networkEventCallback), this);
#else
g_signal_connect(m_soupMessage.get(), "authenticate", G_CALLBACK(authenticateCallback), this);
g_signal_connect(m_soupMessage.get(), "accept-certificate", G_CALLBACK(acceptCertificateCallback), this);
+ if (shouldCaptureExtraNetworkLoadMetrics()) {
+ g_signal_connect(m_soupMessage.get(), "wrote-headers", G_CALLBACK(wroteHeadersCallback), this);
+ g_signal_connect(m_soupMessage.get(), "wrote-body", G_CALLBACK(wroteBodyCallback), this);
+ g_signal_connect(m_soupMessage.get(), "got-body", G_CALLBACK(gotBodyCallback), this);
+ }
#endif
- g_signal_connect(m_soupMessage.get(), "network-event", G_CALLBACK(networkEventCallback), this);
g_signal_connect(m_soupMessage.get(), "restarted", G_CALLBACK(restartedCallback), this);
g_signal_connect(m_soupMessage.get(), "starting", G_CALLBACK(startingCallback), this);
if (m_shouldContentSniff == ContentSniffingPolicy::SniffContent)
@@ -226,6 +236,13 @@
#if USE(SOUP2)
if (m_session)
soup_session_cancel_message(static_cast<NetworkSessionSoup&>(*m_session).soupSession(), m_soupMessage.get(), SOUP_STATUS_CANCELLED);
+#else
+ if (m_networkLoadMetrics.fetchStart && !m_networkLoadMetrics.responseEnd) {
+ auto* metrics = soup_message_get_metrics(m_soupMessage.get());
+ auto responseEnd = Seconds::fromMicroseconds(soup_message_metrics_get_response_end(metrics));
+ m_networkLoadMetrics.responseEnd = responseEnd ? responseEnd - m_networkLoadMetrics.fetchStart : Seconds(-1);
+ m_networkLoadMetrics.markComplete();
+ }
#endif
m_soupMessage = nullptr;
}
@@ -265,6 +282,12 @@
GRefPtr<GCancellable> protectCancellable(m_cancellable);
soup_session_send_async(static_cast<NetworkSessionSoup&>(*m_session).soupSession(), m_soupMessage.get(), RunLoopSourcePriority::AsyncIONetwork, m_cancellable.get(),
reinterpret_cast<GAsyncReadyCallback>(sendRequestCallback), new SendRequestData({ m_soupMessage, WTFMove(protectedThis) }));
+#if !USE(SOUP2)
+ if (!g_cancellable_is_cancelled(protectCancellable.get()) && !m_networkLoadMetrics.fetchStart) {
+ auto* metrics = soup_message_get_metrics(m_soupMessage.get());
+ m_networkLoadMetrics.fetchStart = Seconds::fromMicroseconds(soup_message_metrics_get_fetch_start(metrics));
+ }
+#endif
}
return;
}
@@ -420,7 +443,9 @@
else
m_inputStream = WTFMove(inputStream);
+#if USE(SOUP2)
m_networkLoadMetrics.responseStart = MonotonicTime::now().secondsSinceEpoch() - m_networkLoadMetrics.fetchStart;
+#endif
// FIXME: This cannot be eliminated until other code no longer relies on ResourceResponse's NetworkLoadMetrics.
m_response.setDeprecatedNetworkLoadMetrics(Box<NetworkLoadMetrics>::create(m_networkLoadMetrics));
@@ -480,8 +505,10 @@
void NetworkDataTaskSoup::dispatchDidCompleteWithError(const ResourceError& error)
{
+#if USE(SOUP2)
m_networkLoadMetrics.responseEnd = MonotonicTime::now().secondsSinceEpoch() - m_networkLoadMetrics.fetchStart;
m_networkLoadMetrics.markComplete();
+#endif
m_client->didCompleteWithError(error, m_networkLoadMetrics);
}
@@ -850,7 +877,14 @@
if (request.url().protocolIsInHTTPFamily()) {
if (isCrossOrigin) {
m_networkLoadMetrics = { };
+#if USE(SOUP2)
m_networkLoadMetrics.fetchStart = MonotonicTime::now().secondsSinceEpoch();
+#endif
+ } else {
+#if !USE(SOUP2)
+ m_networkLoadMetrics.responseEnd = { };
+ m_networkLoadMetrics.complete = false;
+#endif
}
applyAuthenticationToRequest(request);
@@ -1048,6 +1082,12 @@
m_credentialForPersistentStorage = Credential();
}
+#if !USE(SOUP2)
+ auto* metrics = soup_message_get_metrics(m_soupMessage.get());
+ auto responseStart = Seconds::fromMicroseconds(soup_message_metrics_get_response_start(metrics));
+ m_networkLoadMetrics.responseStart = responseStart - m_networkLoadMetrics.fetchStart;
+#endif
+
// Soup adds more headers to the request after starting signal is emitted, and got-headers
// is the first one we receive after starting, so we use it also to get information about the
// request headers.
@@ -1062,8 +1102,14 @@
m_networkLoadMetrics.requestHeaders = WTFMove(requestHeaders);
m_networkLoadMetrics.priority = toNetworkLoadPriority(soup_message_get_priority(m_soupMessage.get()));
-#if SOUP_CHECK_VERSION(2, 99, 4)
+#if !USE(SOUP2)
m_networkLoadMetrics.connectionIdentifier = String::number(soup_message_get_connection_id(m_soupMessage.get()));
+ auto* address = soup_message_get_remote_address(m_soupMessage.get());
+ if (G_IS_INET_SOCKET_ADDRESS(address)) {
+ GUniquePtr<char> ipAddress(g_inet_address_to_string(g_inet_socket_address_get_address(G_INET_SOCKET_ADDRESS(address))));
+ m_networkLoadMetrics.remoteAddress = makeString(ipAddress.get(), ':', g_inet_socket_address_get_port(G_INET_SOCKET_ADDRESS(address)));
+ }
+ m_networkLoadMetrics.responseHeaderBytesReceived = soup_message_metrics_get_response_header_bytes_received(metrics);
#endif
}
@@ -1070,6 +1116,42 @@
m_networkLoadMetrics.protocol = soupHTTPVersionToString(soup_message_get_http_version(m_soupMessage.get()));
}
+#if !USE(SOUP2)
+void NetworkDataTaskSoup::wroteHeadersCallback(SoupMessage* soupMessage, NetworkDataTaskSoup* task)
+{
+ if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client) {
+ task->clearRequest();
+ return;
+ }
+ ASSERT(task->m_soupMessage.get() == soupMessage);
+ auto* metrics = soup_message_get_metrics(soupMessage);
+ task->m_networkLoadMetrics.requestHeaderBytesSent = soup_message_metrics_get_request_header_bytes_sent(metrics);
+}
+
+void NetworkDataTaskSoup::wroteBodyCallback(SoupMessage* soupMessage, NetworkDataTaskSoup* task)
+{
+ if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client) {
+ task->clearRequest();
+ return;
+ }
+ ASSERT(task->m_soupMessage.get() == soupMessage);
+ auto* metrics = soup_message_get_metrics(soupMessage);
+ task->m_networkLoadMetrics.requestBodyBytesSent = soup_message_metrics_get_request_body_bytes_sent(metrics);
+}
+
+void NetworkDataTaskSoup::gotBodyCallback(SoupMessage* soupMessage, NetworkDataTaskSoup* task)
+{
+ if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client) {
+ task->clearRequest();
+ return;
+ }
+ ASSERT(task->m_soupMessage.get() == soupMessage);
+ auto* metrics = soup_message_get_metrics(soupMessage);
+ task->m_networkLoadMetrics.responseBodyBytesReceived = soup_message_metrics_get_response_body_bytes_received(metrics);
+ task->m_networkLoadMetrics.responseBodyDecodedSize = soup_message_metrics_get_response_body_size(metrics);
+}
+#endif
+
#if USE(SOUP2)
void NetworkDataTaskSoup::wroteBodyDataCallback(SoupMessage* soupMessage, SoupBuffer* buffer, NetworkDataTaskSoup* task)
#else
@@ -1240,6 +1322,7 @@
dispatchDidCompleteWithError(error);
}
+#if USE(SOUP2)
void NetworkDataTaskSoup::networkEventCallback(SoupMessage* soupMessage, GSocketClientEvent event, GIOStream* stream, NetworkDataTaskSoup* task)
{
if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client)
@@ -1279,11 +1362,9 @@
break;
case G_SOCKET_CLIENT_TLS_HANDSHAKING:
m_networkLoadMetrics.secureConnectionStart = deltaTime;
-#if USE(SOUP2)
RELEASE_ASSERT(G_IS_TLS_CONNECTION(stream));
g_object_set_data(G_OBJECT(stream), "wk-soup-message", m_soupMessage.get());
g_signal_connect(stream, "accept-certificate", G_CALLBACK(tlsConnectionAcceptCertificateCallback), this);
-#endif
break;
case G_SOCKET_CLIENT_TLS_HANDSHAKED:
break;
@@ -1295,6 +1376,7 @@
break;
}
}
+#endif
void NetworkDataTaskSoup::startingCallback(SoupMessage* soupMessage, NetworkDataTaskSoup* task)
{
@@ -1349,7 +1431,24 @@
void NetworkDataTaskSoup::didStartRequest()
{
+#if USE(SOUP2)
m_networkLoadMetrics.requestStart = MonotonicTime::now().secondsSinceEpoch() - m_networkLoadMetrics.fetchStart;
+#else
+ auto* metrics = soup_message_get_metrics(m_soupMessage.get());
+ auto domainLookupStart = Seconds::fromMicroseconds(soup_message_metrics_get_dns_start(metrics));
+ auto domainLookupEnd = Seconds::fromMicroseconds(soup_message_metrics_get_dns_end(metrics));
+ auto connectStart = Seconds::fromMicroseconds(soup_message_metrics_get_connect_start(metrics));
+ auto connectEnd = Seconds::fromMicroseconds(soup_message_metrics_get_connect_end(metrics));
+ auto secureConnectionStart = Seconds::fromMicroseconds(soup_message_metrics_get_tls_start(metrics));
+ auto requestStart = Seconds::fromMicroseconds(soup_message_metrics_get_request_start(metrics));
+
+ m_networkLoadMetrics.domainLookupStart = domainLookupStart ? domainLookupStart - m_networkLoadMetrics.fetchStart : Seconds(-1);
+ m_networkLoadMetrics.domainLookupEnd = domainLookupEnd ? domainLookupEnd - m_networkLoadMetrics.fetchStart : Seconds(-1);
+ m_networkLoadMetrics.connectStart = connectStart ? connectStart - m_networkLoadMetrics.fetchStart : Seconds(-1);
+ m_networkLoadMetrics.connectEnd = connectEnd ? connectEnd - m_networkLoadMetrics.fetchStart : Seconds(-1);
+ m_networkLoadMetrics.secureConnectionStart = secureConnectionStart ? secureConnectionStart - m_networkLoadMetrics.fetchStart : Seconds(-1);
+ m_networkLoadMetrics.requestStart = requestStart - m_networkLoadMetrics.fetchStart;
+#endif
}
void NetworkDataTaskSoup::restartedCallback(SoupMessage* soupMessage, NetworkDataTaskSoup* task)
@@ -1366,8 +1465,11 @@
void NetworkDataTaskSoup::didRestart()
{
m_networkLoadMetrics = { };
+#if USE(SOUP2)
m_networkLoadMetrics.fetchStart = MonotonicTime::now().secondsSinceEpoch();
-#if !USE(SOUP2)
+#else
+ auto* metrics = soup_message_get_metrics(m_soupMessage.get());
+ m_networkLoadMetrics.fetchStart = Seconds::fromMicroseconds(soup_message_metrics_get_fetch_start(metrics));
m_currentRequest.updateSoupMessageBody(m_soupMessage.get(), m_session->blobRegistry());
#endif
}
Modified: trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.h (277224 => 277225)
--- trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.h 2021-05-08 07:32:45 UTC (rev 277224)
+++ trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.h 2021-05-08 10:43:06 UTC (rev 277225)
@@ -127,6 +127,12 @@
#endif
void didWriteBodyData(uint64_t bytesSent);
+#if !USE(SOUP2)
+ static void wroteHeadersCallback(SoupMessage*, NetworkDataTaskSoup*);
+ static void wroteBodyCallback(SoupMessage*, NetworkDataTaskSoup*);
+ static void gotBodyCallback(SoupMessage*, NetworkDataTaskSoup*);
+#endif
+
void download();
static void writeDownloadCallback(GOutputStream*, GAsyncResult*, NetworkDataTaskSoup*);
void writeDownload();
@@ -137,8 +143,11 @@
void didFail(const WebCore::ResourceError&);
+#if USE(SOUP2)
static void networkEventCallback(SoupMessage*, GSocketClientEvent, GIOStream*, NetworkDataTaskSoup*);
void networkEvent(GSocketClientEvent, GIOStream*);
+#endif
+
#if SOUP_CHECK_VERSION(2, 49, 91)
static void startingCallback(SoupMessage*, NetworkDataTaskSoup*);
#else