<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[196082] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/196082">196082</a></dd>
<dt>Author</dt> <dd>jer.noble@apple.com</dd>
<dt>Date</dt> <dd>2016-02-03 14:57:43 -0800 (Wed, 03 Feb 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[Mac] Wrap a resource and resource loader in a NSURLSession-like object for use by lower level frameworks
https://bugs.webkit.org/show_bug.cgi?id=153669

Reviewed by Alex Christensen.

Source/WebCore:

API Test: WebCore.WebCoreNSURLSession

Add a NSURLSession-like object, which wraps a CachedResourceLoader and CachedRawResource, which we can
hand to lower-level frameworks, so that network loads by those frameworks use WebKit's loader.

* platform/network/cocoa/WebCoreNSURLSession.h: Added.
* platform/network/cocoa/WebCoreNSURLSession.mm: Added.
(-[WebCoreNSURLSession initWithResourceLoader:delegate:delegateQueue:]):
(-[WebCoreNSURLSession dealloc]):
(-[WebCoreNSURLSession copyWithZone:]):
(-[WebCoreNSURLSession delegateQueue]):
(-[WebCoreNSURLSession configuration]):
(-[WebCoreNSURLSession loader]):
(-[WebCoreNSURLSession finishTasksAndInvalidate]):
(-[WebCoreNSURLSession invalidateAndCancel]):
(-[WebCoreNSURLSession resetWithCompletionHandler:]):
(-[WebCoreNSURLSession flushWithCompletionHandler:]):
(-[WebCoreNSURLSession getTasksWithCompletionHandler:]):
(-[WebCoreNSURLSession getAllTasksWithCompletionHandler:]):
(-[WebCoreNSURLSession dataTaskWithRequest:]):
(-[WebCoreNSURLSession dataTaskWithURL:]):
(-[WebCoreNSURLSession uploadTaskWithRequest:fromFile:]):
(-[WebCoreNSURLSession uploadTaskWithRequest:fromData:]):
(-[WebCoreNSURLSession uploadTaskWithStreamedRequest:]):
(-[WebCoreNSURLSession downloadTaskWithRequest:]):
(-[WebCoreNSURLSession downloadTaskWithURL:]):
(-[WebCoreNSURLSession downloadTaskWithResumeData:]):
(-[WebCoreNSURLSession streamTaskWithHostName:port:]):
(-[WebCoreNSURLSession streamTaskWithNetService:]):
(-[WebCoreNSURLSession isKindOfClass:]):

Add a C++ class which can act as a CachedRawResourceClient, passing the results back to a WebCoreNSURLSessionDataTask:

(WebCore::WebCoreNSURLSessionDataTaskClient::WebCoreNSURLSessionDataTaskClient):
(WebCore::WebCoreNSURLSessionDataTaskClient::dataSent):
(WebCore::WebCoreNSURLSessionDataTaskClient::responseReceived):
(WebCore::WebCoreNSURLSessionDataTaskClient::dataReceived):
(WebCore::WebCoreNSURLSessionDataTaskClient::redirectReceived):
(WebCore::WebCoreNSURLSessionDataTaskClient::notifyFinished):

Add a NSURLSessionDataTask-like object, which takes a request, then uses it to create and wrap a CachedRawResource.
Becase NSURSessionDataTask is intended to be used off-main-thread, care must be taken to dispatch back to the main-
(or web-) thread before calling CachedRawResource functions.

(-[WebCoreNSURLSessionDataTask initWithSession:identifier:URL:]):
(-[WebCoreNSURLSessionDataTask initWithSession:identifier:request:]):
(-[WebCoreNSURLSessionDataTask copyWithZone:]):
(-[WebCoreNSURLSessionDataTask _restart]):
(-[WebCoreNSURLSessionDataTask _cancel]):
(-[WebCoreNSURLSessionDataTask _finish]):
(-[WebCoreNSURLSessionDataTask _setDefersLoading:]):
(-[WebCoreNSURLSessionDataTask cancel]):
(-[WebCoreNSURLSessionDataTask suspend]):
(-[WebCoreNSURLSessionDataTask resume]):
(-[WebCoreNSURLSessionDataTask _timingData]):
(-[WebCoreNSURLSessionDataTask resource:sentBytes:totalBytesToBeSent:]):
(-[WebCoreNSURLSessionDataTask resource:receivedResponse:]):
(-[WebCoreNSURLSessionDataTask resource:receivedData:length:]):
(-[WebCoreNSURLSessionDataTask resource:receivedRedirect:request:]):
(-[WebCoreNSURLSessionDataTask resourceFinished:]):
* WebCore.xcodeproj/project.pbxproj: Add new files to project.

Tools:

Add an API test for WebCoreNSURLSession, testing that it behaves like a regulare NSURLSession, including
calling appropriate NSURLSessionDelegate callbacks.

Drive-by fix: Add a FeatureDefines.xcconfig to TestWebKitAPI.  Without this, the ENABLE macros in WebCore
header files will not match the one used when compiling WebCore, leading to strange crashes and weird
inconsistencies when calling, e.g., inline methods.

* TestWebKitAPI/Configurations/FeatureDefines.xcconfig: Added.
* TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig:
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebCore/WebCoreNSURLSession.mm: Added.
(-[TestNSURLSessionLoaderDelegate webView:didCommitLoadForFrame:]):
(-[TestNSURLSessionDataDelegate URLSession:task:didCompleteWithError:]):
(-[TestNSURLSessionDataDelegate URLSession:dataTask:didReceiveResponse:completionHandler:]):
(-[TestNSURLSessionDataDelegate URLSession:dataTask:didReceiveData:]):
(TestWebKitAPI::WebCoreNSURLSessionTest::SetUp):
(TestWebKitAPI::WebCoreNSURLSessionTest::TearDown):
(TestWebKitAPI::TEST_F):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPIConfigurationsTestWebKitAPIxcconfig">trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig</a></li>
<li><a href="#trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj">trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreplatformnetworkcocoaWebCoreNSURLSessionh">trunk/Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.h</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkcocoaWebCoreNSURLSessionmm">trunk/Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.mm</a></li>
<li><a href="#trunkToolsTestWebKitAPIConfigurationsFeatureDefinesxcconfig">trunk/Tools/TestWebKitAPI/Configurations/FeatureDefines.xcconfig</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebCoreWebCoreNSURLSessionmm">trunk/Tools/TestWebKitAPI/Tests/WebCore/WebCoreNSURLSession.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (196081 => 196082)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-02-03 22:46:57 UTC (rev 196081)
+++ trunk/Source/WebCore/ChangeLog        2016-02-03 22:57:43 UTC (rev 196082)
</span><span class="lines">@@ -1,3 +1,72 @@
</span><ins>+2016-02-03  Jer Noble  &lt;jer.noble@apple.com&gt;
+
+        [Mac] Wrap a resource and resource loader in a NSURLSession-like object for use by lower level frameworks
+        https://bugs.webkit.org/show_bug.cgi?id=153669
+
+        Reviewed by Alex Christensen.
+
+        API Test: WebCore.WebCoreNSURLSession
+
+        Add a NSURLSession-like object, which wraps a CachedResourceLoader and CachedRawResource, which we can
+        hand to lower-level frameworks, so that network loads by those frameworks use WebKit's loader.
+
+        * platform/network/cocoa/WebCoreNSURLSession.h: Added.
+        * platform/network/cocoa/WebCoreNSURLSession.mm: Added.
+        (-[WebCoreNSURLSession initWithResourceLoader:delegate:delegateQueue:]):
+        (-[WebCoreNSURLSession dealloc]):
+        (-[WebCoreNSURLSession copyWithZone:]):
+        (-[WebCoreNSURLSession delegateQueue]):
+        (-[WebCoreNSURLSession configuration]):
+        (-[WebCoreNSURLSession loader]):
+        (-[WebCoreNSURLSession finishTasksAndInvalidate]):
+        (-[WebCoreNSURLSession invalidateAndCancel]):
+        (-[WebCoreNSURLSession resetWithCompletionHandler:]):
+        (-[WebCoreNSURLSession flushWithCompletionHandler:]):
+        (-[WebCoreNSURLSession getTasksWithCompletionHandler:]):
+        (-[WebCoreNSURLSession getAllTasksWithCompletionHandler:]):
+        (-[WebCoreNSURLSession dataTaskWithRequest:]):
+        (-[WebCoreNSURLSession dataTaskWithURL:]):
+        (-[WebCoreNSURLSession uploadTaskWithRequest:fromFile:]):
+        (-[WebCoreNSURLSession uploadTaskWithRequest:fromData:]):
+        (-[WebCoreNSURLSession uploadTaskWithStreamedRequest:]):
+        (-[WebCoreNSURLSession downloadTaskWithRequest:]):
+        (-[WebCoreNSURLSession downloadTaskWithURL:]):
+        (-[WebCoreNSURLSession downloadTaskWithResumeData:]):
+        (-[WebCoreNSURLSession streamTaskWithHostName:port:]):
+        (-[WebCoreNSURLSession streamTaskWithNetService:]):
+        (-[WebCoreNSURLSession isKindOfClass:]):
+
+        Add a C++ class which can act as a CachedRawResourceClient, passing the results back to a WebCoreNSURLSessionDataTask:
+
+        (WebCore::WebCoreNSURLSessionDataTaskClient::WebCoreNSURLSessionDataTaskClient):
+        (WebCore::WebCoreNSURLSessionDataTaskClient::dataSent):
+        (WebCore::WebCoreNSURLSessionDataTaskClient::responseReceived):
+        (WebCore::WebCoreNSURLSessionDataTaskClient::dataReceived):
+        (WebCore::WebCoreNSURLSessionDataTaskClient::redirectReceived):
+        (WebCore::WebCoreNSURLSessionDataTaskClient::notifyFinished):
+
+        Add a NSURLSessionDataTask-like object, which takes a request, then uses it to create and wrap a CachedRawResource.
+        Becase NSURSessionDataTask is intended to be used off-main-thread, care must be taken to dispatch back to the main-
+        (or web-) thread before calling CachedRawResource functions.
+
+        (-[WebCoreNSURLSessionDataTask initWithSession:identifier:URL:]):
+        (-[WebCoreNSURLSessionDataTask initWithSession:identifier:request:]):
+        (-[WebCoreNSURLSessionDataTask copyWithZone:]):
+        (-[WebCoreNSURLSessionDataTask _restart]):
+        (-[WebCoreNSURLSessionDataTask _cancel]):
+        (-[WebCoreNSURLSessionDataTask _finish]):
+        (-[WebCoreNSURLSessionDataTask _setDefersLoading:]):
+        (-[WebCoreNSURLSessionDataTask cancel]):
+        (-[WebCoreNSURLSessionDataTask suspend]):
+        (-[WebCoreNSURLSessionDataTask resume]):
+        (-[WebCoreNSURLSessionDataTask _timingData]):
+        (-[WebCoreNSURLSessionDataTask resource:sentBytes:totalBytesToBeSent:]):
+        (-[WebCoreNSURLSessionDataTask resource:receivedResponse:]):
+        (-[WebCoreNSURLSessionDataTask resource:receivedData:length:]):
+        (-[WebCoreNSURLSessionDataTask resource:receivedRedirect:request:]):
+        (-[WebCoreNSURLSessionDataTask resourceFinished:]):
+        * WebCore.xcodeproj/project.pbxproj: Add new files to project.
+
</ins><span class="cx"> 2016-02-03  Darin Adler  &lt;darin@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Convert another batch of String::lower callsites to something better, typically convertToASCIILowercase
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (196081 => 196082)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-02-03 22:46:57 UTC (rev 196081)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-02-03 22:57:43 UTC (rev 196082)
</span><span class="lines">@@ -5990,6 +5990,8 @@
</span><span class="cx">                 CD19A2681A13E700008D650E /* DiagnosticLoggingClient.h in Headers */ = {isa = PBXBuildFile; fileRef = CD19A2671A13E700008D650E /* DiagnosticLoggingClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 CD1B4A65160786AE00282DF9 /* MediaKeyNeededEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDA98DC216014EEE00FEA3B1 /* MediaKeyNeededEvent.cpp */; };
</span><span class="cx">                 CD1E7347167BC78E009A885D /* TextTrackRepresentation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD1E7346167BC78E009A885D /* TextTrackRepresentation.cpp */; };
</span><ins>+                CD225C0B1C46FBF400140761 /* WebCoreNSURLSession.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD225C091C46FBF400140761 /* WebCoreNSURLSession.mm */; };
+                CD225C0C1C46FBF400140761 /* WebCoreNSURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = CD225C0A1C46FBF400140761 /* WebCoreNSURLSession.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 CD27F6E51457685A0078207D /* JSMediaController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD27F6E2145767580078207D /* JSMediaController.cpp */; };
</span><span class="cx">                 CD27F6E7145770D30078207D /* MediaController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD27F6E6145770D30078207D /* MediaController.cpp */; };
</span><span class="cx">                 CD2F4A2318D89F700063746D /* AudioHardwareListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD2F4A2118D89F700063746D /* AudioHardwareListener.cpp */; };
</span><span class="lines">@@ -13880,6 +13882,8 @@
</span><span class="cx">                 CD127DEB14F3097900E84779 /* WebCoreFullScreenWindow.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCoreFullScreenWindow.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CD19A2671A13E700008D650E /* DiagnosticLoggingClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiagnosticLoggingClient.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CD1E7346167BC78E009A885D /* TextTrackRepresentation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextTrackRepresentation.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                CD225C091C46FBF400140761 /* WebCoreNSURLSession.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCoreNSURLSession.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
+                CD225C0A1C46FBF400140761 /* WebCoreNSURLSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebCoreNSURLSession.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 CD27F6E014575C1B0078207D /* MediaController.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = MediaController.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CD27F6E2145767580078207D /* JSMediaController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMediaController.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CD27F6E3145767580078207D /* JSMediaController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMediaController.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -18068,6 +18072,8 @@
</span><span class="cx">                                 5C9B860B1C21E3C600110F36 /* ResourceLoadTiming.mm */,
</span><span class="cx">                                 7E7DE1FC195CEF260035363B /* ResourceRequestCocoa.mm */,
</span><span class="cx">                                 A1F78D0B1C25422C00245446 /* ResourceResponseCocoa.mm */,
</span><ins>+                                CD225C091C46FBF400140761 /* WebCoreNSURLSession.mm */,
+                                CD225C0A1C46FBF400140761 /* WebCoreNSURLSession.h */,
</ins><span class="cx">                         );
</span><span class="cx">                         path = cocoa;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="lines">@@ -27474,6 +27480,7 @@
</span><span class="cx">                                 973E325710883B7C005BC493 /* ResourceLoadNotifier.h in Headers */,
</span><span class="cx">                                 E4295FA412B0614E00D1ACE0 /* ResourceLoadPriority.h in Headers */,
</span><span class="cx">                                 8A81BF8511DCFD9000DA2B98 /* ResourceLoadTiming.h in Headers */,
</span><ins>+                                CD225C0C1C46FBF400140761 /* WebCoreNSURLSession.h in Headers */,
</ins><span class="cx">                                 7EE6846D12D26E3800E79415 /* ResourceRequest.h in Headers */,
</span><span class="cx">                                 514C767D0CE923A1007EF3CD /* ResourceRequestBase.h in Headers */,
</span><span class="cx">                                 7EE6846F12D26E3800E79415 /* ResourceRequestCFNet.h in Headers */,
</span><span class="lines">@@ -28921,6 +28928,7 @@
</span><span class="cx">                                 FD315FFE12B0267600C1A359 /* ChannelMergerNode.cpp in Sources */,
</span><span class="cx">                                 FD31600112B0267600C1A359 /* ChannelSplitterNode.cpp in Sources */,
</span><span class="cx">                                 6550B69F099DF0270090D781 /* CharacterData.cpp in Sources */,
</span><ins>+                                CD225C0B1C46FBF400140761 /* WebCoreNSURLSession.mm in Sources */,
</ins><span class="cx">                                 9326DC0C09DAD5D600AFC847 /* CharsetData.cpp in Sources */,
</span><span class="cx">                                 F55B3DB11251F12D003EF269 /* CheckboxInputType.cpp in Sources */,
</span><span class="cx">                                 93F925440F7EF5B8007E37C9 /* CheckedRadioButtons.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkcocoaWebCoreNSURLSessionh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.h (0 => 196082)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.h                                (rev 0)
+++ trunk/Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.h        2016-02-03 22:57:43 UTC (rev 196082)
</span><span class="lines">@@ -0,0 +1,132 @@
</span><ins>+/*
+ * Copyright (C) 2016 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 COMPUTER, 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 COMPUTER, 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. 
+ */
+
+#ifndef WebCoreNSURLSession_h
+#define WebCoreNSURLSession_h
+
+#import &quot;CachedRawResource.h&quot;
+#import &quot;CachedResourceHandle.h&quot;
+#import &lt;Foundation/NSURLSession.h&gt;
+#import &lt;wtf/HashSet.h&gt;
+#import &lt;wtf/RefPtr.h&gt;
+#import &lt;wtf/RetainPtr.h&gt;
+
+@class NSNetService;
+@class NSOperationQueue;
+@class NSURL;
+@class NSURLRequest;
+@class NSURLResponse;
+@class WebCoreNSURLSessionDataTask;
+
+namespace WebCore {
+class CachedResourceLoader;
+class CachedResourceRequest;
+class WebCoreNSURLSessionDataTaskClient;
+}
+
+NS_ASSUME_NONNULL_BEGIN
+
+WEBCORE_EXPORT @interface WebCoreNSURLSession : NSObject {
+    RefPtr&lt;WebCore::CachedResourceLoader&gt; _loader;
+    RetainPtr&lt;id&lt;NSURLSessionDelegate&gt;&gt; _delegate;
+    RetainPtr&lt;NSOperationQueue&gt; _queue;
+    NSString *_sessionDescription;
+    HashSet&lt;RetainPtr&lt;WebCoreNSURLSessionDataTask&gt;&gt; _dataTasks;
+    BOOL _invalidated;
+    NSUInteger _nextTaskIdentifier;
+}
+- (id)initWithResourceLoader:(WebCore::CachedResourceLoader&amp;)loader delegate:(id&lt;NSURLSessionTaskDelegate&gt;)delegate delegateQueue:(NSOperationQueue*)queue;
+@property (readonly, retain) NSOperationQueue *delegateQueue;
+@property (nullable, readonly, retain) id &lt;NSURLSessionDelegate&gt; delegate;
+@property (readonly, copy) NSURLSessionConfiguration *configuration;
+@property (copy) NSString *sessionDescription;
+- (void)finishTasksAndInvalidate;
+- (void)invalidateAndCancel;
+
+- (void)resetWithCompletionHandler:(void (^)(void))completionHandler;
+- (void)flushWithCompletionHandler:(void (^)(void))completionHandler;
+- (void)getTasksWithCompletionHandler:(void (^)(NSArray&lt;NSURLSessionDataTask *&gt; *dataTasks, NSArray&lt;NSURLSessionUploadTask *&gt; *uploadTasks, NSArray&lt;NSURLSessionDownloadTask *&gt; *downloadTasks))completionHandler;
+- (void)getAllTasksWithCompletionHandler:(void (^)(NSArray&lt;__kindof NSURLSessionTask *&gt; *tasks))completionHandler;
+
+- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request;
+- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url;
+- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL;
+- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(NSData *)bodyData;
+- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request;
+- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request;
+- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url;
+- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData;
+- (NSURLSessionStreamTask *)streamTaskWithHostName:(NSString *)hostname port:(NSInteger)port;
+- (NSURLSessionStreamTask *)streamTaskWithNetService:(NSNetService *)service;
+@end
+
+@interface WebCoreNSURLSession (NSURLSessionAsynchronousConvenience)
+- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSData * data, NSURLResponse * response, NSError * error))completionHandler;
+- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSData * data, NSURLResponse * response, NSError * error))completionHandler;
+- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL completionHandler:(void (^)(NSData * data, NSURLResponse * response, NSError * error))completionHandler;
+- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(nullable NSData *)bodyData completionHandler:(void (^)(NSData * data, NSURLResponse * response, NSError * error))completionHandler;
+- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURL * location, NSURLResponse * response, NSError * error))completionHandler;
+- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSURL * location, NSURLResponse * response, NSError * error))completionHandler;
+- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData completionHandler:(void (^)(NSURL * location, NSURLResponse * response, NSError * error))completionHandler;
+@end
+
+@interface WebCoreNSURLSessionDataTask : NSObject {
+    WebCoreNSURLSession *_session;
+    std::unique_ptr&lt;WebCore::CachedResourceRequest&gt; _request;
+    std::unique_ptr&lt;WebCore::WebCoreNSURLSessionDataTaskClient&gt; _client;
+    WebCore::CachedResourceHandle&lt;WebCore::CachedRawResource&gt; _resource;
+    RetainPtr&lt;NSURLResponse&gt; _response;
+    NSUInteger _taskIdentifier;
+    NSURLRequest *_originalRequest;
+    NSURLRequest *_currentRequest;
+    int64_t _countOfBytesReceived;
+    int64_t _countOfBytesSent;
+    int64_t _countOfBytesExpectedToSend;
+    int64_t _countOfBytesExpectedToReceive;
+    NSURLSessionTaskState _state;
+    NSError *_error;
+    NSString *_taskDescription;
+    float _priority;
+}
+@property (readwrite) NSUInteger taskIdentifier;
+@property (readwrite, copy) NSURLRequest *originalRequest;
+@property (readwrite, copy) NSURLRequest *currentRequest;
+@property (readonly, copy) NSURLResponse *response;
+@property (readwrite) int64_t countOfBytesReceived;
+@property (readwrite) int64_t countOfBytesSent;
+@property (readwrite) int64_t countOfBytesExpectedToSend;
+@property (readwrite) int64_t countOfBytesExpectedToReceive;
+@property (readwrite) NSURLSessionTaskState state;
+@property (readwrite, copy) NSError *error;
+@property (copy) NSString *taskDescription;
+@property float priority;
+- (void)cancel;
+- (void)suspend;
+- (void)resume;
+@end
+
+NS_ASSUME_NONNULL_END
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkcocoaWebCoreNSURLSessionmm"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.mm (0 => 196082)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.mm                                (rev 0)
+++ trunk/Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.mm        2016-02-03 22:57:43 UTC (rev 196082)
</span><span class="lines">@@ -0,0 +1,548 @@
</span><ins>+/*
+ * Copyright (C) 2016 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 COMPUTER, 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 COMPUTER, 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 &quot;config.h&quot;
+#import &quot;WebCoreNSURLSession.h&quot;
+
+#import &quot;CachedRawResource.h&quot;
+#import &quot;CachedResourceLoader.h&quot;
+#import &quot;CachedResourceRequest.h&quot;
+#import &quot;SoftLinking.h&quot;
+#import &quot;SubresourceLoader.h&quot;
+
+using namespace WebCore;
+
+#pragma mark - Soft linking
+
+// FIXME: Soft Linking is required for Yosemite; remove once Yosemite support is no longer needed.
+SOFT_LINK_FRAMEWORK(Foundation);
+SOFT_LINK_CONSTANT_MAY_FAIL(Foundation, NSURLSessionTaskPriorityDefault, float)
+#define NSURLSessionTaskPriorityDefault getNSURLSessionTaskPriorityDefault()
+
+#pragma mark - Private declarations
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface WebCoreNSURLSession ()
+@property (readonly) CachedResourceLoader&amp; loader;
+@property (readwrite, retain) id&lt;NSURLSessionTaskDelegate&gt; delegate;
+- (void)taskCompleted:(WebCoreNSURLSessionDataTask *)task;
+@end
+
+@interface WebCoreNSURLSessionDataTask ()
+- (id)initWithSession:(WebCoreNSURLSession *)session identifier:(NSUInteger)identifier request:(NSURLRequest *)request;
+- (id)initWithSession:(WebCoreNSURLSession *)session identifier:(NSUInteger)identifier URL:(NSURL *)url;
+- (void)_restart;
+- (void)_cancel;
+- (void)_finish;
+- (void)_setDefersLoading:(BOOL)defers;
+@property (assign) WebCoreNSURLSession * _Nullable session;
+
+- (void)resource:(CachedResource*)resource sentBytes:(unsigned long long)bytesSent totalBytesToBeSent:(unsigned long long)totalBytesToBeSent;
+- (void)resource:(CachedResource*)resource receivedResponse:(const ResourceResponse&amp;)response;
+- (void)resource:(CachedResource*)resource receivedData:(const char*)data length:(int)length;
+- (void)resource:(CachedResource*)resource receivedRedirect:(const ResourceResponse&amp;)response request:(ResourceRequest&amp;)request;
+- (void)resourceFinished:(CachedResource*)resource;
+@end
+
+NS_ASSUME_NONNULL_END
+
+#pragma mark - WebCoreNSURLSession
+
+@implementation WebCoreNSURLSession
+- (id)initWithResourceLoader:(CachedResourceLoader&amp;)loader delegate:(id&lt;NSURLSessionTaskDelegate&gt;)inDelegate delegateQueue:(NSOperationQueue*)inQueue
+{
+    self = [super init];
+    if (!self)
+        return nil;
+
+    _loader = &amp;loader;
+    self.delegate = inDelegate;
+    _queue = inQueue ? inQueue : [NSOperationQueue mainQueue];
+    _invalidated = NO;
+    return self;
+}
+
+- (void)dealloc
+{
+    for (auto&amp; task : _dataTasks)
+        task.get().session = nil;
+    [super dealloc];
+}
+
+- (id)copyWithZone:(NSZone *)zone
+{
+    UNUSED_PARAM(zone);
+    return [self retain];
+}
+
+#pragma mark - Internal Methods
+
+- (void)taskCompleted:(WebCoreNSURLSessionDataTask *)task
+{
+    ASSERT(_dataTasks.contains(task));
+    _dataTasks.remove(task);
+    if (!_dataTasks.isEmpty() || !_invalidated)
+        return;
+
+    RetainPtr&lt;WebCoreNSURLSession&gt; strongSelf { self };
+    [self.delegateQueue addOperationWithBlock:[strongSelf] {
+        if ([strongSelf.get().delegate respondsToSelector:@selector(URLSession:didBecomeInvalidWithError:)])
+            [strongSelf.get().delegate URLSession:(NSURLSession *)strongSelf.get() didBecomeInvalidWithError:nil];
+    }];
+}
+
+#pragma mark - NSURLSession API
+@synthesize sessionDescription=_sessionDescription;
+@dynamic delegate;
+- (__nullable id&lt;NSURLSessionDelegate&gt;)delegate
+{
+    return _delegate.get();
+}
+
+- (void)setDelegate:(id&lt;NSURLSessionDelegate&gt;)delegate
+{
+    _delegate = delegate;
+}
+
+@dynamic delegateQueue;
+- (NSOperationQueue *)delegateQueue
+{
+    return _queue.get();
+}
+
+@dynamic configuration;
+- (NSURLSessionConfiguration *)configuration
+{
+    return nil;
+}
+
+@dynamic loader;
+- (CachedResourceLoader&amp;)loader
+{
+    return *_loader;
+}
+
+- (void)finishTasksAndInvalidate
+{
+    _invalidated = YES;
+    if (!_dataTasks.isEmpty())
+        return;
+
+    RetainPtr&lt;WebCoreNSURLSession&gt; strongSelf { self };
+    [self.delegateQueue addOperationWithBlock:[strongSelf] {
+        if ([strongSelf.get().delegate respondsToSelector:@selector(URLSession:didBecomeInvalidWithError:)])
+            [strongSelf.get().delegate URLSession:(NSURLSession *)strongSelf.get() didBecomeInvalidWithError:nil];
+    }];
+}
+
+- (void)invalidateAndCancel
+{
+    for (auto&amp; task : _dataTasks)
+        [task cancel];
+
+    [self finishTasksAndInvalidate];
+}
+
+- (void)resetWithCompletionHandler:(void (^)(void))completionHandler
+{
+    // FIXME: This cannot currently be implemented. We cannot guarantee that the next connection will happen on a new socket.
+    [self.delegateQueue addOperationWithBlock:completionHandler];
+}
+
+- (void)flushWithCompletionHandler:(void (^)(void))completionHandler
+{
+    // FIXME: This cannot currently be implemented. We cannot guarantee that the next connection will happen on a new socket.
+    [self.delegateQueue addOperationWithBlock:completionHandler];
+}
+
+- (void)getTasksWithCompletionHandler:(void (^)(NSArray&lt;NSURLSessionDataTask *&gt; *dataTasks, NSArray&lt;NSURLSessionUploadTask *&gt; *uploadTasks, NSArray&lt;NSURLSessionDownloadTask *&gt; *downloadTasks))completionHandler
+{
+    NSMutableArray *array = [NSMutableArray arrayWithCapacity:_dataTasks.size()];
+    for (auto&amp; task : _dataTasks)
+        [array addObject:task.get()];
+    [self.delegateQueue addOperationWithBlock:^{
+        completionHandler(array, nil, nil);
+    }];
+}
+
+- (void)getAllTasksWithCompletionHandler:(void (^)(NSArray&lt;__kindof NSURLSessionTask *&gt; *tasks))completionHandler
+{
+    NSMutableArray *array = [NSMutableArray arrayWithCapacity:_dataTasks.size()];
+    for (auto&amp; task : _dataTasks)
+        [array addObject:task.get()];
+    [self.delegateQueue addOperationWithBlock:^{
+        completionHandler(array);
+    }];
+}
+
+- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
+{
+    if (_invalidated)
+        return nil;
+
+    WebCoreNSURLSessionDataTask *task = [[WebCoreNSURLSessionDataTask alloc] initWithSession:self identifier:_nextTaskIdentifier++ request:request];
+    _dataTasks.add(task);
+    return (NSURLSessionDataTask *)[task autorelease];
+}
+
+- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url
+{
+    if (_invalidated)
+        return nil;
+
+    WebCoreNSURLSessionDataTask *task = [[WebCoreNSURLSessionDataTask alloc] initWithSession:self identifier:_nextTaskIdentifier++ URL:url];
+    _dataTasks.add(task);
+    return (NSURLSessionDataTask *)[task autorelease];
+}
+
+- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL
+{
+    UNUSED_PARAM(request);
+    UNUSED_PARAM(fileURL);
+    return nil;
+}
+
+- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(NSData *)bodyData
+{
+    UNUSED_PARAM(request);
+    UNUSED_PARAM(bodyData);
+    return nil;
+}
+
+- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request
+{
+    UNUSED_PARAM(request);
+    return nil;
+}
+
+- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request
+{
+    UNUSED_PARAM(request);
+    return nil;
+}
+
+- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url
+{
+    UNUSED_PARAM(url);
+    return nil;
+}
+
+- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData
+{
+    UNUSED_PARAM(resumeData);
+    return nil;
+}
+
+- (NSURLSessionStreamTask *)streamTaskWithHostName:(NSString *)hostname port:(NSInteger)port
+{
+    UNUSED_PARAM(hostname);
+    UNUSED_PARAM(port);
+    return nil;
+}
+
+- (NSURLSessionStreamTask *)streamTaskWithNetService:(NSNetService *)service
+{
+    UNUSED_PARAM(service);
+    return nil;
+}
+
+- (BOOL)isKindOfClass:(Class)aClass
+{
+    if (aClass == [NSURLSession class])
+        return YES;
+    return [super isKindOfClass:aClass];
+}
+@end
+
+#pragma mark - WebCoreNSURLSessionDataTaskClient
+
+namespace WebCore {
+
+class WebCoreNSURLSessionDataTaskClient : public CachedRawResourceClient {
+public:
+    WebCoreNSURLSessionDataTaskClient(WebCoreNSURLSessionDataTask *task)
+        : m_task(task)
+    {
+    }
+
+    void dataSent(CachedResource*, unsigned long long, unsigned long long) override;
+    void responseReceived(CachedResource*, const ResourceResponse&amp;) override;
+    void dataReceived(CachedResource*, const char* /* data */, int /* length */) override;
+    void redirectReceived(CachedResource*, ResourceRequest&amp;, const ResourceResponse&amp;) override;
+    void notifyFinished(CachedResource*) override;
+
+private:
+    WebCoreNSURLSessionDataTask *m_task;
+};
+
+void WebCoreNSURLSessionDataTaskClient::dataSent(CachedResource* resource, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
+{
+    [m_task resource:resource sentBytes:bytesSent totalBytesToBeSent:totalBytesToBeSent];
+}
+
+void WebCoreNSURLSessionDataTaskClient::responseReceived(CachedResource* resource, const ResourceResponse&amp; response)
+{
+    [m_task resource:resource receivedResponse:response];
+}
+
+void WebCoreNSURLSessionDataTaskClient::dataReceived(CachedResource* resource, const char* data, int length)
+{
+    [m_task resource:resource receivedData:data length:length];
+}
+
+void WebCoreNSURLSessionDataTaskClient::redirectReceived(CachedResource* resource, ResourceRequest&amp; request, const ResourceResponse&amp; response)
+{
+    [m_task resource:resource receivedRedirect:response request:request];
+}
+
+void WebCoreNSURLSessionDataTaskClient::notifyFinished(CachedResource* resource)
+{
+    [m_task resourceFinished:resource];
+}
+
+}
+
+#pragma mark - WebCoreNSURLSessionDataTask
+
+@implementation WebCoreNSURLSessionDataTask
+- (id)initWithSession:(WebCoreNSURLSession *)session identifier:(NSUInteger)identifier URL:(NSURL *)url
+{
+    self.taskIdentifier = identifier;
+    self.session = session;
+    self.state = NSURLSessionTaskStateSuspended;
+    self.priority = canLoadNSURLSessionTaskPriorityDefault() ? NSURLSessionTaskPriorityDefault : 0.5f;
+    self.originalRequest = self.currentRequest = [NSURLRequest requestWithURL:url];
+    _client = std::make_unique&lt;WebCoreNSURLSessionDataTaskClient&gt;(self);
+
+    return self;
+}
+
+- (id)initWithSession:(WebCoreNSURLSession *)session identifier:(NSUInteger)identifier request:(NSURLRequest *)request
+{
+    self.taskIdentifier = identifier;
+    self.session = session;
+    self.state = NSURLSessionTaskStateSuspended;
+    self.priority = canLoadNSURLSessionTaskPriorityDefault() ? NSURLSessionTaskPriorityDefault : 0.5f;
+    self.originalRequest = self.currentRequest = request;
+    _client = std::make_unique&lt;WebCoreNSURLSessionDataTaskClient&gt;(self);
+
+    return self;
+}
+
+- (id)copyWithZone:(NSZone *)zone
+{
+    UNUSED_PARAM(zone);
+    return [self retain];
+}
+
+#pragma mark - Internal methods
+
+- (void)_restart
+{
+    ASSERT(isMainThread());
+    [self _cancel];
+
+    _request = std::make_unique&lt;CachedResourceRequest&gt;(self.originalRequest, ResourceLoaderOptions(SendCallbacks, DoNotSniffContent, DoNotBufferData, DoNotAllowStoredCredentials, DoNotAskClientForCrossOriginCredentials, ClientDidNotRequestCredentials, DoSecurityCheck, UseDefaultOriginRestrictionsForType, DoNotIncludeCertificateInfo, ContentSecurityPolicyImposition::DoPolicyCheck, DefersLoadingPolicy::AllowDefersLoading, CachingPolicy::DisallowCaching));
+    _resource = self.session.loader.requestRawResource(*_request);
+    if (_resource)
+        _resource-&gt;addClient(_client.get());
+}
+
+- (void)_cancel
+{
+    ASSERT(isMainThread());
+    if (_resource) {
+        if (SubresourceLoader* loader = _resource-&gt;loader())
+            loader-&gt;cancel(ResourceError());
+        _resource-&gt;removeClient(_client.get());
+        _resource = nil;
+    }
+}
+
+- (void)_finish
+{
+    ASSERT(isMainThread());
+    if (_resource)
+        [self resourceFinished:_resource.get()];
+}
+
+- (void)_setDefersLoading:(BOOL)defers
+{
+    ASSERT(isMainThread());
+    if (_resource &amp;&amp; _resource-&gt;loader())
+        _resource-&gt;loader()-&gt;setDefersLoading(defers);
+}
+
+#pragma mark - NSURLSession API
+@synthesize session=_session;
+@synthesize taskIdentifier=_taskIdentifier;
+@synthesize originalRequest=_originalRequest;
+@synthesize currentRequest=_currentRequest;
+@synthesize countOfBytesReceived=_countOfBytesReceived;
+@synthesize countOfBytesSent=_countOfBytesSent;
+@synthesize countOfBytesExpectedToSend=_countOfBytesExpectedToSend;
+@synthesize countOfBytesExpectedToReceive=_countOfBytesExpectedToReceive;
+@synthesize state=_state;
+@synthesize error=_error;
+@synthesize taskDescription=_taskDescription;
+@synthesize priority=_priority;
+@dynamic response;
+- (NSURLResponse *)response
+{
+    return _response.get();
+}
+
+- (void)cancel
+{
+    self.state = NSURLSessionTaskStateCanceling;
+    RetainPtr&lt;WebCoreNSURLSessionDataTask&gt; strongSelf { self };
+    callOnMainThread([strongSelf] {
+        [strongSelf _cancel];
+        [strongSelf _finish];
+    });
+}
+
+- (void)suspend
+{
+    RetainPtr&lt;WebCoreNSURLSessionDataTask&gt; strongSelf { self };
+    callOnMainThread([strongSelf] {
+        // NSURLSessionDataTasks must start over after suspending, so while
+        // we could defer loading at this point, instead cancel and restart
+        // upon resume so as to adhere to NSURLSessionDataTask semantics.
+        [strongSelf _cancel];
+        strongSelf.get().state = NSURLSessionTaskStateSuspended;
+    });
+}
+
+- (void)resume
+{
+    RetainPtr&lt;WebCoreNSURLSessionDataTask&gt; strongSelf { self };
+    callOnMainThread([strongSelf] {
+        if (strongSelf.get().state != NSURLSessionTaskStateSuspended)
+            return;
+
+        [strongSelf _restart];
+        strongSelf.get().state = NSURLSessionTaskStateRunning;
+    });
+}
+
+#pragma mark - NSURLSession SPI
+
+- (NSDictionary *)_timingData
+{
+    // FIXME: return a dictionary sourced from ResourceHandle::getConnectionTimingData().
+    return @{ };
+}
+
+#pragma mark - CachedRawResourceClient callbacks
+
+- (void)resource:(CachedResource*)resource sentBytes:(unsigned long long)bytesSent totalBytesToBeSent:(unsigned long long)totalBytesToBeSent
+{
+    ASSERT_UNUSED(resource, resource == _resource);
+    UNUSED_PARAM(bytesSent);
+    UNUSED_PARAM(totalBytesToBeSent);
+    // No-op.
+}
+
+- (void)resource:(CachedResource*)resource receivedResponse:(const ResourceResponse&amp;)response
+{
+    ASSERT_UNUSED(resource, resource == _resource);
+    ASSERT(isMainThread());
+    _response = response.nsURLResponse();
+    self.countOfBytesExpectedToReceive = response.expectedContentLength();
+    [self _setDefersLoading:YES];
+    RetainPtr&lt;WebCoreNSURLSessionDataTask&gt; strongSelf { self };
+    [self.session.delegateQueue addOperationWithBlock:[strongSelf] {
+        id&lt;NSURLSessionDataDelegate&gt; dataDelegate = (id&lt;NSURLSessionDataDelegate&gt;)strongSelf.get().session.delegate;
+        if (![dataDelegate respondsToSelector:@selector(URLSession:dataTask:didReceiveResponse:completionHandler:)]) {
+            callOnMainThread([strongSelf] {
+                [strongSelf _setDefersLoading:NO];
+            });
+            return;
+        }
+
+        [dataDelegate URLSession:(NSURLSession *)strongSelf.get().session dataTask:(NSURLSessionDataTask *)strongSelf.get() didReceiveResponse:strongSelf.get().response completionHandler:[strongSelf] (NSURLSessionResponseDisposition disposition) {
+            if (disposition == NSURLSessionResponseCancel)
+                [strongSelf cancel];
+            else if (disposition == NSURLSessionResponseAllow)
+                [strongSelf resume];
+            else
+                ASSERT_NOT_REACHED();
+            callOnMainThread([strongSelf] {
+                [strongSelf _setDefersLoading:NO];
+            });
+        }];
+    }];
+}
+
+- (void)resource:(CachedResource*)resource receivedData:(const char*)data length:(int)length
+{
+    ASSERT_UNUSED(resource, resource == _resource);
+    UNUSED_PARAM(data);
+    UNUSED_PARAM(length);
+    // FIXME: try to avoid a copy, if possible.
+    // e.g., RetainPtr&lt;CFDataRef&gt; cfData = resource-&gt;resourceBuffer()-&gt;createCFData();
+
+    RetainPtr&lt;NSData&gt; nsData = adoptNS([[NSData alloc] initWithBytes:data length:length]);
+    RetainPtr&lt;WebCoreNSURLSessionDataTask&gt; strongSelf { self };
+    [self.session.delegateQueue addOperationWithBlock:[strongSelf, length, nsData] {
+        strongSelf.get().countOfBytesReceived += length;
+        id&lt;NSURLSessionDataDelegate&gt; dataDelegate = (id&lt;NSURLSessionDataDelegate&gt;)strongSelf.get().session.delegate;
+        if ([dataDelegate respondsToSelector:@selector(URLSession:dataTask:didReceiveData:)])
+            [dataDelegate URLSession:(NSURLSession *)strongSelf.get().session dataTask:(NSURLSessionDataTask *)strongSelf.get() didReceiveData:nsData.get()];
+    }];
+}
+
+- (void)resource:(CachedResource*)resource receivedRedirect:(const ResourceResponse&amp;)response request:(ResourceRequest&amp;)request
+{
+    ASSERT_UNUSED(resource, resource == _resource);
+    UNUSED_PARAM(response);
+    UNUSED_PARAM(request);
+    // FIXME: This cannot currently be implemented, as the callback is synchronous
+    // on the main thread, and the NSURLSession delegate must be called back on a
+    // background queue, and we do not want to block the main thread until the
+    // delegate handles the callback and responds via a completion handler. If, in
+    // the future, the ResourceLoader exposes a callback-based willSendResponse
+    // API, this can be implemented.
+}
+
+- (void)resourceFinished:(CachedResource*)resource
+{
+    ASSERT_UNUSED(resource, resource == _resource);
+    self.state = NSURLSessionTaskStateCompleted;
+
+    RetainPtr&lt;WebCoreNSURLSessionDataTask&gt; strongSelf { self };
+    [self.session.delegateQueue addOperationWithBlock:[strongSelf] {
+        id&lt;NSURLSessionTaskDelegate&gt; delegate = (id&lt;NSURLSessionTaskDelegate&gt;)strongSelf.get().session.delegate;
+        if ([delegate respondsToSelector:@selector(URLSession:task:didCompleteWithError:)])
+            [delegate URLSession:(NSURLSession *)strongSelf.get().session task:(NSURLSessionDataTask *)strongSelf.get() didCompleteWithError:nil];
+
+        callOnMainThread([strongSelf] {
+            [strongSelf.get().session taskCompleted:strongSelf.get()];
+        });
+    }];
+}
+@end
</ins></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (196081 => 196082)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2016-02-03 22:46:57 UTC (rev 196081)
+++ trunk/Tools/ChangeLog        2016-02-03 22:57:43 UTC (rev 196082)
</span><span class="lines">@@ -1,3 +1,29 @@
</span><ins>+2016-02-03  Jer Noble  &lt;jer.noble@apple.com&gt;
+
+        [Mac] Wrap a resource and resource loader in a NSURLSession-like object for use by lower level frameworks
+        https://bugs.webkit.org/show_bug.cgi?id=153669
+
+        Reviewed by Alex Christensen.
+
+        Add an API test for WebCoreNSURLSession, testing that it behaves like a regulare NSURLSession, including
+        calling appropriate NSURLSessionDelegate callbacks.
+
+        Drive-by fix: Add a FeatureDefines.xcconfig to TestWebKitAPI.  Without this, the ENABLE macros in WebCore
+        header files will not match the one used when compiling WebCore, leading to strange crashes and weird
+        inconsistencies when calling, e.g., inline methods.
+
+        * TestWebKitAPI/Configurations/FeatureDefines.xcconfig: Added.
+        * TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig:
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebCore/WebCoreNSURLSession.mm: Added.
+        (-[TestNSURLSessionLoaderDelegate webView:didCommitLoadForFrame:]):
+        (-[TestNSURLSessionDataDelegate URLSession:task:didCompleteWithError:]):
+        (-[TestNSURLSessionDataDelegate URLSession:dataTask:didReceiveResponse:completionHandler:]):
+        (-[TestNSURLSessionDataDelegate URLSession:dataTask:didReceiveData:]):
+        (TestWebKitAPI::WebCoreNSURLSessionTest::SetUp):
+        (TestWebKitAPI::WebCoreNSURLSessionTest::TearDown):
+        (TestWebKitAPI::TEST_F):
+
</ins><span class="cx"> 2016-02-03  Konstantin Tokarev  &lt;annulen@yandex.ru&gt;
</span><span class="cx"> 
</span><span class="cx">         [webkitdirs] Clarify logic behind is{PortName} functions.
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPIConfigurationsFeatureDefinesxcconfig"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/Configurations/FeatureDefines.xcconfig (0 => 196082)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Configurations/FeatureDefines.xcconfig                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/Configurations/FeatureDefines.xcconfig        2016-02-03 22:57:43 UTC (rev 196082)
</span><span class="lines">@@ -0,0 +1,195 @@
</span><ins>+// Copyright (C) 2009, 2010, 2014, 2015 Apple Inc. All rights reserved.
+// Copyright (C) 2009 Google 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.
+
+// The contents of this file must be kept in sync with FeatureDefines.xcconfig in JavaScriptCore,
+// WebCore, WebKit and WebKit2.  Also the default values of the ENABLE_FEATURE_NAME macros in
+// build-webkit should match the values below, but they do not need to be in the same order.
+
+// Keep this list of features (not enabled/disabled state) in sync with FeatureDefines.vsprops
+// and FeatureDefinesCairo.vsprops in WebKitLibraries/win/tools/vsprops.
+
+// Set any ENABLE_FEATURE_NAME macro to an empty string to disable that feature.
+
+ENABLE_3D_TRANSFORMS = ENABLE_3D_TRANSFORMS;
+ENABLE_ACCELERATED_2D_CANVAS = ;
+ENABLE_ACCELERATED_OVERFLOW_SCROLLING[sdk=iphone*] = ENABLE_ACCELERATED_OVERFLOW_SCROLLING;
+ENABLE_ATTACHMENT_ELEMENT = ENABLE_ATTACHMENT_ELEMENT;
+ENABLE_AVF_CAPTIONS = ENABLE_AVF_CAPTIONS;
+ENABLE_CACHE_PARTITIONING = ENABLE_CACHE_PARTITIONING;
+ENABLE_CANVAS_PATH = ENABLE_CANVAS_PATH;
+ENABLE_CANVAS_PROXY = ;
+ENABLE_CHANNEL_MESSAGING = ENABLE_CHANNEL_MESSAGING;
+ENABLE_ES6_ARROWFUNCTION_SYNTAX = ENABLE_ES6_ARROWFUNCTION_SYNTAX;
+ENABLE_ES6_CLASS_SYNTAX = ENABLE_ES6_CLASS_SYNTAX;
+ENABLE_ES6_GENERATORS = ENABLE_ES6_GENERATORS;
+ENABLE_ES6_MODULES = ;
+ENABLE_ES6_TEMPLATE_LITERAL_SYNTAX = ENABLE_ES6_TEMPLATE_LITERAL_SYNTAX;
+ENABLE_CONTENT_FILTERING = ENABLE_CONTENT_FILTERING;
+ENABLE_CSP_NEXT = ;
+ENABLE_CSS_ANIMATIONS_LEVEL_2 = ENABLE_CSS_ANIMATIONS_LEVEL_2;
+ENABLE_CSS_BOX_DECORATION_BREAK = ENABLE_CSS_BOX_DECORATION_BREAK;
+ENABLE_CSS_COMPOSITING = ENABLE_CSS_COMPOSITING;
+ENABLE_CSS_DEVICE_ADAPTATION = ;
+ENABLE_CSS_GRID_LAYOUT = ENABLE_CSS_GRID_LAYOUT;
+ENABLE_CSS_IMAGE_ORIENTATION = ;
+ENABLE_CSS_IMAGE_RESOLUTION = ;
+ENABLE_CSS_REGIONS = ENABLE_CSS_REGIONS;
+ENABLE_CSS_SELECTORS_LEVEL4 = ENABLE_CSS_SELECTORS_LEVEL4;
+ENABLE_CSS_SHAPES = ENABLE_CSS_SHAPES;
+ENABLE_CSS3_TEXT = ;
+ENABLE_CSS3_TEXT_LINE_BREAK = ;
+ENABLE_CURRENTSRC = ;
+ENABLE_CURSOR_VISIBILITY = ENABLE_CURSOR_VISIBILITY;
+ENABLE_CUSTOM_SCHEME_HANDLER = ;
+ENABLE_DASHBOARD_SUPPORT[sdk=macosx*] = ENABLE_DASHBOARD_SUPPORT;
+ENABLE_DATALIST_ELEMENT = ;
+ENABLE_DATA_TRANSFER_ITEMS = ;
+ENABLE_DETAILS_ELEMENT = ENABLE_DETAILS_ELEMENT;
+ENABLE_DEVICE_ORIENTATION[sdk=iphone*] = ENABLE_DEVICE_ORIENTATION;
+ENABLE_DOM4_EVENTS_CONSTRUCTOR = ENABLE_DOM4_EVENTS_CONSTRUCTOR;
+ENABLE_ENCRYPTED_MEDIA[sdk=macosx*] = ENABLE_ENCRYPTED_MEDIA;
+ENABLE_ENCRYPTED_MEDIA_V2[sdk=macosx*] = ENABLE_ENCRYPTED_MEDIA_V2;
+ENABLE_FETCH_API = ENABLE_FETCH_API;
+ENABLE_FILTERS_LEVEL_2 = ENABLE_FILTERS_LEVEL_2;
+ENABLE_FONT_LOAD_EVENTS = ;
+ENABLE_FULLSCREEN_API[sdk=macosx*] = ENABLE_FULLSCREEN_API;
+ENABLE_GAMEPAD[sdk=macosx*] = ENABLE_GAMEPAD;
+ENABLE_GAMEPAD_DEPRECATED = ;
+ENABLE_GEOLOCATION = ENABLE_GEOLOCATION;
+ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING[sdk=macosx*] = ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING;
+ENABLE_ICONDATABASE[sdk=macosx*] = ENABLE_ICONDATABASE;
+ENABLE_SERVICE_CONTROLS[sdk=macosx*] = ENABLE_SERVICE_CONTROLS;
+ENABLE_INDEXED_DATABASE = ENABLE_INDEXED_DATABASE;
+ENABLE_INDEXED_DATABASE_IN_WORKERS = ;
+ENABLE_INDIE_UI = ENABLE_INDIE_UI;
+ENABLE_INPUT_TYPE_COLOR[sdk=macosx*] = ENABLE_INPUT_TYPE_COLOR;
+ENABLE_INPUT_TYPE_COLOR_POPOVER[sdk=macosx*] = ENABLE_INPUT_TYPE_COLOR_POPOVER;
+ENABLE_INPUT_TYPE_DATE[sdk=iphone*] = ENABLE_INPUT_TYPE_DATE;
+ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE = ;
+ENABLE_INPUT_TYPE_DATETIMELOCAL[sdk=iphone*] = ENABLE_INPUT_TYPE_DATETIMELOCAL;
+ENABLE_INPUT_TYPE_MONTH[sdk=iphone*] = ENABLE_INPUT_TYPE_MONTH;
+ENABLE_INPUT_TYPE_TIME[sdk=iphone*] = ENABLE_INPUT_TYPE_TIME;
+ENABLE_INPUT_TYPE_WEEK[sdk=iphone*] = ENABLE_INPUT_TYPE_WEEK;
+
+ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS = ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS;
+
+ENABLE_WIRELESS_PLAYBACK_TARGET[sdk=iphone*] = ENABLE_WIRELESS_PLAYBACK_TARGET;
+ENABLE_WIRELESS_PLAYBACK_TARGET[sdk=macosx*] = $(ENABLE_WIRELESS_PLAYBACK_TARGET_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR))
+ENABLE_WIRELESS_PLAYBACK_TARGET_macosx_101000 = ;
+ENABLE_WIRELESS_PLAYBACK_TARGET_macosx_101100 = ENABLE_WIRELESS_PLAYBACK_TARGET;
+ENABLE_WIRELESS_PLAYBACK_TARGET_macosx_101200 = ENABLE_WIRELESS_PLAYBACK_TARGET;
+
+ENABLE_INTL = ENABLE_INTL;
+
+ENABLE_IOS_GESTURE_EVENTS = ;
+ENABLE_IOS_GESTURE_EVENTS[sdk=iphone*] = $(ENABLE_IOS_GESTURE_EVENTS_ios_WITH_INTERNAL_SDK_$(USE_INTERNAL_SDK));
+ENABLE_IOS_GESTURE_EVENTS_ios_WITH_INTERNAL_SDK_YES = ENABLE_IOS_GESTURE_EVENTS;
+
+ENABLE_MAC_GESTURE_EVENTS = ;
+ENABLE_MAC_GESTURE_EVENTS[sdk=macosx*] = $(ENABLE_MAC_GESTURE_EVENTS_macosx_WITH_INTERNAL_SDK_$(USE_INTERNAL_SDK));
+ENABLE_MAC_GESTURE_EVENTS_macosx_WITH_INTERNAL_SDK_YES = ENABLE_MAC_GESTURE_EVENTS;
+
+ENABLE_IOS_TEXT_AUTOSIZING[sdk=iphone*] = ENABLE_IOS_TEXT_AUTOSIZING;
+
+ENABLE_IOS_TOUCH_EVENTS[sdk=iphone*] = $(ENABLE_IOS_TOUCH_EVENTS_ios_WITH_INTERNAL_SDK_$(USE_INTERNAL_SDK));
+ENABLE_IOS_TOUCH_EVENTS_ios_WITH_INTERNAL_SDK_YES = ENABLE_IOS_TOUCH_EVENTS;
+
+ENABLE_LEGACY_CSS_VENDOR_PREFIXES = ENABLE_LEGACY_CSS_VENDOR_PREFIXES;
+ENABLE_LEGACY_NOTIFICATIONS[sdk=macosx*] = ENABLE_LEGACY_NOTIFICATIONS;
+ENABLE_LEGACY_VENDOR_PREFIXES = ENABLE_LEGACY_VENDOR_PREFIXES;
+ENABLE_LEGACY_WEB_AUDIO = ENABLE_LEGACY_WEB_AUDIO;
+ENABLE_LETTERPRESS[sdk=iphone*] = ENABLE_LETTERPRESS;
+ENABLE_LINK_PREFETCH = ;
+ENABLE_MATHML = ENABLE_MATHML;
+ENABLE_MEDIA_CONTROLS_SCRIPT = ENABLE_MEDIA_CONTROLS_SCRIPT;
+ENABLE_MEDIA_SESSION = ;
+
+ENABLE_MEDIA_SOURCE[sdk=macosx*] = ENABLE_MEDIA_SOURCE;
+
+ENABLE_MEDIA_STATISTICS = ;
+ENABLE_MEDIA_STREAM = ENABLE_MEDIA_STREAM;
+ENABLE_METER_ELEMENT[sdk=macosx*] = ENABLE_METER_ELEMENT;
+ENABLE_MHTML = ;
+ENABLE_MOUSE_CURSOR_SCALE[sdk=macosx*] = ENABLE_MOUSE_CURSOR_SCALE;
+ENABLE_NAVIGATOR_CONTENT_UTILS = ;
+ENABLE_NAVIGATOR_HWCONCURRENCY = ENABLE_NAVIGATOR_HWCONCURRENCY;
+ENABLE_NOSNIFF = ;
+ENABLE_NOTIFICATIONS[sdk=macosx*] = ENABLE_NOTIFICATIONS;
+ENABLE_PDFKIT_PLUGIN[sdk=macosx*] = ENABLE_PDFKIT_PLUGIN;
+ENABLE_POINTER_LOCK = ;
+ENABLE_PROXIMITY_EVENTS = ;
+ENABLE_PUBLIC_SUFFIX_LIST = ENABLE_PUBLIC_SUFFIX_LIST;
+ENABLE_QUOTA = ;
+ENABLE_REQUEST_ANIMATION_FRAME = ENABLE_REQUEST_ANIMATION_FRAME;
+ENABLE_REQUEST_AUTOCOMPLETE = ;
+ENABLE_REMOTE_INSPECTOR = ENABLE_REMOTE_INSPECTOR;
+ENABLE_RESOLUTION_MEDIA_QUERY = ;
+ENABLE_RUBBER_BANDING[sdk=macosx*] = ENABLE_RUBBER_BANDING;
+ENABLE_CSS_SCROLL_SNAP = ENABLE_CSS_SCROLL_SNAP;
+ENABLE_SPEECH_SYNTHESIS = ENABLE_SPEECH_SYNTHESIS;
+ENABLE_STREAMS_API = ENABLE_STREAMS_API;
+ENABLE_SUBTLE_CRYPTO = ENABLE_SUBTLE_CRYPTO;
+ENABLE_SVG_FONTS = ENABLE_SVG_FONTS;
+ENABLE_SVG_OTF_CONVERTER = ENABLE_SVG_OTF_CONVERTER;
+
+ENABLE_TELEPHONE_NUMBER_DETECTION = ENABLE_TELEPHONE_NUMBER_DETECTION;
+
+ENABLE_TEMPLATE_ELEMENT = ENABLE_TEMPLATE_ELEMENT;
+ENABLE_TEXT_AUTOSIZING = ;
+
+ENABLE_CSS_TRAILING_WORD = ENABLE_CSS_TRAILING_WORD;
+
+// FIXME: Remove the USE_INTERNAL_SDK condition once we support touch events when building for iOS with
+// the public SDK. We will also need to update FeatureDefines.h.
+ENABLE_TOUCH_EVENTS[sdk=iphone*] = $(ENABLE_TOUCH_EVENTS_ios_WITH_INTERNAL_SDK_$(USE_INTERNAL_SDK));
+ENABLE_TOUCH_EVENTS_ios_WITH_INTERNAL_SDK_YES = ENABLE_TOUCH_EVENTS;
+
+ENABLE_TOUCH_ICON_LOADING = ;
+ENABLE_USERSELECT_ALL = ENABLE_USERSELECT_ALL;
+ENABLE_VIDEO = ENABLE_VIDEO;
+ENABLE_VIDEO_PRESENTATION_MODE[sdk=iphone*] = ENABLE_VIDEO_PRESENTATION_MODE;
+ENABLE_VIDEO_TRACK = ENABLE_VIDEO_TRACK;
+ENABLE_DATACUE_VALUE = ENABLE_DATACUE_VALUE;
+ENABLE_VIEW_MODE_CSS_MEDIA = ;
+ENABLE_WEBASSEMBLY = ;
+ENABLE_WEBGL = ENABLE_WEBGL;
+ENABLE_WEBGL2 = ;
+ENABLE_WEB_ANIMATIONS = ;
+ENABLE_WEB_AUDIO = ENABLE_WEB_AUDIO;
+ENABLE_WEB_REPLAY = $(ENABLE_WEB_REPLAY_$(PLATFORM_NAME)_$(CONFIGURATION));
+ENABLE_WEB_REPLAY_macosx_Debug = ENABLE_WEB_REPLAY;
+ENABLE_WEB_REPLAY_macosx_Release = ENABLE_WEB_REPLAY;
+ENABLE_WEB_SOCKETS = ENABLE_WEB_SOCKETS;
+
+ENABLE_WEB_TIMING = ENABLE_WEB_TIMING;
+
+ENABLE_XSLT = ENABLE_XSLT;
+
+ENABLE_FTL_JIT[sdk=macosx*] = ENABLE_FTL_JIT;
+ENABLE_FTL_JIT[sdk=iphoneos*] = ENABLE_FTL_JIT;
+
+ENABLE_SHADOW_DOM = ENABLE_SHADOW_DOM;
+ENABLE_CUSTOM_ELEMENTS = ENABLE_CUSTOM_ELEMENTS;
+
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_AVF_CAPTIONS) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_ES6_ARROWFUNCTION_SYNTAX) $(ENABLE_ES6_CLASS_SYNTAX) $(ENABLE_ES6_GENERATORS) $(ENABLE_ES6_MODULES) $(ENABLE_ES6_TEMPLATE_LITERAL_SYNTAX) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_GRID_LAYOUT) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS3_TEXT_LINE_BREAK) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE
 _ORIENTATION) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GEOLOCATION) $(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING) $(ENABLE_ICONDATABASE) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TEXT_AUTOSIZING) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LEGACY_WEB_AUDIO) $(ENABLE_LETTERPRESS) $(ENABLE_LINK
 _PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_CURRENTSRC) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RUBBER_BANDING) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_OTF_CONVERTER) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEMPLATE_ELEMENT) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_USERSELECT_ALL) $(ENABLE_V
 IDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_DATACUE_VALUE) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_XSLT) $(ENABLE_FTL_JIT) $(ENABLE_JIT) $(ENABLE_SHADOW_DOM) $(ENABLE_CUSTOM_ELEMENTS) $(ENABLE_VIDEO_PRESENTATION_MODE);
</ins></span></pre></div>
<a id="trunkToolsTestWebKitAPIConfigurationsTestWebKitAPIxcconfig"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig (196081 => 196082)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig        2016-02-03 22:46:57 UTC (rev 196081)
+++ trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig        2016-02-03 22:57:43 UTC (rev 196082)
</span><span class="lines">@@ -21,6 +21,8 @@
</span><span class="cx"> // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
</span><span class="cx"> // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
</span><span class="cx"> 
</span><ins>+#include &quot;FeatureDefines.xcconfig&quot;
+
</ins><span class="cx"> PRODUCT_NAME = TestWebKitAPI;
</span><span class="cx"> GCC_ENABLE_OBJC_EXCEPTIONS = YES;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (196081 => 196082)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2016-02-03 22:46:57 UTC (rev 196081)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2016-02-03 22:57:43 UTC (rev 196082)
</span><span class="lines">@@ -316,6 +316,7 @@
</span><span class="cx">                 CD225C081C45A69200140761 /* ParsedContentRange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD225C071C45A69200140761 /* ParsedContentRange.cpp */; };
</span><span class="cx">                 CD59F53419E9110D00CF1835 /* file-with-mse.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CD59F53219E910AA00CF1835 /* file-with-mse.html */; };
</span><span class="cx">                 CD59F53519E9110D00CF1835 /* test-mse.mp4 in Copy Resources */ = {isa = PBXBuildFile; fileRef = CD59F53319E910BC00CF1835 /* test-mse.mp4 */; };
</span><ins>+                CD89D03A1C4EDB2A00040A04 /* WebCoreNSURLSession.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD89D0381C4EDB2A00040A04 /* WebCoreNSURLSession.mm */; };
</ins><span class="cx">                 CDBFCC451A9FF45300A7B691 /* FullscreenZoomInitialFrame.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDBFCC431A9FF44800A7B691 /* FullscreenZoomInitialFrame.mm */; };
</span><span class="cx">                 CDBFCC461A9FF49E00A7B691 /* FullscreenZoomInitialFrame.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CDBFCC421A9FF44800A7B691 /* FullscreenZoomInitialFrame.html */; };
</span><span class="cx">                 CDC8E48D1BC5CB4500594FEC /* AudioSessionCategoryIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDC8E4851BC5B19400594FEC /* AudioSessionCategoryIOS.mm */; };
</span><span class="lines">@@ -791,6 +792,8 @@
</span><span class="cx">                 CD5497B315857F0C00B5BC30 /* MediaTime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaTime.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CD59F53219E910AA00CF1835 /* file-with-mse.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = &quot;file-with-mse.html&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CD59F53319E910BC00CF1835 /* test-mse.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = &quot;test-mse.mp4&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                CD773F711C5057DB0002257C /* FeatureDefines.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = FeatureDefines.xcconfig; sourceTree = &quot;&lt;group&gt;&quot;; };
+                CD89D0381C4EDB2A00040A04 /* WebCoreNSURLSession.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCoreNSURLSession.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 CDBFCC421A9FF44800A7B691 /* FullscreenZoomInitialFrame.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = FullscreenZoomInitialFrame.html; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CDBFCC431A9FF44800A7B691 /* FullscreenZoomInitialFrame.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FullscreenZoomInitialFrame.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CDC2C7141797089D00E627FB /* TimeRanges.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TimeRanges.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -983,6 +986,7 @@
</span><span class="cx">                 440A1D3614A01000008A66F2 /* WebCore */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                CD89D0371C4EDB1300040A04 /* cocoa */,
</ins><span class="cx">                                 93A720E518F1A0E800A848E1 /* CalculationValue.cpp */,
</span><span class="cx">                                 7CB184C41AA3F2100066EDFD /* ContentExtensions.cpp */,
</span><span class="cx">                                 CD5451E919E41F9D0016936F /* CSSParser.cpp */,
</span><span class="lines">@@ -1092,6 +1096,7 @@
</span><span class="cx">                         children = (
</span><span class="cx">                                 BC90957E12554CF900083756 /* Base.xcconfig */,
</span><span class="cx">                                 BC90957F12554CF900083756 /* DebugRelease.xcconfig */,
</span><ins>+                                CD773F711C5057DB0002257C /* FeatureDefines.xcconfig */,
</ins><span class="cx">                                 BC575AE2126E88B1006F0F12 /* InjectedBundle.xcconfig */,
</span><span class="cx">                                 BC90958012554CF900083756 /* TestWebKitAPI.xcconfig */,
</span><span class="cx">                                 7CCE7EA31A4115CB00447C4C /* TestWebKitAPILibrary.xcconfig */,
</span><span class="lines">@@ -1465,6 +1470,14 @@
</span><span class="cx">                         path = mac;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="cx">                 };
</span><ins>+                CD89D0371C4EDB1300040A04 /* cocoa */ = {
+                        isa = PBXGroup;
+                        children = (
+                                CD89D0381C4EDB2A00040A04 /* WebCoreNSURLSession.mm */,
+                        );
+                        name = cocoa;
+                        sourceTree = &quot;&lt;group&gt;&quot;;
+                };
</ins><span class="cx">                 CDC8E4981BC728AE00594FEC /* WebKit */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><span class="lines">@@ -1844,6 +1857,7 @@
</span><span class="cx">                                 7AA6A1521AAC0B31002B2ED3 /* WorkQueue.cpp in Sources */,
</span><span class="cx">                                 2E7765CF16C4D81100BA2BB1 /* mainMac.mm in Sources */,
</span><span class="cx">                                 41973B5B1AF2286A006C7B36 /* FileSystem.cpp in Sources */,
</span><ins>+                                CD89D03A1C4EDB2A00040A04 /* WebCoreNSURLSession.mm in Sources */,
</ins><span class="cx">                                 A1C4FB6E1BACCE50003742D0 /* QuickLook.mm in Sources */,
</span><span class="cx">                                 7A5623111AD5AF3E0096B920 /* MenuTypesForMouseEvents.cpp in Sources */,
</span><span class="cx">                                 9B0786A31C58830F00D159E3 /* InjectedBundleMakeAllShadowRootsOpen.cpp in Sources */,
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebCoreWebCoreNSURLSessionmm"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/Tests/WebCore/WebCoreNSURLSession.mm (0 => 196082)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebCore/WebCoreNSURLSession.mm                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/WebCoreNSURLSession.mm        2016-02-03 22:57:43 UTC (rev 196082)
</span><span class="lines">@@ -0,0 +1,161 @@
</span><ins>+/*
+ * Copyright (C) 2016 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 COMPUTER, 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 COMPUTER, 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 &quot;config.h&quot;
+#import &quot;PlatformUtilities.h&quot;
+#import &lt;WebKit/WebView.h&gt;
+#import &lt;WebCore/FrameLoadRequest.h&gt;
+#import &lt;WebCore/MainFrame.h&gt;
+#import &lt;WebCore/Page.h&gt;
+#import &lt;WebCore/PageConfiguration.h&gt;
+#import &lt;WebCore/Document.h&gt;
+#import &lt;WebCore/DocumentLoader.h&gt;
+#import &lt;WebCore/Settings.h&gt;
+#import &lt;WebCore/SubresourceLoader.h&gt;
+#import &lt;WebCore/WebCoreNSURLSession.h&gt;
+#import &lt;WebCore/ResourceLoader.h&gt;
+#import &lt;wtf/SchedulePair.h&gt;
+
+static bool didLoadMainResource;
+static bool didRecieveResponse;
+static bool didRecieveData;
+static bool didComplete;
+static bool didInvalidate;
+
+static NSURL *documentURL = [[NSBundle mainBundle] URLForResource:@&quot;simple&quot; withExtension:@&quot;html&quot; subdirectory:@&quot;TestWebKitAPI.resources&quot;];
+static NSURL *resourceURL = [[NSBundle mainBundle] URLForResource:@&quot;test&quot; withExtension:@&quot;mp4&quot; subdirectory:@&quot;TestWebKitAPI.resources&quot;];
+
+@interface TestNSURLSessionLoaderDelegate : NSObject&lt;WebFrameLoadDelegate&gt;
+@end
+
+@implementation TestNSURLSessionLoaderDelegate
+- (void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame
+{
+    UNUSED_PARAM(sender);
+    UNUSED_PARAM(frame);
+    didLoadMainResource = true;
+}
+@end
+
+@interface TestNSURLSessionDataDelegate : NSObject&lt;NSURLSessionDataDelegate&gt;
+@end
+
+@implementation TestNSURLSessionDataDelegate
+- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error
+{
+    didComplete = true;
+}
+
+- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
+{
+    didRecieveResponse = true;
+    completionHandler(NSURLSessionResponseAllow);
+}
+
+- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
+{
+    didRecieveData = true;
+
+    NSData* directData = [NSData dataWithContentsOfURL:dataTask.originalRequest.URL];
+    NSData* directSubdata = [directData subdataWithRange:NSMakeRange(dataTask.countOfBytesReceived - data.length, data.length)];
+    ASSERT_TRUE([data isEqualToData:directSubdata]);
+}
+
+- (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(nullable NSError *)error
+{
+    didInvalidate = true;
+}
+@end
+
+using namespace WebCore;
+
+@interface WebView (WebViewInternalForTesting)
+- (WebCore::Frame*)_mainCoreFrame;
+@end
+
+namespace TestWebKitAPI {
+
+class WebCoreNSURLSessionTest : public testing::Test {
+public:
+    WebView *view { nil };
+    Frame* frame { nullptr };
+    TestNSURLSessionDataDelegate *delegate { nil };
+
+    virtual void SetUp()
+    {
+        view = [[WebView alloc] initWithFrame:NSZeroRect];
+        view.frameLoadDelegate = [[[TestNSURLSessionLoaderDelegate alloc] init] autorelease];
+
+        didLoadMainResource = false;
+        view.mainFrameURL = documentURL.absoluteString;
+        TestWebKitAPI::Util::run(&amp;didLoadMainResource);
+
+        delegate = [[TestNSURLSessionDataDelegate alloc] init];
+        frame = [view _mainCoreFrame];
+    }
+
+    virtual void TearDown()
+    {
+        [view release];
+        [delegate release];
+    }
+};
+
+TEST_F(WebCoreNSURLSessionTest, BasicOperation)
+{
+    WebCoreNSURLSession* session = [[WebCoreNSURLSession alloc] initWithResourceLoader:frame-&gt;document()-&gt;loader()-&gt;cachedResourceLoader() delegate:delegate delegateQueue:[NSOperationQueue mainQueue]];
+    didRecieveResponse = false;
+    didRecieveData = false;
+    didComplete = false;
+
+    NSURLSessionDataTask *task = [session dataTaskWithURL:resourceURL];
+    [task resume];
+
+    TestWebKitAPI::Util::run(&amp;didRecieveResponse);
+    TestWebKitAPI::Util::run(&amp;didRecieveData);
+    TestWebKitAPI::Util::run(&amp;didComplete);
+
+    didInvalidate = false;
+
+    task = [session dataTaskWithURL:resourceURL];
+    [task resume];
+    [session finishTasksAndInvalidate];
+
+    TestWebKitAPI::Util::run(&amp;didInvalidate);
+
+    [session release];
+}
+
+TEST_F(WebCoreNSURLSessionTest, InvalidateEmpty)
+{
+    WebCoreNSURLSession* session = [[WebCoreNSURLSession alloc] initWithResourceLoader:frame-&gt;document()-&gt;loader()-&gt;cachedResourceLoader() delegate:delegate delegateQueue:[NSOperationQueue mainQueue]];
+    didInvalidate = false;
+    [session finishTasksAndInvalidate];
+    TestWebKitAPI::Util::run(&amp;didInvalidate);
+    [session release];
+}
+
+
+}
</ins></span></pre>
</div>
</div>

</body>
</html>