Implement Web Timing when using NETWORK_SESSION
authorachristensen@apple.com <achristensen@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 Dec 2015 18:25:00 +0000 (18:25 +0000)
committerachristensen@apple.com <achristensen@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 Dec 2015 18:25:00 +0000 (18:25 +0000)
https://bugs.webkit.org/show_bug.cgi?id=152285

Reviewed by Darin Adler.

Source/WebCore:

Covered by existing tests.

* WebCore.xcodeproj/project.pbxproj:
* platform/network/ResourceHandle.h:
* platform/network/ResourceLoadTiming.h:
(WebCore::ResourceLoadTiming::encode):
Moved setCollectsTimingData from ResourceHandle to ResourceLoadTiming.h to be shared
with WebKit2 when using NETWORK_SESSION, which does not use ResourceHandle.
Also moved getConnectionTimingData to copyTimingData in ResourceLoadTiming for the same reason.
* platform/network/cf/ResourceHandleCFNet.cpp:
(WebCore::ResourceHandle::createCFURLConnection):
(WebCore::ResourceHandle::start):
Use the proper definition of _TimingDataOptionsEnableW3CNavigationTiming.
* platform/network/cocoa/ResourceLoadTiming.mm: Added.
(WebCore::timingValue):
(WebCore::copyTimingData):
Moved from getConnectionTimingData, and use objectForKey instead of valueForKey,
and check to see if there is no object in the dictionary with the given key.
This should never happen with the current CFNetwork implementation, but it's good to check dictionaries.
(WebCore::setCollectsTimingData):
Use _collectTimingDataWithOptions, which should be a slight performance improvement on Mavericks
because we are not collecting unused timing data. Hooray!
* platform/network/mac/ResourceHandleMac.mm:
(WebCore::ResourceHandle::createNSURLConnection):
(WebCore::ResourceHandle::getConnectionTimingData):
(WebCore::ResourceHandle::setCollectsTimingData): Deleted.
* platform/spi/cf/CFNetworkSPI.h:
* platform/spi/cocoa/NSURLConnectionSPI.h:
Moved definitions of SPI to proper SPI headers.

Source/WebKit2:

* NetworkProcess/cocoa/NetworkSessionCocoa.mm:
(-[NetworkSessionDelegate URLSession:dataTask:didReceiveResponse:completionHandler:]):
(WebKit::NetworkSession::NetworkSession):
Use functions moved to ResourceLoadTiming.h.  setCollectsTimingData is for Mavericks, _timingDataOptions is post-Mavericks.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@194156 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/platform/network/ResourceHandle.h
Source/WebCore/platform/network/ResourceLoadTiming.h
Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
Source/WebCore/platform/network/cocoa/ResourceLoadTiming.mm [new file with mode: 0644]
Source/WebCore/platform/network/mac/ResourceHandleMac.mm
Source/WebCore/platform/spi/cf/CFNetworkSPI.h
Source/WebCore/platform/spi/cocoa/NSURLConnectionSPI.h
Source/WebKit2/ChangeLog
Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm

index 78b1e84..149913d 100644 (file)
@@ -1,3 +1,40 @@
+2015-12-16  Alex Christensen  <achristensen@webkit.org>
+
+        Implement Web Timing when using NETWORK_SESSION
+        https://bugs.webkit.org/show_bug.cgi?id=152285
+
+        Reviewed by Darin Adler.
+
+        Covered by existing tests.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/network/ResourceHandle.h:
+        * platform/network/ResourceLoadTiming.h:
+        (WebCore::ResourceLoadTiming::encode):
+        Moved setCollectsTimingData from ResourceHandle to ResourceLoadTiming.h to be shared 
+        with WebKit2 when using NETWORK_SESSION, which does not use ResourceHandle.
+        Also moved getConnectionTimingData to copyTimingData in ResourceLoadTiming for the same reason.
+        * platform/network/cf/ResourceHandleCFNet.cpp:
+        (WebCore::ResourceHandle::createCFURLConnection):
+        (WebCore::ResourceHandle::start):
+        Use the proper definition of _TimingDataOptionsEnableW3CNavigationTiming.
+        * platform/network/cocoa/ResourceLoadTiming.mm: Added.
+        (WebCore::timingValue):
+        (WebCore::copyTimingData):
+        Moved from getConnectionTimingData, and use objectForKey instead of valueForKey,
+        and check to see if there is no object in the dictionary with the given key.
+        This should never happen with the current CFNetwork implementation, but it's good to check dictionaries.
+        (WebCore::setCollectsTimingData):
+        Use _collectTimingDataWithOptions, which should be a slight performance improvement on Mavericks
+        because we are not collecting unused timing data. Hooray!
+        * platform/network/mac/ResourceHandleMac.mm:
+        (WebCore::ResourceHandle::createNSURLConnection):
+        (WebCore::ResourceHandle::getConnectionTimingData):
+        (WebCore::ResourceHandle::setCollectsTimingData): Deleted.
+        * platform/spi/cf/CFNetworkSPI.h:
+        * platform/spi/cocoa/NSURLConnectionSPI.h:
+        Moved definitions of SPI to proper SPI headers.
+
 2015-12-16  Beth Dakin  <bdakin@apple.com>
 
         Legacy style scrollbars do not change color when you mouse over them if you 
 2015-12-16  Beth Dakin  <bdakin@apple.com>
 
         Legacy style scrollbars do not change color when you mouse over them if you 
index f9cf3b4..c09d3d9 100644 (file)
                5C4304B6191AEF46000E2BC0 /* JSEXTShaderTextureLOD.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C4304B4191AEF46000E2BC0 /* JSEXTShaderTextureLOD.h */; };
                5C9A7A751AA0F6EA00958ACF /* DFABytecodeCompiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C39305E1AA0F6A90029C816 /* DFABytecodeCompiler.cpp */; };
                5C9A7A761AA0F6ED00958ACF /* DFABytecodeInterpreter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C3930601AA0F6A90029C816 /* DFABytecodeInterpreter.cpp */; };
                5C4304B6191AEF46000E2BC0 /* JSEXTShaderTextureLOD.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C4304B4191AEF46000E2BC0 /* JSEXTShaderTextureLOD.h */; };
                5C9A7A751AA0F6EA00958ACF /* DFABytecodeCompiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C39305E1AA0F6A90029C816 /* DFABytecodeCompiler.cpp */; };
                5C9A7A761AA0F6ED00958ACF /* DFABytecodeInterpreter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C3930601AA0F6A90029C816 /* DFABytecodeInterpreter.cpp */; };
+               5C9B860C1C21E3C900110F36 /* ResourceLoadTiming.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C9B860B1C21E3C600110F36 /* ResourceLoadTiming.mm */; };
                5CBC8DAC1AAA302200E1C803 /* MediaAccessibilitySoftLink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CBC8DAA1AAA302200E1C803 /* MediaAccessibilitySoftLink.cpp */; };
                5CBC8DAD1AAA302200E1C803 /* MediaAccessibilitySoftLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CBC8DAB1AAA302200E1C803 /* MediaAccessibilitySoftLink.h */; };
                5CD9F5661AA0F73C00DA45FF /* DFABytecode.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C39305D1AA0F6A90029C816 /* DFABytecode.h */; settings = {ATTRIBUTES = (Private, ); }; };
                5CBC8DAC1AAA302200E1C803 /* MediaAccessibilitySoftLink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CBC8DAA1AAA302200E1C803 /* MediaAccessibilitySoftLink.cpp */; };
                5CBC8DAD1AAA302200E1C803 /* MediaAccessibilitySoftLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CBC8DAB1AAA302200E1C803 /* MediaAccessibilitySoftLink.h */; };
                5CD9F5661AA0F73C00DA45FF /* DFABytecode.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C39305D1AA0F6A90029C816 /* DFABytecode.h */; settings = {ATTRIBUTES = (Private, ); }; };
                5C4304AF191AC908000E2BC0 /* EXTShaderTextureLOD.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = EXTShaderTextureLOD.idl; sourceTree = "<group>"; };
                5C4304B3191AEF46000E2BC0 /* JSEXTShaderTextureLOD.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSEXTShaderTextureLOD.cpp; sourceTree = "<group>"; };
                5C4304B4191AEF46000E2BC0 /* JSEXTShaderTextureLOD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSEXTShaderTextureLOD.h; sourceTree = "<group>"; };
                5C4304AF191AC908000E2BC0 /* EXTShaderTextureLOD.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = EXTShaderTextureLOD.idl; sourceTree = "<group>"; };
                5C4304B3191AEF46000E2BC0 /* JSEXTShaderTextureLOD.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSEXTShaderTextureLOD.cpp; sourceTree = "<group>"; };
                5C4304B4191AEF46000E2BC0 /* JSEXTShaderTextureLOD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSEXTShaderTextureLOD.h; sourceTree = "<group>"; };
+               5C9B860B1C21E3C600110F36 /* ResourceLoadTiming.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ResourceLoadTiming.mm; sourceTree = "<group>"; };
                5CBC8DAA1AAA302200E1C803 /* MediaAccessibilitySoftLink.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaAccessibilitySoftLink.cpp; sourceTree = "<group>"; };
                5CBC8DAB1AAA302200E1C803 /* MediaAccessibilitySoftLink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaAccessibilitySoftLink.h; sourceTree = "<group>"; };
                5CDFA6C71AA4F2DA00EA8746 /* ContentExtensionActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContentExtensionActions.h; sourceTree = "<group>"; };
                5CBC8DAA1AAA302200E1C803 /* MediaAccessibilitySoftLink.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaAccessibilitySoftLink.cpp; sourceTree = "<group>"; };
                5CBC8DAB1AAA302200E1C803 /* MediaAccessibilitySoftLink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaAccessibilitySoftLink.h; sourceTree = "<group>"; };
                5CDFA6C71AA4F2DA00EA8746 /* ContentExtensionActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContentExtensionActions.h; sourceTree = "<group>"; };
                7E7DE1FE195CEF2D0035363B /* cocoa */ = {
                        isa = PBXGroup;
                        children = (
                7E7DE1FE195CEF2D0035363B /* cocoa */ = {
                        isa = PBXGroup;
                        children = (
+                               5C9B860B1C21E3C600110F36 /* ResourceLoadTiming.mm */,
                                3792917C1987678F00F4B661 /* CredentialCocoa.h */,
                                3792917B1987678F00F4B661 /* CredentialCocoa.mm */,
                                372ADA37197F47B900FC501E /* ProtectionSpaceCocoa.h */,
                                3792917C1987678F00F4B661 /* CredentialCocoa.h */,
                                3792917B1987678F00F4B661 /* CredentialCocoa.mm */,
                                372ADA37197F47B900FC501E /* ProtectionSpaceCocoa.h */,
                                93F19B0308245E59001E9ABC /* XSLStyleSheetLibxslt.cpp in Sources */,
                                E1F1E82F0C3C2BB9006DB391 /* XSLTExtensions.cpp in Sources */,
                                93F19B0408245E59001E9ABC /* XSLTProcessor.cpp in Sources */,
                                93F19B0308245E59001E9ABC /* XSLStyleSheetLibxslt.cpp in Sources */,
                                E1F1E82F0C3C2BB9006DB391 /* XSLTExtensions.cpp in Sources */,
                                93F19B0408245E59001E9ABC /* XSLTProcessor.cpp in Sources */,
+                               5C9B860C1C21E3C900110F36 /* ResourceLoadTiming.mm in Sources */,
                                93F19B0508245E59001E9ABC /* XSLTProcessorLibxslt.cpp in Sources */,
                                E1BE512D0CF6C512002EA959 /* XSLTUnicodeSort.cpp in Sources */,
                                977E2E0E12F0FC9C00C13379 /* XSSAuditor.cpp in Sources */,
                                93F19B0508245E59001E9ABC /* XSLTProcessorLibxslt.cpp in Sources */,
                                E1BE512D0CF6C512002EA959 /* XSLTUnicodeSort.cpp in Sources */,
                                977E2E0E12F0FC9C00C13379 /* XSSAuditor.cpp in Sources */,
index 52dd46a..53e24cd 100644 (file)
@@ -135,7 +135,6 @@ public:
 #endif
         
 #if PLATFORM(COCOA) && ENABLE(WEB_TIMING)
 #endif
         
 #if PLATFORM(COCOA) && ENABLE(WEB_TIMING)
-    void setCollectsTimingData();
 #if USE(CFNETWORK)
     static void getConnectionTimingData(CFURLConnectionRef, ResourceLoadTiming&);
 #else
 #if USE(CFNETWORK)
     static void getConnectionTimingData(CFURLConnectionRef, ResourceLoadTiming&);
 #else
@@ -285,10 +284,6 @@ private:
     void createNSURLConnection(id delegate, bool shouldUseCredentialStorage, bool shouldContentSniff, SchedulingBehavior, NSDictionary *connectionProperties);
 #endif
 
     void createNSURLConnection(id delegate, bool shouldUseCredentialStorage, bool shouldContentSniff, SchedulingBehavior, NSDictionary *connectionProperties);
 #endif
 
-#if PLATFORM(COCOA) && ENABLE(WEB_TIMING)
-static void getConnectionTimingData(NSDictionary *timingData, ResourceLoadTiming&);
-#endif
-
 #if USE(SOUP)
     void timeoutFired();
 #endif
 #if USE(SOUP)
     void timeoutFired();
 #endif
index d717bd1..9bd945c 100644 (file)
 #ifndef ResourceLoadTiming_h
 #define ResourceLoadTiming_h
 
 #ifndef ResourceLoadTiming_h
 #define ResourceLoadTiming_h
 
+#if PLATFORM(COCOA)
+OBJC_CLASS NSDictionary;
+#endif
+
 namespace WebCore {
     
 class ResourceLoadTiming {
 namespace WebCore {
     
 class ResourceLoadTiming {
@@ -94,6 +98,14 @@ public:
     int secureConnectionStart;
 };
 
     int secureConnectionStart;
 };
 
+#if PLATFORM(COCOA)
+WEBCORE_EXPORT void copyTimingData(NSDictionary *timingData, ResourceLoadTiming&);
+#endif
+
+#if PLATFORM(COCOA) && !HAVE(TIMINGDATAOPTIONS)
+WEBCORE_EXPORT void setCollectsTimingData();
+#endif
+    
 template<class Encoder>
 void ResourceLoadTiming::encode(Encoder& encoder) const
 {
 template<class Encoder>
 void ResourceLoadTiming::encode(Encoder& encoder) const
 {
index 3e61cd4..d7e94fd 100644 (file)
@@ -207,8 +207,7 @@ void ResourceHandle::createCFURLConnection(bool shouldUseCredentialStorage, bool
     else
         propertiesDictionary = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
 #if HAVE(TIMINGDATAOPTIONS)
     else
         propertiesDictionary = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
 #if HAVE(TIMINGDATAOPTIONS)
-    const int64_t TimingDataOptionsEnableW3CNavigationTiming = (1 << 0);
-    auto enableW3CNavigationTiming = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &TimingDataOptionsEnableW3CNavigationTiming));
+    auto enableW3CNavigationTiming = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &_TimingDataOptionsEnableW3CNavigationTiming));
     auto timingDataOptionsDictionary = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
     CFDictionaryAddValue(timingDataOptionsDictionary.get(), CFSTR("_kCFURLConnectionPropertyTimingDataOptions"), enableW3CNavigationTiming.get());
     CFDictionaryAddValue(propertiesDictionary.get(), CFSTR("kCFURLConnectionURLConnectionProperties"), timingDataOptionsDictionary.get());
     auto timingDataOptionsDictionary = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
     CFDictionaryAddValue(timingDataOptionsDictionary.get(), CFSTR("_kCFURLConnectionPropertyTimingDataOptions"), enableW3CNavigationTiming.get());
     CFDictionaryAddValue(propertiesDictionary.get(), CFSTR("kCFURLConnectionURLConnectionProperties"), timingDataOptionsDictionary.get());
@@ -252,7 +251,7 @@ bool ResourceHandle::start()
 
     bool shouldUseCredentialStorage = !client() || client()->shouldUseCredentialStorage(this);
 
 
     bool shouldUseCredentialStorage = !client() || client()->shouldUseCredentialStorage(this);
 
-#if ENABLE(WEB_TIMING) && PLATFORM(COCOA)
+#if ENABLE(WEB_TIMING) && PLATFORM(COCOA) && !HAVE(TIMINGDATAOPTIONS)
     setCollectsTimingData();
 #endif
 
     setCollectsTimingData();
 #endif
 
diff --git a/Source/WebCore/platform/network/cocoa/ResourceLoadTiming.mm b/Source/WebCore/platform/network/cocoa/ResourceLoadTiming.mm
new file mode 100644 (file)
index 0000000..a480ffc
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2015 Apple, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "ResourceLoadTiming.h"
+
+#import <WebCore/NSURLConnectionSPI.h>
+
+namespace WebCore {
+
+static double timingValue(NSDictionary *timingData, NSString *key)
+{
+    if (id object = [timingData objectForKey:key])
+        return [object doubleValue];
+    return 0.0;
+}
+    
+void copyTimingData(NSDictionary *timingData, ResourceLoadTiming& timing)
+{
+    if (!timingData)
+        return;
+    
+    // This is not the navigationStart time in monotonic time, but the other times are relative to this time
+    // and only the differences between times are stored.
+    double referenceStart = timingValue(timingData, @"_kCFNTimingDataFetchStart");
+    
+    double domainLookupStart = timingValue(timingData, @"_kCFNTimingDataDomainLookupStart");
+    double domainLookupEnd = timingValue(timingData, @"_kCFNTimingDataDomainLookupEnd");
+    double connectStart = timingValue(timingData, @"_kCFNTimingDataConnectStart");
+    double secureConnectionStart = timingValue(timingData, @"_kCFNTimingDataSecureConnectionStart");
+    double connectEnd = timingValue(timingData, @"_kCFNTimingDataConnectEnd");
+    double requestStart = timingValue(timingData, @"_kCFNTimingDataRequestStart");
+    double responseStart = timingValue(timingData, @"_kCFNTimingDataResponseStart");
+    
+    timing.domainLookupStart = domainLookupStart <= 0 ? -1 : (domainLookupStart - referenceStart) * 1000;
+    timing.domainLookupEnd = domainLookupEnd <= 0 ? -1 : (domainLookupEnd - referenceStart) * 1000;
+    timing.connectStart = connectStart <= 0 ? -1 : (connectStart - referenceStart) * 1000;
+    timing.secureConnectionStart = secureConnectionStart <= 0 ? -1 : (secureConnectionStart - referenceStart) * 1000;
+    timing.connectEnd = connectEnd <= 0 ? -1 : (connectEnd - referenceStart) * 1000;
+    timing.requestStart = requestStart <= 0 ? 0 : (requestStart - referenceStart) * 1000;
+    timing.responseStart = responseStart <= 0 ? 0 : (responseStart - referenceStart) * 1000;
+}
+
+#if !HAVE(TIMINGDATAOPTIONS)
+void setCollectsTimingData()
+{
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        [NSURLConnection _setCollectsTimingData:YES];
+        [NSURLConnection _collectTimingDataWithOptions:TimingDataCollectionNStatsOff | TimingDataCollectionConnectionDataOff];
+    });
+}
+#endif
+    
+}
index bba0533..ce1b49a 100644 (file)
@@ -66,17 +66,6 @@ CFDictionaryRef _CFURLConnectionCopyTimingData(CFURLConnectionRef);
 }
 #endif // USE(CFNETWORK)
 
 }
 #endif // USE(CFNETWORK)
 
-#if __has_include(<Foundation/NSURLConnectionPrivate.h>)
-#import <Foundation/NSURLConnectionPrivate.h>
-#else
-@interface NSURLConnection (TimingData)
-#if !HAVE(TIMINGDATAOPTIONS)
-+ (void)_setCollectsTimingData:(BOOL)collect;
-#endif
-- (NSDictionary *)_timingData;
-@end
-#endif
-
 #if PLATFORM(IOS)
 #import "CFNetworkSPI.h"
 #import "RuntimeApplicationChecksIOS.h"
 #if PLATFORM(IOS)
 #import "CFNetworkSPI.h"
 #import "RuntimeApplicationChecksIOS.h"
@@ -145,7 +134,7 @@ void ResourceHandle::createNSURLConnection(id delegate, bool shouldUseCredential
 void ResourceHandle::createNSURLConnection(id delegate, bool shouldUseCredentialStorage, bool shouldContentSniff, SchedulingBehavior schedulingBehavior, NSDictionary *connectionProperties)
 #endif
 {
 void ResourceHandle::createNSURLConnection(id delegate, bool shouldUseCredentialStorage, bool shouldContentSniff, SchedulingBehavior schedulingBehavior, NSDictionary *connectionProperties)
 #endif
 {
-#if ENABLE(WEB_TIMING)
+#if ENABLE(WEB_TIMING) && !HAVE(TIMINGDATAOPTIONS)
     setCollectsTimingData();
 #endif
 
     setCollectsTimingData();
 #endif
 
@@ -224,8 +213,7 @@ void ResourceHandle::createNSURLConnection(id delegate, bool shouldUseCredential
     const bool usesCache = true;
 #endif
 #if HAVE(TIMINGDATAOPTIONS)
     const bool usesCache = true;
 #endif
 #if HAVE(TIMINGDATAOPTIONS)
-    const int64_t TimingDataOptionsEnableW3CNavigationTiming = (1 << 0);
-    [propertyDictionary setObject:@{@"_kCFURLConnectionPropertyTimingDataOptions": @(TimingDataOptionsEnableW3CNavigationTiming)} forKey:@"kCFURLConnectionURLConnectionProperties"];
+    [propertyDictionary setObject:@{@"_kCFURLConnectionPropertyTimingDataOptions": @(_TimingDataOptionsEnableW3CNavigationTiming)} forKey:@"kCFURLConnectionURLConnectionProperties"];
 #endif
     d->m_connection = adoptNS([[NSURLConnection alloc] _initWithRequest:nsRequest delegate:delegate usesCache:usesCache maxContentLength:0 startImmediately:NO connectionProperties:propertyDictionary]);
 }
 #endif
     d->m_connection = adoptNS([[NSURLConnection alloc] _initWithRequest:nsRequest delegate:delegate usesCache:usesCache maxContentLength:0 startImmediately:NO connectionProperties:propertyDictionary]);
 }
@@ -739,55 +727,19 @@ void ResourceHandle::continueWillCacheResponse(NSCachedURLResponse *response)
 #endif // !USE(CFNETWORK)
     
 #if ENABLE(WEB_TIMING)
 #endif // !USE(CFNETWORK)
     
 #if ENABLE(WEB_TIMING)
-    
-void ResourceHandle::getConnectionTimingData(NSDictionary *timingData, ResourceLoadTiming& timing)
-{
-    if (!timingData)
-        return;
-
-    // This is not the navigationStart time in monotonic time, but the other times are relative to this time
-    // and only the differences between times are stored.
-    double referenceStart = [[timingData valueForKey:@"_kCFNTimingDataFetchStart"] doubleValue];
-            
-    double domainLookupStart = [[timingData valueForKey:@"_kCFNTimingDataDomainLookupStart"] doubleValue];
-    double domainLookupEnd = [[timingData valueForKey:@"_kCFNTimingDataDomainLookupEnd"] doubleValue];
-    double connectStart = [[timingData valueForKey:@"_kCFNTimingDataConnectStart"] doubleValue];
-    double secureConnectionStart = [[timingData valueForKey:@"_kCFNTimingDataSecureConnectionStart"] doubleValue];
-    double connectEnd = [[timingData valueForKey:@"_kCFNTimingDataConnectEnd"] doubleValue];
-    double requestStart = [[timingData valueForKey:@"_kCFNTimingDataRequestStart"] doubleValue];
-    double responseStart = [[timingData valueForKey:@"_kCFNTimingDataResponseStart"] doubleValue];
-        
-    timing.domainLookupStart = domainLookupStart <= 0 ? -1 : (domainLookupStart - referenceStart) * 1000;
-    timing.domainLookupEnd = domainLookupEnd <= 0 ? -1 : (domainLookupEnd - referenceStart) * 1000;
-    timing.connectStart = connectStart <= 0 ? -1 : (connectStart - referenceStart) * 1000;
-    timing.secureConnectionStart = secureConnectionStart <= 0 ? -1 : (secureConnectionStart - referenceStart) * 1000;
-    timing.connectEnd = connectEnd <= 0 ? -1 : (connectEnd - referenceStart) * 1000;
-    timing.requestStart = requestStart <= 0 ? 0 : (requestStart - referenceStart) * 1000;
-    timing.responseStart = responseStart <= 0 ? 0 : (responseStart - referenceStart) * 1000;
-}
-
-void ResourceHandle::setCollectsTimingData()
-{
-#if !HAVE(TIMINGDATAOPTIONS)
-    static dispatch_once_t onceToken;
-    dispatch_once(&onceToken, ^{
-        [NSURLConnection _setCollectsTimingData:YES];
-    });
-#endif
-}
 
 #if USE(CFNETWORK)
     
 void ResourceHandle::getConnectionTimingData(CFURLConnectionRef connection, ResourceLoadTiming& timing)
 {
 
 #if USE(CFNETWORK)
     
 void ResourceHandle::getConnectionTimingData(CFURLConnectionRef connection, ResourceLoadTiming& timing)
 {
-    getConnectionTimingData((__bridge NSDictionary*)(adoptCF(_CFURLConnectionCopyTimingData(connection)).get()), timing);
+    copyTimingData((__bridge NSDictionary*)adoptCF(_CFURLConnectionCopyTimingData(connection)).get(), timing);
 }
     
 #else
     
 void ResourceHandle::getConnectionTimingData(NSURLConnection *connection, ResourceLoadTiming& timing)
 {
 }
     
 #else
     
 void ResourceHandle::getConnectionTimingData(NSURLConnection *connection, ResourceLoadTiming& timing)
 {
-    getConnectionTimingData([connection _timingData], timing);
+    copyTimingData([connection _timingData], timing);
 }
     
 #endif
 }
     
 #endif
index d585225..eea520a 100644 (file)
@@ -51,7 +51,18 @@ extern "C" {
 #endif
 #endif // defined(__OBJC__) && (PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000)
 
 #endif
 #endif // defined(__OBJC__) && (PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000)
 
-#else
+#else // PLATFORM(WIN) || USE(APPLE_INTERNAL_SDK)
+
+#if defined(__OBJC__)
+@interface NSURLSessionTask (TimingData)
+- (NSDictionary *)_timingData;
+@end
+#endif
+
+typedef CF_ENUM(int64_t, _TimingDataOptions)
+{
+    _TimingDataOptionsEnableW3CNavigationTiming = (1 << 0)
+};
 
 typedef struct OpaqueCFHTTPCookieStorage* CFHTTPCookieStorageRef;
 typedef const struct _CFCachedURLResponse* CFCachedURLResponseRef;
 
 typedef struct OpaqueCFHTTPCookieStorage* CFHTTPCookieStorageRef;
 typedef const struct _CFCachedURLResponse* CFCachedURLResponseRef;
index 2756732..2c66c5a 100644 (file)
 
 #else
 
 
 #else
 
+enum {
+    TimingDataCollectionDefault = 0,
+    TimingDataCollectionNStatsOff = 1,
+    TimingDataCollectionConnectionDataOff = 2,
+};
+typedef NSUInteger TimingDataCollection;
+
 @interface NSURLConnection ()
 + (CFRunLoopRef)resourceLoaderRunLoop;
 - (void)setDefersCallbacks:(BOOL)defers;
 @interface NSURLConnection ()
 + (CFRunLoopRef)resourceLoaderRunLoop;
 - (void)setDefersCallbacks:(BOOL)defers;
+#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101100
++ (void)_setCollectsTimingData:(BOOL)collect;
++ (void)_collectTimingDataWithOptions:(TimingDataCollection)options;
+#endif
+- (NSDictionary *)_timingData;
 @end
 
 #endif
 @end
 
 #endif
index 59e5968..0eec9c7 100644 (file)
@@ -1,3 +1,15 @@
+2015-12-16  Alex Christensen  <achristensen@webkit.org>
+
+        Implement Web Timing when using NETWORK_SESSION
+        https://bugs.webkit.org/show_bug.cgi?id=152285
+
+        Reviewed by Darin Adler.
+
+        * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
+        (-[NetworkSessionDelegate URLSession:dataTask:didReceiveResponse:completionHandler:]):
+        (WebKit::NetworkSession::NetworkSession):
+        Use functions moved to ResourceLoadTiming.h.  setCollectsTimingData is for Mavericks, _timingDataOptions is post-Mavericks.
+
 2015-12-16  Youenn Fablet  <youenn.fablet@crf.canon.fr>
 
         [Fetch API] Add fetch API compile time flag
 2015-12-16  Youenn Fablet  <youenn.fablet@crf.canon.fr>
 
         [Fetch API] Add fetch API compile time flag
index 883722b..b5202b7 100644 (file)
@@ -37,6 +37,7 @@
 #import <WebCore/NetworkStorageSession.h>
 #import <WebCore/NotImplemented.h>
 #import <WebCore/ResourceError.h>
 #import <WebCore/NetworkStorageSession.h>
 #import <WebCore/NotImplemented.h>
 #import <WebCore/ResourceError.h>
+#import <WebCore/ResourceLoadTiming.h>
 #import <WebCore/ResourceRequest.h>
 #import <WebCore/ResourceResponse.h>
 #import <WebCore/SharedBuffer.h>
 #import <WebCore/ResourceRequest.h>
 #import <WebCore/ResourceResponse.h>
 #import <WebCore/SharedBuffer.h>
@@ -142,6 +143,7 @@ static NSURLSessionAuthChallengeDisposition toNSURLSessionAuthChallengeDispositi
         if (auto* client = networkingTask->client()) {
             ASSERT(isMainThread());
             WebCore::ResourceResponse resourceResponse(response);
         if (auto* client = networkingTask->client()) {
             ASSERT(isMainThread());
             WebCore::ResourceResponse resourceResponse(response);
+            copyTimingData([dataTask _timingData], resourceResponse.resourceLoadTiming());
             auto completionHandlerCopy = Block_copy(completionHandler);
             client->didReceiveResponse(resourceResponse, [completionHandlerCopy](WebCore::PolicyAction policyAction)
                 {
             auto completionHandlerCopy = Block_copy(completionHandler);
             client->didReceiveResponse(resourceResponse, [completionHandlerCopy](WebCore::PolicyAction policyAction)
                 {
@@ -214,6 +216,13 @@ NetworkSession::NetworkSession(Type type, WebCore::SessionID sessionID)
     m_sessionDelegate = adoptNS([[NetworkSessionDelegate alloc] initWithNetworkSession:*this]);
 
     NSURLSessionConfiguration *configuration = configurationForType(type);
     m_sessionDelegate = adoptNS([[NetworkSessionDelegate alloc] initWithNetworkSession:*this]);
 
     NSURLSessionConfiguration *configuration = configurationForType(type);
+
+#if HAVE(TIMINGDATAOPTIONS)
+    configuration._timingDataOptions = _TimingDataOptionsEnableW3CNavigationTiming;
+#else
+    setCollectsTimingData();
+#endif
+
     if (auto* storageSession = SessionTracker::storageSession(sessionID)) {
         if (CFHTTPCookieStorageRef storage = storageSession->cookieStorage().get())
             configuration.HTTPCookieStorage = [[[NSHTTPCookieStorage alloc] _initWithCFHTTPCookieStorage:storage] autorelease];
     if (auto* storageSession = SessionTracker::storageSession(sessionID)) {
         if (CFHTTPCookieStorageRef storage = storageSession->cookieStorage().get())
             configuration.HTTPCookieStorage = [[[NSHTTPCookieStorage alloc] _initWithCFHTTPCookieStorage:storage] autorelease];