Only use CFNetwork SPI for metrics where needed
https://bugs.webkit.org/show_bug.cgi?id=202825

Patch by Alex Christensen <achristensen@webkit.org> on 2019-10-11
Reviewed by Joseph Pecoraro.

Source/WebCore:

* platform/network/NetworkLoadMetrics.h:

Source/WebKit:

* NetworkProcess/cocoa/NetworkSessionCocoa.mm:
(stringForSSLProtocolVersion):
(-[WKNetworkSessionDelegate URLSession:task:didFinishCollectingMetrics:]):

Source/WTF:

* wtf/Platform.h:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@251021 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog
index 4affc40..07f2469 100644
--- a/Source/WTF/ChangeLog
+++ b/Source/WTF/ChangeLog
@@ -1,3 +1,12 @@
+2019-10-11  Alex Christensen  <achristensen@webkit.org>
+
+        Only use CFNetwork SPI for metrics where needed
+        https://bugs.webkit.org/show_bug.cgi?id=202825
+
+        Reviewed by Joseph Pecoraro.
+
+        * wtf/Platform.h:
+
 2019-10-11  Keith Rollin  <krollin@apple.com>
 
         Remove some support for < iOS 13
diff --git a/Source/WTF/wtf/Platform.h b/Source/WTF/wtf/Platform.h
index c85a06d..fecf97e 100644
--- a/Source/WTF/wtf/Platform.h
+++ b/Source/WTF/wtf/Platform.h
@@ -1516,6 +1516,10 @@
 #define HAVE_CFNETWORK_NEGOTIATED_SSL_PROTOCOL_CIPHER 1
 #endif
 
+#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101600) || (PLATFORM(IOS_FAMILY) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 140000)
+#define HAVE_CFNETWORK_METRICS_APIS_V4 1
+#endif
+
 #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500
 #define HAVE_CSCHECKFIXDISABLE 1
 #endif
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index d8060e9..1918f3e 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,12 @@
+2019-10-11  Alex Christensen  <achristensen@webkit.org>
+
+        Only use CFNetwork SPI for metrics where needed
+        https://bugs.webkit.org/show_bug.cgi?id=202825
+
+        Reviewed by Joseph Pecoraro.
+
+        * platform/network/NetworkLoadMetrics.h:
+
 2019-10-11  Chris Dumez  <cdumez@apple.com>
 
         Pages frequently fail to enter the back/forward cache due to frames with a quick redirect coming
diff --git a/Source/WebCore/platform/network/NetworkLoadMetrics.h b/Source/WebCore/platform/network/NetworkLoadMetrics.h
index 156f223..03c18b6 100644
--- a/Source/WebCore/platform/network/NetworkLoadMetrics.h
+++ b/Source/WebCore/platform/network/NetworkLoadMetrics.h
@@ -176,8 +176,8 @@
 
     HTTPHeaderMap requestHeaders;
 
-    uint32_t requestHeaderBytesSent;
-    uint32_t responseHeaderBytesReceived;
+    uint64_t requestHeaderBytesSent;
+    uint64_t responseHeaderBytesReceived;
     uint64_t requestBodyBytesSent;
     uint64_t responseBodyBytesReceived;
     uint64_t responseBodyDecodedSize;
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index 67075dc..ac99b93 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,14 @@
+2019-10-11  Alex Christensen  <achristensen@webkit.org>
+
+        Only use CFNetwork SPI for metrics where needed
+        https://bugs.webkit.org/show_bug.cgi?id=202825
+
+        Reviewed by Joseph Pecoraro.
+
+        * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
+        (stringForSSLProtocolVersion):
+        (-[WKNetworkSessionDelegate URLSession:task:didFinishCollectingMetrics:]):
+
 2019-10-11  Kate Cheney  <katherine_cheney@apple.com>
 
         Get StorageAccess API features working on SQLite database implementation (195422)
diff --git a/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm b/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
index 651afc6..00be2c2 100644
--- a/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
+++ b/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
@@ -111,6 +111,68 @@
 }
 
 #if HAVE(CFNETWORK_NEGOTIATED_SSL_PROTOCOL_CIPHER)
+#if HAVE(CFNETWORK_METRICS_APIS_V4)
+static String stringForTLSProtocolVersion(tls_protocol_version_t protocol)
+{
+    switch (protocol) {
+    case tls_protocol_version_TLSv10:
+        return "TLS 1.0"_s;
+    case tls_protocol_version_TLSv11:
+        return "TLS 1.1"_s;
+    case tls_protocol_version_TLSv12:
+        return "TLS 1.2"_s;
+    case tls_protocol_version_TLSv13:
+        return "TLS 1.3"_s;
+    case tls_protocol_version_DTLSv10:
+        return "DTLS 1.0"_s;
+    case tls_protocol_version_DTLSv12:
+        return "DTLS 1.2"_s;
+    }
+    return { };
+}
+
+static String stringForTLSCipherSuite(tls_ciphersuite_t suite)
+{
+#define STRINGIFY_CIPHER(cipher) \
+    case tls_ciphersuite_##cipher: \
+        return "" #cipher ""_s
+
+    switch (suite) {
+        STRINGIFY_CIPHER(RSA_WITH_3DES_EDE_CBC_SHA);
+        STRINGIFY_CIPHER(RSA_WITH_AES_128_CBC_SHA);
+        STRINGIFY_CIPHER(RSA_WITH_AES_256_CBC_SHA);
+        STRINGIFY_CIPHER(RSA_WITH_AES_128_GCM_SHA256);
+        STRINGIFY_CIPHER(RSA_WITH_AES_256_GCM_SHA384);
+        STRINGIFY_CIPHER(RSA_WITH_AES_128_CBC_SHA256);
+        STRINGIFY_CIPHER(RSA_WITH_AES_256_CBC_SHA256);
+        STRINGIFY_CIPHER(ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA);
+        STRINGIFY_CIPHER(ECDHE_ECDSA_WITH_AES_128_CBC_SHA);
+        STRINGIFY_CIPHER(ECDHE_ECDSA_WITH_AES_256_CBC_SHA);
+        STRINGIFY_CIPHER(ECDHE_RSA_WITH_3DES_EDE_CBC_SHA);
+        STRINGIFY_CIPHER(ECDHE_RSA_WITH_AES_128_CBC_SHA);
+        STRINGIFY_CIPHER(ECDHE_RSA_WITH_AES_256_CBC_SHA);
+        STRINGIFY_CIPHER(ECDHE_ECDSA_WITH_AES_128_CBC_SHA256);
+        STRINGIFY_CIPHER(ECDHE_ECDSA_WITH_AES_256_CBC_SHA384);
+        STRINGIFY_CIPHER(ECDHE_RSA_WITH_AES_128_CBC_SHA256);
+        STRINGIFY_CIPHER(ECDHE_RSA_WITH_AES_256_CBC_SHA384);
+        STRINGIFY_CIPHER(ECDHE_ECDSA_WITH_AES_128_GCM_SHA256);
+        STRINGIFY_CIPHER(ECDHE_ECDSA_WITH_AES_256_GCM_SHA384);
+        STRINGIFY_CIPHER(ECDHE_RSA_WITH_AES_128_GCM_SHA256);
+        STRINGIFY_CIPHER(ECDHE_RSA_WITH_AES_256_GCM_SHA384);
+        STRINGIFY_CIPHER(ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256);
+        STRINGIFY_CIPHER(ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256);
+        STRINGIFY_CIPHER(AES_128_GCM_SHA256);
+        STRINGIFY_CIPHER(AES_256_GCM_SHA384);
+        STRINGIFY_CIPHER(CHACHA20_POLY1305_SHA256);
+    }
+
+    return { };
+
+#undef STRINGIFY_CIPHER
+}
+
+#else // HAVE(CFNETWORK_METRICS_APIS_V4)
+
 static String stringForSSLProtocol(SSLProtocol protocol)
 {
     ALLOW_DEPRECATED_DECLARATIONS_BEGIN
@@ -325,7 +387,8 @@
 
 #undef STRINGIFY_CIPHER
 }
-#endif
+#endif // HAVE(CFNETWORK_METRICS_APIS_V4)
+#endif // HAVE(CFNETWORK_NEGOTIATED_SSL_PROTOCOL_CIPHER)
 
 @interface WKNetworkSessionDelegate : NSObject <NSURLSessionDataDelegate
 #if HAVE(NSURLSESSION_WEBSOCKET)
@@ -669,17 +732,28 @@
         networkLoadMetrics.markComplete();
         networkLoadMetrics.protocol = String(m.networkProtocolName);
 
-        ALLOW_DEPRECATED_DECLARATIONS_BEGIN
         if (networkDataTask->shouldCaptureExtraNetworkLoadMetrics()) {
             networkLoadMetrics.priority = toNetworkLoadPriority(task.priority);
 
+#if HAVE(CFNETWORK_METRICS_APIS_V4)
+            if (auto port = [m.remotePort unsignedIntValue])
+                networkLoadMetrics.remoteAddress = makeString(String(m.remoteAddress), ':', port);
+            else
+                networkLoadMetrics.remoteAddress = m.remoteAddress;
+#else
             networkLoadMetrics.remoteAddress = String(m._remoteAddressAndPort);
+#endif
             networkLoadMetrics.connectionIdentifier = String([m._connectionIdentifier UUIDString]);
 
 #if HAVE(CFNETWORK_NEGOTIATED_SSL_PROTOCOL_CIPHER)
+#if HAVE(CFNETWORK_METRICS_APIS_V4)
+            networkLoadMetrics.tlsProtocol = stringForTLSProtocolVersion((tls_protocol_version_t)[m.negotiatedTLSProtocolVersion unsignedShortValue]);
+            networkLoadMetrics.tlsCipher = stringForTLSCipherSuite((tls_ciphersuite_t)[m.negotiatedTLSCipherSuite unsignedShortValue]);
+#else
             networkLoadMetrics.tlsProtocol = stringForSSLProtocol(m._negotiatedTLSProtocol);
             networkLoadMetrics.tlsCipher = stringForSSLCipher(m._negotiatedTLSCipher);
 #endif
+#endif
 
             __block WebCore::HTTPHeaderMap requestHeaders;
             [m.request.allHTTPHeaderFields enumerateKeysAndObjectsUsingBlock:^(NSString *name, NSString *value, BOOL *) {
@@ -693,10 +767,17 @@
             uint64_t responseBodyDecodedSize = 0;
 
             for (NSURLSessionTaskTransactionMetrics *transactionMetrics in metrics.transactionMetrics) {
+#if HAVE(CFNETWORK_METRICS_APIS_V4)
+                requestHeaderBytesSent += transactionMetrics.countOfRequestHeaderBytesSent;
+                responseHeaderBytesReceived += transactionMetrics.countOfResponseHeaderBytesReceived;
+                responseBodyBytesReceived += transactionMetrics.countOfResponseBodyBytesReceived;
+                responseBodyDecodedSize += transactionMetrics.countOfResponseBodyBytesAfterDecoding ? transactionMetrics.countOfResponseBodyBytesAfterDecoding : transactionMetrics.countOfResponseBodyBytesReceived;
+#else
                 requestHeaderBytesSent += transactionMetrics._requestHeaderBytesSent;
                 responseHeaderBytesReceived += transactionMetrics._responseHeaderBytesReceived;
                 responseBodyBytesReceived += transactionMetrics._responseBodyBytesReceived;
                 responseBodyDecodedSize += transactionMetrics._responseBodyBytesDecoded ? transactionMetrics._responseBodyBytesDecoded : transactionMetrics._responseBodyBytesReceived;
+#endif
             }
 
             networkLoadMetrics.requestHeaderBytesSent = requestHeaderBytesSent;
@@ -705,7 +786,6 @@
             networkLoadMetrics.responseBodyBytesReceived = responseBodyBytesReceived;
             networkLoadMetrics.responseBodyDecodedSize = responseBodyDecodedSize;
         }
-        ALLOW_DEPRECATED_DECLARATIONS_END
     }
 }